在MDK下学习使用STM32也快两个礼拜了,基本掌握了STM32在MDK环境下的开发流程和基本硬件程序的书写。其间,遇到了许多问题,其中不少问题花费了我相当多得时间才得以解决,现将这些问题和解决方法列出。其中也有一些是学习过程中我觉得需要记下的注意事项。
1、STM32固件库使用外围设备的主要思路
在STM32中,外围设备的配置思路比较固定。首先是使能相关的时钟,一方面是设备本身的时钟,另一方面如果设备通过IO口输出还需要使能IO口的时钟;最后如果对应的IO口是复用功能的IO口,则还必须使能AFIO的时钟。
其次是配置GPIO,GPIO的各种属性由硬件手册的AFIO一章详细规定,较为简单。
接着相关设备需要如果需要使用中断功能,必须先配置中断优先级,后文详述。
然后是配置外围设备的相关属性,视具体设备而定,如果设备需要使用中断方式,必须使能相应设备的中断,之后需要使能相关设备。
最后如果设备使用了中断功能,则还需要填写相应的中断服务程序,在服务程序中进行相应操作。
2、如果在源文件中未定义以下预定义,需在工程“C/C++”中预定义一栏 填写
“USE_STDPERIPH_DRIVER,STM32F10X_CL(器件所属分类),USE_STM3210C_EVAL(使用的评估板,库自带的历程中需要根据"readme"文件提示添加,自己的工程除非是在一样的评估板上运行,否则不需要预定义此项)”
3、NVIC的优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //这个对所有中断有效,一个程序中只能有一个分组
NVIC_PriorityGroup_n中n代表4位中有n位是给中断分配抢占式优先级的,4-n位是给中断分配响应优先级的。
4、NVIC_InitStructure.NVIC_IRQChannel =EXTI15_10_IRQn;//其中EXTI15_10_IRQn表示选中的通道为[15:10],不懂就跳到它的定义处看注释
5、TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV4中的TIM_ClockDivision或 控制寄存器1(TIMx_CR1)中得位CKD[1:0] 为 时钟分频因子 (Clock division)
为定义在定时器时钟(CK_INT)频率与数字滤波器(ETR ,TIx)使用的采样频率之间的分频比例,与用内部时钟时counter使用的时钟频率(分频是在PSC寄存器中设置)无关。
6、下面对该库文件做个简单介绍:
Libraries\STM32F10x_StdPeriph_Driver\下的内容很好理解就是stm32的各个外设模块驱动代码。
misc.h和misc.c是和CM3内核有关的NVIC和SysTick的驱动代码。
Libraries\CMSIS下是什么呢?cmsis英文全称:CortexMicrocontroller Software InterfaceStandard,是Cortex系列处理器硬件抽象层,可以理解为cortex内核的软件接口。
core_cm3.c, core_cm3.h
它们的目录名为CoreSupport,说明这两个文件是CM3内核支撑文件,其他使用CM3内核的芯片也可以用,不一定是stm32。这两个文件用来获取设置CM3内核,配置一些内核寄存器。
stm32f10x.h, system_stm32f10x.c,system_stm32f10x.h和startup_stm32f10x_hd.s在DeviceSupport目录下,说明这几个文件是和具体的芯片有关的,也就是stm32芯片的支撑文件。其中stm32f10x.h是标准外设库的入口,使用标准外设库的代码中必须包含该头文件。system_stm32f10x.c,system_stm32f10x.h这两个文件提供函数用来初始化stm32芯片,配置PLL、系统时钟和内置flash接口。startup_stm32f10x_hd.s是大容量型stm32芯片的启动文件。
7、USER下部分文件介绍
(1)stm32f10x_conf.h是用来添加所需外设头文件的,要根据需要进行更改,否则编译会出现很多提示外设库函数没有定义 的错误。
(2)stm32f10x_it.c这是一个中断处理文件,_it结尾,就是interrupt(中断)的意思,说明这个是整个工程的中断处理函数,要是楼主没有用到中断的话就可以不添加进去,还有,也可以去掉,将中断函数添加到其它.c文件里也行.
stm32f10x_it.h中是对中断处理函数的声明。
(3)System_stm32f10x.c这个文件中定义的单片机的时钟设置,修改时钟设置直接修改里面的相应宏定义即可。调用System_Init()函数时会调用这个宏定义。由于在STM32的启动代码中(eg.starup_stm32f10x_cl.s)就调用了System_Init()函数,因此在主函数中不需调用此函数。
8、24C02器件地址组成
八位前面4位代表器件类型,eeprom为1010,A2、A1、A0为同类型器件地址,主要看原理图中相应位是接高还是接地。
eg.由STM32 HY-GoldBullV3开发板的原理图可知,24C02的A2、A1、A0脚全部接地,所以24C02的地址应为1010000_ ,最后一位表示读还是写。
9、在一个源文件中调用其他文件的函数,也需要在文件头声明,不然会有警告。
10、使用串口出现乱码
原因分析
(1)USART设置有错
(2)系统时钟设置有误
(3)如果使用的是MDK,使用printf()函数需要在工程属性的“Target“-》”Code Generation“中勾选”UseMicroLIB“,否则使用printf函数会出现问题,例如会出现乱码。
11、如果错误提示“expect a ")" " 原因有可能为
(1)少写了半个括号 ")"
(2)输成中文输入法的括号
(3)定义了与宏定义重复的变量
其中第三个最不容易发现,平常写程序时要注意。