《stm32学习笔记原创》由会员分享,可在线阅读,更多相关《stm32学习笔记原创(28页珍藏版)》请在金锄头文库上搜索。
1、STM32野火模版:CMSIS:(Cortex Microcontroller Software Interface Standard)是ARM Cortex微控制器软件接口标准。启动文件及Cortex M3所使用的库,所有ARM Cortex M3架构处理器通用FWlib:STM32的片内资源的驱动,由意法公司提供USER:用户写的文件、config头文件、中断函数的h、c文件及工程文件Output:编译后的输出文件STM32 库结构:Libraries:要用到的库文件都在Libraries里面,其中CMSIS同上,STM32F10x_StdPeriph_Driver则为STM32片内资源的
2、驱动。Project:为示例与不同开发软件下的模板Utilities:ST官方开发板的外设驱动#ifdef USE_STDPERIPH_DRIVER #include stm32f10x_conf.h#endif /位于stm32f10x.h一、流水灯实验学习中要查看以下文档:1.库的查询手册stm32f10x_stdperiph_lib_um.chm2.野火STM32管脚分配野火M3主芯片STM32F103VET6资源分配.txt3.实验教程野火M3教程.pdf4.STM32手册STM32参考手册中文.pdf、STM32参考手册英文.pdf5.CM3权威指南CnR2.pdf本实验涉及到两个片
3、内外设的操作:RCC(Reset and Clock Control)和GPIO。RCC:这里只用到函数SystemInit()将系统时钟设置为72M,不赘述。GPIO: GPIO的初始化和GPIO的置位与清零操作。GPIO的初始化:见以下代码void LED_GPIO_Config(void)GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_
4、Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5); / turn off all led可见,GPIO的初始化用的是库函数GPIO_Init()void GPIO_Init ( GPIO_TypeDef* GPIOx, GPIO_InitType
5、Def* GPIO_InitStruct )两个参数中前者是GPIO的组号,填上GPIOA-GPIOE中的一个即可。后者是GPIO设置的结构体GPIO_InitTypeDef*,该结构体中包含三个成员:GPIO_Pin、GPIO_Mode、GPIO_Speed,分别用于对具体的管脚、对GPIO功能及GPIO输出速度进行配置。具体可选值的宏定义查手册。另外还有函数RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);。它指定了GPIO采用高速外设的时钟。STM32所有的IO口都是高速的,所以这句是在使用IO时必须要的一句。GPIO的赋值操作使
6、用到库函数GPIO_ResetBits()、GPIO_SetBits()void GPIO_ResetBits ( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin )void GPIO_SetBits ( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin )另外,关于GPIO操作还有许多其他库函数,我们只需查找库查询手册的Modules-StdPeriph_Driver-GPIO-GPIO_Private_Functions即可。二、SysTick实验本实验涉及到了SysTick,即系统滴答定时器,以及向量中断控制器NVIC。NVI
7、C与CM3内核逻辑紧密相连,在包含控制寄存器和中断处理的控制逻辑外,还包含了MPU、SysTick定时器及调试控制相关的寄存器。SysTick定时器被捆绑在NVIC中,用于产生SysTick异常(异常号:15)。在以前,操作系统还有所有使用了时基的系统,都必须要一个硬件定时器来产生需要的“滴答”中断,作为整个系统的时基。操作系统需要用它来为多个任务分以不同数目的时间片,实现分时复用。而此SysTick定时器即用于产生滴答中断。在STM32中,SysTick以FCLK(内部时钟,CM3上自由运行的时钟)为运行时钟。本实验要实现LED每500ms变换一次状态,利用的是SysTick的定时功能。首先
8、,系统时钟被设置为了72MHz,GPIO已被初始化,不提。之后是SysTick的初始化。其函数在SysTick.c文件中,定义如下:void SysTick_Init(void)/* SystemFrequency / 1000 1ms中断一次 * SystemFrequency / 100000 10us中断一次 * SystemFrequency / 1000000 1us中断一次 */if (SysTick_Config(SystemFrequency / 100000) /* Capture error */ while (1); 这里用到的库函数是SysTick_Config(uin
9、t32_t ticks),其参数即为计数初值,当定时器打开后,SysTick的值将从初值递减,直至减至0时,产生一个SysTick中断。本实验中设定每10us中断一次,因此设初值为72M/100000(SystemFrequency值即为72M),故SysTick中断一次耗时(72M/100000)/72M(s)=10us。if判断加上whlie循环一句是在等待函数返回0(即操作成功)然后跳出,从而保证SysTick设置是正确的。定时器写好以后,又怎么写它的中断函数呢?在MDK中,看Project窗口如下:前面提到,在STM32的工程中,我们将在USER中放置中断函数的文件,即是stm32f1
10、0x_it.c,写中断函数时只需在该文件中对应的中断函数中写入自己的代码即可。本实验中代码如下:/* * brief This function handles SysTick Handler. * param None * retval : None */void SysTick_Handler(void)TimingDelay_Decrement();其调用的函数TimingDelay_Decrement()的定义在文件SysTick.c文件中,负责执行一个计数变量的减一操作。而在SysTick.c文件中的Delay_us()函数会初始化该计数变量TimingDelay并等待其减至0,从而
11、实现延时等待。在main.c的主函数中,以下代码实现了500ms延时,其计算见注释:LED1( 0 ); Delay_us(50000); / 50000 * 10us = 500msLED1( 1 );至此,通过SysTick定时器实现LED的定时变换状态就能实现了。有一点要清楚:本实验用到的关于SysTick的库函数SysTick_Config(uint32_t ticks)的定义并非来自STM32固件库,而是CM3内核的库。因为SysTick不是片内外设,而是被包含在内核中。另外还有这么个变量类型定义值得注意:void Delay_us(_IO u32 nTime)关于代码中的变量定义:
12、_IO u32 nTime,查得_IO为volatile,u32即为uint32_t。volatile作为一个类型修饰符,其作用是表示该类型变量可能被未知的因素更改,因此编译器每一次执行读取该变量的代码时都应直接存取其原始内存地址,而不是进行优化操作。笔者认为这里用到_IO是因为nTime这个变量不是在Delay_us函数中而是在中断函数中被减小的,因此加上了_IO以保证其数值在读取时不会被优化操作,即认为Delay_us函数并未对其操作从而直接读取原来没变的值。后面提到的采用位带技术的寄存器位定义都将加上volatile。三、USART1通信实验明显,在使用USART1前要先对其进行初始化,
13、见以下代码:void USART1_Config(void)GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* config USART1 clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);/* USART1 GPIO config */ /* Configure USART1 Tx (PA.09) as alternate function push-pull */ GPI
14、O_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART1 Rx (PA.10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode
15、= GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* USART1 mode config */USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No ;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowCon