前段时间将Cortex-M3威望攻略看完了,现在开端拿块开发板练手。
STM32F1xx自身并不难,不过由于第一次用KeilMDK,还有想在程序中运用最新的stm32f10x_stdperiph_libV3.5,最终让程序跑通也阅历了一番曲折。这儿简略的记载一下,期望对刚刚开端学STM32的初学者有些协助。(这篇的内容很初级,高手请绕道)
首要介绍一下我这儿的试验环境,开发板是块廉价货“神舟IV号STM32F107VCT开发板”,听这个姓名就挺山寨,不过廉价却是真的。仿真器是国内山寨的J-LinkV8,买开发板时送的。J-Link用的是V4.12版的驱动程序,segger网站上有新版的驱动,不过我试过了,新版的驱动增加了检测J-Link是否是山寨的功用,装上也不能用,在网上也没有找到处理方法,所以仍是死心吧,4.12版的驱动也能支撑挺多的ARM芯片型号了。
IDE环境是KeiluVersionV4.10,东西链的版别为:RealViewMDK-ARM4.12,当然是D版的。
总归,这一套从头到脚都挺山寨。不过我这对错商业用途,仅供个人学习,想来ARM和segger也不会来难为我。
不说废话了。首要讲一讲如安在程序中运用STM32F10x_StdPeriph_Driver。
(1)新建一个文件夹寄存项目文件,要留意途径不能有中文,我这儿目录名取为stm32-test1。
(2)翻开KeiluVersion,新建一个项目“test.uvproj”,CPU挑选STM32F107VC。
(3)KeiluVersion会提示是否增加发动代码,挑选否,由于咱们要用STM32F10x_StdPeriph_Driver中供给的发动代码。
(4)给ProjectTargets改名,我改的名为:STM32F107。这一步不是有必要的,仅仅默许的称号“Target1”太没特性了。
(5)Groups中我建立了三个组:Source、CMSIS、StdPeriphDriver。Source中寄存我写的代码,别的两个望文生义寄存相应的代码。
(6)stm32-test1目录中也增加相应的三个文件夹:Source、CMSIS、StdPeriphDriver。这时stm32-test1目录中应该有这些文件(文件夹):
CMSIS
Source
StdPeriphDriver
test.plg
test.uvopt
test.uvproj
test_STM32F107.dep
test_Target1.dep
(7)网上下载的STM32F10x_StdPeriph_Lib_V3.5.0,解压缩后“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport”和“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x”目录中的c文件和h文件都拷贝到CMSIS目录中。“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm”目录中“startup_stm32f10x_cl.s”也拷贝到CMSIS目录中。这儿多说一句,startup_stm32f10x_cl.s是STM32F105和STM32F107系列的发动文件,cl指的是Connectivityline。假如用的是其他类型的STM32,需求换用适宜的发动文件。
(8)“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\inc”和“STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\src”文件中的内容都拷贝到StdPeriphDriver目录中。“STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template\stm32f10x_conf.h”拷贝到StdPeriphDriver目录中。读者或许留意到我将c文件和头文件都混到了一个文件夹中了,之所以这样办理文件,是为了让项目的目录结构看起来尽量的简略。现在,CMSIS下的文件应该有这些:
core_cm3.c
core_cm3.h
startup_stm32f10x_cl.s
stm32f10x.h
system_stm32f10x.c
system_stm32f10x.h
StdPeriphDriver目录中文件应该有这些:
misc.h
stm32f10x_adc.c
stm32f10x_adc.h
stm32f10x_bkp.c
stm32f10x_bkp.h
stm32f10x_can.c
stm32f10x_can.h
stm32f10x_cec.c
stm32f10x_cec.h
stm32f10x_crc.c
stm32f10x_crc.h
stm32f10x_dac.c
stm32f10x_dac.h
stm32f10x_dbgmcu.c
stm32f10x_dbgmcu.h
stm32f10x_dma.c
stm32f10x_dma.h
stm32f10x_exti.c
stm32f10x_exti.h
stm32f10x_flash.c
stm32f10x_flash.h
stm32f10x_fsmc.c
stm32f10x_fsmc.h
stm32f10x_gpio.c
stm32f10x_gpio.h
stm32f10x_i2c.c
stm32f10x_i2c.h
stm32f10x_iwdg.c
stm32f10x_iwdg.h
stm32f10x_pwr.c
stm32f10x_pwr.h
stm32f10x_rcc.c
stm32f10x_rcc.h
stm32f10x_rtc.c
stm32f10x_rtc.h
stm32f10x_sdio.c
stm32f10x_sdio.h
stm32f10x_spi.c
stm32f10x_spi.h
stm32f10x_tim.c
stm32f10x_tim.h
stm32f10x_usart.c
stm32f10x_usart.h
stm32f10x_wwdg.c
stm32f10x_wwdg.h
stm32f10x_conf.h
关于某个详细的项目,这些文件不一定都会用到,不过放在这儿也没什么害处。
(9)将.\CMSIS;.\StdPeriphDriver这两个目录加入到头文件的查找目录中。
(10)将startup_stm32f10x_cl.s增加到组CMSIS中,新建个main.c文件,加入到组Source中。
(11)修正“stm32f10x.h”文件。在文件中找到这一段:
- #if!defined(STM32F10X_LD)&&!defined(STM32F10X_LD_VL)&&!defined(STM32F10X_MD)&&!defined(STM32F10X_MD_VL)&&!defined(STM32F10X_HD)&&!defined(STM32F10X_XL)&&!defined(STM32F10X_CL)
- /*#defineSTM32F10X_LD*//*!
- /*#defineSTM32F10X_LD_VL*//*!
- /*#defineSTM32F10X_MD*//*!
- /*#defineSTM32F10X_MD_VL*//*!
- /*#defineSTM32F10X_HD_VL*//*!
- /*#defineSTM32F10X_HD*//*!
- /*#defineSTM32F10X_XL*//*!
- /*#defineSTM32F10X_CL*//*!
- #endif
- /*#defineSTM32F10X_LD_VL*//*!
将对“#defineSTM32F10X_CL”的注释去掉。
找到“#defineUSE_PERIPH_LIBRARY”将注释去掉。
(12)将“system_stm32f10x.c”加入到组“CMSIS”中,找到如下代码:
- #ifdefined(STM32F10X_LD_VL)||(definedSTM32F10X_MD_VL)||(definedSTM32F10X_HD_VL)
- /*#defineSYSCLK_FREQ_HSEHSE_Value*/
- #defineSYSCLK_FREQ_24MHz24000000
- #else
- /*#defineSYSCLK_FREQ_HSEHSE_Value*/
- /*#defineSYSCLK_FREQ_24MHz24000000*/
- /*#defineSYSCLK_FREQ_36MHz36000000*/
- /*#defineSYSCLK_FREQ_48MHz48000000*/
- /*#defineSYSCLK_FREQ_56MHz56000000*/
- #defineSYSCLK_FREQ_72MHz72000000
- #endif
依据板子上的运用的时钟体系来确认SYSCLK的频率。
至此,该设置的都设置的差不多了,能够开端写使用代码了。我这儿以闪灯程序为例吧。我的开发板上有四个LED,别离对应的GPIO端口D的PD2、PD3、PD4和PD7。
下面先给一个不使用STM32F10x_StdPeriph_Driver中库函数,只使用STM32F10x_StdPeriph_Driver中给出的外设寄存器的界说。下面是main.c的代码。
- #include”stm32f10x.h”
- voiddelay(void)
- {
- uint32_ti;
- for(i=0;i<3000000L;i++)
- {
- }
- }
- intmain(void)
- {
- RCC->APB2ENR|=0x00000020;
- GPIOD->CRL=0x24422244;//PD2PD3PD4PD7SettoOutputmode
- for(;;)
- {
- GPIOD->ODR=0x00000000;
- delay();
- GPIOD->ODR=0x0000009C;
- delay();
- }
- }
下面再给个使用TM32F10x_StdPeriph_Driver中库函数的代码。
- #include”stm32f10x.h”
- #defineRCC_GPIO_LEDRCC_APB2Periph_GPIOD
- #defineGPIO_LED_PORTGPIOD
- #defineGPIO_LED1GPIO_Pin_2
- #defineGPIO_LED2GPIO_Pin_3
- #defineGPIO_LED3GPIO_Pin_4
- #defineGPIO_LED4GPIO_Pin_7
- #defineGPIO_LED_ALLGPIO_LED1|GPIO_LED2|GPIO_LED3|GPIO_LED4
- voiddelay(void)
- {
- uint32_ti;
- for(i=0;i<3000000L;i++)
- {
- }
- }
- intmain(void)
- {
- GPIO_InitTypeDefGPIO_InitStructure;
- SystemInit();
- /*EnableGPIOB,GPIOCandAFIOclock*/
- RCC_APB2PeriphClockCmd(RCC_GPIO_LED|RCC_APB2Periph_AFIO,ENABLE);
- /*LEDspinsconfiguration*/
- GPIO_InitStructure.GPIO_Pin=GPIO_LED_ALL;
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
- GPIO_Init(GPIO_LED_PORT,&GPIO_InitStructure);
- for(;;)
- {
- GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
- delay();
- GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED_ALL);
- delay();
- }
- }
编译程序,在链接阶段报错了,错误信息如下:
- BuildtargetSTM32F107
- linking…
- test.axf:Error:L6218E:UndefinedsymbolGPIO_Init(referredfrommain.o).
- test.axf:Error:L6218E:UndefinedsymbolGPIO_ResetBits(referredfrommain.o).
- test.axf:Error:L6218E:UndefinedsymbolGPIO_SetBits(referredfrommain.o).
- test.axf:Error:L6218E:UndefinedsymbolRCC_APB2PeriphClockCmd(referredfrommain.o).
- test.axf:Notenoughinformationtolistimagesymbols.
- test.axf:Finished:1information,0warningand4errormessages.
- Targetnotcreated
说的很理解,GPIO_Init、GPIO_ResetBits、GPIO_SetBits、RCC_APB2PeriphClockCmd这几个函数的完成没有找到。处理的方法清楚明了,将“stm32f10x_gpio.c”和“stm32f10x_rcc.c”两个文件加入到组“StdPeriphDriver”中,再编译就通过了。将程序下载到板子上,一切正常。
上面只说了个大约的流程,还有些怎么设置J-Link一类的都略去了,由于介绍这些的文章实在是太多了。