STM32f103C8T6入门学习记录.doc_第1页
STM32f103C8T6入门学习记录.doc_第2页
STM32f103C8T6入门学习记录.doc_第3页
STM32f103C8T6入门学习记录.doc_第4页
STM32f103C8T6入门学习记录.doc_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

STM32 自 学 笔 记 作者:忙碌的小姚 新浪微博:忙碌的小姚 新浪博客: /mlxiaoyao222 目录STM32 自 学 笔 记1第一章3我与STM32 的那些日子3第二章4使用固件库建立一个工程41、了解STM32F103的固件库42、创建第一个工程43、接下来就是管理工程文件了94、编写main.c 和文件路径10第三章14STM32点亮第一个LED 使用keil for ARM MDK 软件仿真141、Main.c 函数代码:142、代码分析:153、软件仿真介绍:16第四章19串口的使用191、为什么要用串口?192、STM32跟PC机(也就是电脑)如何连接193、代码分析204、仿真及调试235、串口接收数据25第五章27通用定时器的使用271、STM32F103内部定时器有哪些?272、如何进行程序编写273仿真结果观察304对第四章串口的补充315工程代码35第一章 我与STM32 的那些日子 STM32这块板子是在阿莫上跟一个老师买的,砍了半天100块钱。包括一个Jlink v8仿真器(好像65块左右),和一块STM32系统板。那已是一年前的事了。那时我刚大三,刚学了半年51,于是想学点更高级的。但我好像属于三分钟热度的这种人,买回来学了一个星期,就学不动了,寄存器操作,固件库的使用根本就没明白是怎么一回事,之后就没有然后了。现在看到那块板子,总有一种说不出的滋味,要是当时能咬牙切齿努力学习,说不定现在也不会安静地坐在电脑前一字一句敲打这篇激励性文章了。对于STM32我没用任何基础,唯一有的也只是一年前学的那一个星期,不过那已不重要了,我现在仍是一个小白。作为一个初学者,也许是坐井观天,看的是片面的,可能有很多观点是错误的,希望读者朋友能勇于指出来。 -前记第二章使用固件库建立一个工程我打算先从软件编程学起,以前用过KEIL 和IAR,IAR我比较熟悉,因为参加电子设计竞赛的时候,就是用它编程MSP430程序的。但我还是选择了KEIL,也许因为资料比较多,或者别的吧,我没分析过KEIL 和IAR代码效率如何,因为这不是我现在要考虑的,软件都只是工具而已。我去百度搜索了几篇如何在KEIL MDK环境下建立STM32工程,加上自己的实践。我也把我的初学者步骤贴出来。1、了解STM32F103的固件库我在网上下了STM32F103的固件库-stm32f10x_stdperiph_lib 3.5V版的,里面内容如图所示,据说STM32F103和STM32F101都能用。2、创建第一个工程 1.新建一个文件夹取名如 first_project,也可以建在桌面。 2.在里面新建 CMSIS ,libraries ,Libaries , List(用于链接的) , Obj(工程文件) , output (输出hex文件), User 文件夹; 3. 将固件库里 Libraries-STM32F10x_StdPeriph_Driver 下的 inc 和src 文件夹复 制到fisrt_project 文件夹下的libraries 里; 将固件库里 Libraries-CMSIS-CM3-CoreSupport文件夹里面的 core_cm3.c 和core_cm3.h 文件复制到我们新建的fisrt_project 文件夹下的CMSIS 里; 将固件库里 Project-STM32F10x_StdPeriph_Template(这个文件家里有KEIL和 IAR建好工程的模板)里的stm32f10x_conf.h , stm32f10x_it.c , stm32f10x_it.h , system_stm32f10x.c 四个文件 复制到我们新建的fisrt_project 文件夹下的User 里; 如下图所示 打开keil uvision4 MDK , 在菜单栏里点击project 选择 new uVision project 保存工程名,选择Obj文件夹, 文件名为first_project ,不用加后缀格式,系统默认。接下来会弹出让你选择器件的窗口,这里我们选择 STmicroelectronics 的 STM32F103C8最后会弹出是否复制启动代码的对话框,选择YES;3、接下来就是管理工程文件了 1、在project窗口右键点击Tagert 1 选择 manage conponents 或者 找到倒数第二个 品字形图标; 2、在Groups 框下面将Groups1 重命名为startup ,同时添加CMSIS, Libraries, User; 选择CMSIS 在Files框下将CMSIS文件夹的core_cm3.c添加进去; 选择Libraries在Files框下将Libraries-src文件下的所以文件都加进去添加进去; 选择User在Files框下将User文件下的所以文件都加进去添加进去; 如下图所示: 点击OK,确定;工程构架如下图所示:4、编写main.c 和文件路径 1、新建main.c 保存到User文件夹里,将其添加到User工程名下。 #include stm32f10x.h int main(void) while(1); 2、在project框下,右键点击Target 1,选择Options for Target target1 在output 选项下,在create HEX file 前打上钩, 点击select Folder for Objects 选择输出文 件夹为 output文件夹; 在Listing选项下,点击select Folder for Listings 选择链接文 件夹为 List文件夹;在C/C+选项下, define里 填入 USE_STDPERIPH_DRIVER,STM32F10X_MD 中间用英 文的逗号;(一定要记得) Include Paths 里,点击右边的文件路径框 ,选择相应的CMSIS, libraries 里的INC 和SRC 还有 User ; 也可以填绝对路径,比如: C:UsersAdministratorDesktopSTM32编程练习 fisrt_projectCMSIS 这样比较麻烦 好了,这下开始编译链接:0 Error , 0 Warring;First_project 就建好了;万里长征的第一步,总算走出去了。总结:关键是Option for target 的设置,包括output ,listing,和C/C+,尤其是C/C+这个选项里一定要设置对。Define:USE_STDPERIPH_DRIVER,STM32F10X_MD,这是预定义的两个宏定义。 在stm32f10x.h这个头文件里搜索 USE_STDPERIPH_DRIVER 有这么一段 #ifdef USE_STDPERIPH_DRIVER #include stm32f10x_conf.h #endif 据说是定义控制了是否在应用中启用外设驱动。在stm32f10x.h这个头文件里搜索 STM32F10X_MD, /* #define STM32F10X_MD */ /*! STM32F10X_MD: STM32 Medium density devices */ STM32中密度器件#ifdef STM32F10X_MDADC1_2_IRQn = 18, /*! ADC1 and ADC2 global Interrupt */ USB_HP_CAN1_TX_IRQn = 19, /*! USB Device High Priority or CAN1 TX Interrupts */USB_LP_CAN1_RX0_IRQn = 20, /*! USB Device Low Priority or CAN1 RX0 Interrupts */CAN1_RX1_IRQn = 21, /*! CAN1 RX1 Interrupt */CAN1_SCE_IRQn = 22, /*! CAN1 SCE Interrupt */EXTI9_5_IRQn = 23, /*!0;i-) for(j=1000;j0;j-); void GPIO_Config(void) GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB , &GPIO_InitStructure); int main(void) GPIO_Config(); SystemInit(); while(1) GPIO_SetBits(GPIOB,GPIO_Pin_5 ); /点亮PB.5 delay();GPIO_ResetBits(GPIOB,GPIO_Pin_5 );/熄灭PB.5 delay();GPIO_SetBits(GPIOB,GPIO_Pin_6 );/点亮PB.6 delay();GPIO_ResetBits(GPIOB,GPIO_Pin_6 );/熄灭PB.6 delay(); 2、代码分析:GPIO_InitTypeDef GPIO_InitStructure; 定义一个结构变量GPIO_InitStructure ,结构体类型为GPIO_InitTypeDef ,相当于int A ; GPIO_InitTypeDef =int GPIO_InitStructure=A一样。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); 开启GPIOB的时钟,要使用某个管脚都需要开启该管脚的时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; 管脚号设置为第五脚和第六脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Speed_10MHz, GPIO_Speed_2MHz, GPIO_Speed_50MH 设置管脚电平翻转的速率,比如不要求快速变化一般10M,做串口的时候设置较高波特率的话就使用50MHZ的。 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 设置输出为推挽输出。 它有8中工作模式,输出只有两种推挽和开漏输出。其它可以参 考相关手册GPIO_Init(GPIOB , &GPIO_InitStructure); 这一句就是将前面四句的设置初始化到GPIOB中; SystemInit(); 将系统时钟设置为72M,不写这句,默认为8M; GPIO_SetBits(GPIOB,GPIO_Pin_5 ); /点亮PB.5 delay();/ 延时GPIO_ResetBits(GPIOB,GPIO_Pin_5 );/熄灭PB.5 delay();GPIO_SetBits(GPIOB,GPIO_Pin_6 );/点亮PB.6 delay();GPIO_ResetBits(GPIOB,GPIO_Pin_6 );/熄灭PB.6 delay(); 编译链接,然后开始软件仿真3、软件仿真介绍:1、编译连接好后,点击debug 进入调试界面2、 调试窗口如下3、图片上加文字不好弄,大概就是复位、运行、停止、单步运行等我也不太熟悉,反正用到的时候试一试就知道了。4、 选择菜单栏上的 peripherals 按钮,选择general purpose I/O 的GPIOB5、 点击左上角的运行按钮 或者按F5键 就可以看到GPIOB的5,6 在一闪一闪的6、 顺便在看看波形仿真功能 点击下图的波形分析按钮 点击setup 按钮 会弹出一个窗口,在窗口的右上边,有个new的按钮,点击后 分别输入 PORTB.5 和PORTB.6 8、点击运行,将窗口调到合适的位置,最终波形图如下; 写得有些地方可能有错误,明天就要回四川了,有些急 2014年1月12日第四章串口的使用1、为什么要用串口? 自上一篇写的时间是1月20号,今6月7号了,半年没更新了。 这半年发生了什么? 过完年就去找公司实习,在那里自我感觉进步很大。其实在公司大多都是自学,师傅基本不会给你说什么。但这并不能说明你的师傅对你不好,带我的那个师傅只比我高一届,但他的水平比我高的好多届。他也是自学,也没人告诉他该怎么做,因为老板也不太懂。 所以自学能力很重要,当然有人带你的话,这样会更好。 不说这些了,串口在调试的时候作用非常大。也学我们在学51的时候,只是将程序下载到开发板,看看是否能运行起来,通过数码管将结果显示出来,从而就知道程序设计的正确性。以前我也是这样做的,没什么不好。 在公司实习的时候,他们调试都是使用串口打印输出信息,观察程序从上电、初始化、运行数据什么的全部都显示到PC机上。然后再一句一句分析它的打印信息,从而找到出错的源头。这使我对串口的认识有更深了一步,所以我决定在学习STM32的时候,开发流程跟在公司学的方法一样使用串口,观察打印信息。2、STM32跟PC机(也就是电脑)如何连接 我的STM32F103C8T6只是裸板,没有串口芯片,当然用的也是学生机笔记本电脑,同样也没串口。 解决办法1、买一块 MAX3232转接板+一条USB转串口线 +邮费=30块左右 2、只需要买一块PL2303的USB转接板。这样就将第一种的转接板和连接结合到一起了。 不过我用的是第一种,MAX3232+USB的串口线 ,为什么不用方便的2种? max3232对于没有串口的开发板可以充当电平转换芯片,如何开发板有了电平转换芯片,我便使用USB转串口线经行连接,这样便灵活了。 第二种只是用在既没转换芯片也没USB转串口的情况,不过对于最小系统板来说,它既可以下载程序,又可以当做串口来调试。 至于台式机就不需要USB转串口线了,普通串口线即可。 连接示意如下所示: 3、代码分析再写这里之前,应该已经学过模块化编程了,STM32的每个XXX.c 和xxx.h 这都是模块化编程。良好的程序,与其好的代码风格有关。你的代码风格跟你接触教你写代码的有很大关系。 以前刚刚学习单片机编程,我还不信,现在我承认,跟教我单片机的老师风格有些像。 这里我做的是一个串口发送数据到PC机的例子:要让STM32能够顺利发出数据,要进行如下配置PA9,PA10管脚要配置,USART也需要配置波特率,数据有几位,停止位,数据流等。USART和uart有什么区别 USART在做串口时,两者并不区别,但是USART有SPI的功能。还有串口通信为什么要配置波特率,停止位,硬件数据留这些,以前我也没想过,现在只觉得协议这个东西,是一个好的标准。建立一个usart_debug.c的文本,内容如下#includeusart_debug.hvoid GPIO_Configuration(void) GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);/使能UASRT的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);/使能GPIOA的时钟,开始的时候,我没用这句话,调了两天,跟源码一句一句比才知道 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; /波特率较高,IO翻转需较高频率GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /复用推挽输出;我看网上有人说设置成GPIO_Mode_Out_PP普通推挽输出也行,但实践出真知,我试了发送是乱码。;GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /配置成浮空输入,既然是输入所以就不用配置IO口的频率了GPIO_Init(GPIOA,&GPIO_InitStructure); void USART1_config(void)USART_InitTypeDefUSART_InitStructure;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_HardwareFlowControl_None; /硬件流 USART_InitStructure.USART_Mode =USART_Mode_Rx |USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); /*这段很重要,如果要使用printf函数打印信息,需要加fputc函数,就需要对printf函数重定向到串口,以前工作中他们老是提重定向,什么串口重定向,USB重定向什么的,我也是云里雾里,如今给我的感觉就是将上层函数实现对底层硬件的操作*/ int fputc(int ch, FILE*f) while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET); /*网上的一些函数里面是没有这一句代码,如果不加的话,打印时第一个字符就会没有,原因据说是硬件复位后,USART_FLAG_TC被置一了,而要发送数据必须让其为底才可以,一表示数据发送发出的标志,也可以用这样一句USART_ClearFlag(USART2,USART_FLAG_TC);清楚标志位。可是我没这样做一样发成功了,这个疑惑以后再想明白。*/ USART_SendData(USART1, (uint16_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET); return ch; void usart_debug_config(void) /提供给main函数调用的串口配置函数 GPIO_Configuration(); /IO口配置 USART1_config(); /串口配置还就是usart_debug.h #ifndef _usart_debug_H#define_usart_debug_H#include stm32f10x.h#include void usart_debug_config(void); int fputc(int ch, FILE *f); #endif /* _USART1_H */main函数: 这里使用两种方式一种是 使用普通的方式发送,另一种使用printf函数 其实还有一种USART_printf函数来实现,这里不做介绍。有空看看区别一下printf和usart_printf,据说是支持格式多少的问题#includestm32f10x.h#includeusart_debug.h /包含main函数里的调用函数int main(void) unsigned char TxBuf1100 =发送字符串!!rn; int i;SystemInit();usart_debug_config(); for( i = 0; TxBuf1i != 0; i+) while(USART_GetFlagStatus(USART1, USART_FLAG_TC)=RESET);/这里跟分析fputc时是一样的 USART_SendData(USART1 , TxBuf1i);/发送字符数组里的单个字符 while(USART_GetFlagStatus(USART1, USART_FLAG_TC)=RESET); printf(hello world! 世界你好! rn); /调用printf函数 while(1) ; 4、仿真及调试 程序编好之后,在target option里要选择 USE microLIB (keil自带的微库),这是使用非标准C库,在编译链接是,将我们编写的fputc函数作为编译的首选,否则就会编译stdio.h里的fputc函数。 写到这里我发现我这个代码感觉不是很好,使用微库而不用标准C库,应该会有影响,我瞬间就明白了他们为什么要自己编写支持输出格式很少的的USART_printf函数了,后面目测我也会使用这个函数。 一个好的程序代码就是结构健全,BUG很少。把简单做到极致下载后通过secureCRT或者串口小助手观察在KEIL里继续软件仿真 仿真和下载时要注意的是,仿真要选USE Simulation 而下载要选右边的JTAG。然后点击debug 进入调试界面view-serial windos -UART 1 全速运行 其结果如下:串口发送数据就到此为止。5、串口接收数据 这儿写的跟上面的已经没有关系了,不要搞混。关于从PC机发送数据到STM32,这一部分则需要中断来实现,因为我们不需要时时刻刻都来检测外部是否发出数据给STM32,因此只要有数据来,就触发中断。这里就需要配置NVIC了 void NVIC_Config(void)NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /优先组为2 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; /打开USART中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; /抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; /子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /中断通道使能NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);/串口接收中断使能 USART_Cmd(USART1, ENABLE);其他配置比如串口复用到IO配置,串口时钟配置,和发送数据是一样的。串口中断处理函数:void USART1_IRQHandler(void) int RX_status; /自己定义一个标志位 RX_status = USART_GetFlagStatus(USART1, USART_FLAG_RXNE);/读取接收数据标志位,如果装好了一帧数据则硬件将其置一。if(RX_status = SET) USART_SendData(USART1 , USART_ReceiveData(USART1);/将收到的数据再由STM32发送给PC机。while(USART_GetFlagStatus(USART1, USART_FLAG_TC)=RESET);/等待发送完成。 串口的发送接收大致如此,还是要搞懂什么数据位,硬件流,停止位,校验位什么,一个东西既然出现了就要好好分析出现的意义。想到了今天给电脑拆机清灰,电脑最好两年清一次。反正每次上螺丝都会多出那么一两个来,是不是可以不用要? 肯定不是,生产商肯定也知道节约成本什么,他们的结构工程师也知道PCB上开一个螺丝孔也是要收钱的。所以每一颗螺丝都有它的意义,所以什么校验位,停止位也有他的意义,即便我们不使用。 其实剩的螺丝我也扔了,完全不知道上在哪儿! 记于2014年6月8日串口发送数据 百度云盘:/s/1bn0ADLt串口发送接收数据 百度云盘:/s/1dD7YkZv第五章通用定时器的使用1、STM32F103内部定时器有哪些? STM32一共有8个通用16位Timer,其中TIMER1和TIMER8是高级定时器,其它的TIMER2TIMER7是普通定时器。 此外还有一个Systick(系统滴答定时器),这个定时器通常在操作系统中作为系统的任务切换周期。 还有一个RTC,是一个毫秒定时器,支持秒级中断,用来做实时时钟计数器。 看门狗定时器 也可以算一个。 8个定时器中,Timer1 和Timer8是由APB2(输出最高频率为72MHZ)预分频后,再通过一个倍频器得到时钟频率,最高为72MHz。Timer2Timer7则是由APB1(输出最高频率为36MHZ)预分频后,再通过一个倍频器得到时钟频率,最高为36MHz。2、如何进行程序编写 这里我通过定时器来控制一个LED亮0.5s 灭0.5s ,交替闪烁。当然要让定时器正常工作起来,还要配置中断NVIC。定时器计数到某个数,产生中断,从而进入中断服务程序,点亮LED灯。main函数分析: #include stm32f10x.hvoid GPIO_Config(void)/GPIO配置 GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);/使能gpioc的时 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; /选择管脚PC.13作LED灯 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /管脚速度为50M GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /设置输出模式为推挽输出 GPIO_Init(GPIOC, &GPIO_InitStructure); /将上述设置写入到GPIOC里去 void NVIC_Config(void) /中断控制器的配置NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /优先组设置NVIC_InitStructure.NVIC_IRQChannel =TIM2_IRQn ; /TIM2中断选通 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; /抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /使能中断控制NVIC_Init(&NVIC_InitStructure);void Timer_Config(void) /定时器的配置TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); /Timer2 时钟使能 TIM_DeInit(TIM2); /复位TIM2定时器 TIM_TimeBaseStructure.TIM_Period=1000; /定时器周期TIM_TimeBaseStructure.TIM_Prescaler=36000-1; /预分频数TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /TIM2时钟分频,为1表示不分频TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;/定时器计数为向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ClearFlag(TIM2, TIM_FLAG_Update); /清除定时器2的溢出标志位TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); /使能定时器2溢出中断TIM_Cmd(TIM2, ENABLE); /定时器2使能int main(void) SystemInit();/初始化时钟,配置为72MHz,我试过将这句注释掉,好像不影响结果。查 了一下,在配置 /main函数之前的启动代码有这样一句 LDR R0, =SystemInit,我疑惑的是难 道启动的时候就配成72Mhz? GPIO_Config(); NVIC_Config();Timer_Config(); while(1) ; 中断服务函数 void TIM2_IRQHandler(void)static int flag_bit=0;/定义一个标志位if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) /判断中断溢出标志为是否为1 TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); /清除溢出中断标志位 flag_bit = !flag_bit; if(flag_bit = 1) GPIO_SetBits(GPIOC, GPIO_Pin_13); /熄灭LED if(flag_bit = 0) GPIO_ResetBits(GPIOC, GPIO_Pin_13); /点亮LED 这个函数是写在stm32f10x_it.c 里面的,我对TIM2_IRQHandler()函数的理解应该是这样的: 首先由定时器定时,定时好了产生中断溢出标志位,发送中断 然后进入中断服务函数TIM2_IRQHandler(),进入函数之后要做的就是清除中断溢出 标志位。 最后再执行函数里的其他内容。定时器定时时间计算是这两句: TIM_TimeBaseStructure.TIM_Period=1000; /定时器周期 TIM_TimeBaseStructure.TIM_Prescaler=36000-1; /预分频数 Prescaler可以理解为定时器的基数是72M / Prescaler+1 = 2000k,也就是500us ,Period 可以理解为要计数多少次,这里是1000次。 所以就是每500us记一次,计数1000次,就是500ms。公式为: Period / (72M / (Prescaler+1) )=_ 秒 1000 / (72 M/ (35999+1) ) = 0.5 秒我有的一些疑问:1、进入中断函数之后,定时器要干些什么,是不是就停止计数了? 2、计数记到1000发生中断,计数值是不是有自动清零 问题先放到这儿,边学习,边解决。 3仿真结果观察前面第三章已经过如何仿真波形的步骤,可以参看前面。点击setup 按钮 会弹出一个窗口,在窗口的右上边,有个new的按钮,点击后输入 PORTC.13-仿真运行结果如下:可以从仿真结果中观察到,方波的周期为一秒。占空比为0.5 ,跟预期一致。4对第四章串口的补充 第四章介绍了串口的打印函数printf 是如何调用实现的。但要使用keil自带的微库microLIB ,那能不能不使用这个微库呢。我参照野火的教程,修改了程序,自己编写usart_printf()函数来实现打印的功能。 USRT1的配置不改变,主要的就是添加打印函数实现串口输出功能。代码感觉可能很长,但无非就是一些判断,看看字符串最后一位是不是0 ,很多时候我都没注意: 1、 这一句while ( *Data != 0) / 判断是否到达字符串结束符 我们平时不是都用 0 吗? 用0开始我还没反应过来。 其实ASCII的十六进制的0 就是0 如果要使用0,while ( *Data !=0) ,主要要加单引号表

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论