《stm32初学例程.docx》由会员分享,可在线阅读,更多相关《stm32初学例程.docx(20页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、kongstIf an error, please contact author, to be corrected.For other uses, indicate the source, to express my recognition of the result s.Thank you.Introduction由于公司需要,以及充满对arm 的向往,开始学习STM32.。与8位单片机不同,32位处理器的开发变得更加复杂,同时也伴随着性能和功能的显 著提高。由于初学 STM32, 遇到了很多莫名其妙的问题,但是总归是在自己的摸索中一个个的解决了。说来惭愧,三个星期天天忙 STM32, 总算
2、实现了几个常用的功能,心中窃喜arm也不过如此嘛!当然, STM32 许多过人之处还没有细细研究,巧妙设计之处还没有完全的感受到,暂 且就当是小小的步入STM32 开发初期阶段吧。为了纪念STM32 学习过程的辛劳和无助,记下我的学习过程,与大家共勉。也希望能 为广大的初学者提供小小的帮助。如有任何问题和建议,您可以联系kongst此文章所采用的开发环境如下A、开发板、仿真器:使用的是STM32F103C8-PKT+ST-LINK;B 、开发环境: IAR Embedded Workbench for ARM 6.10 Kick start;C 、Firmware:STM32F10x StdP
3、eriph Lib V3.4.0首先安装IAR Embedded Workbench for ARM, 32K Kick start Edition;下载STM32F10x StdPeriph Lib V3.4.0;购买一块开发板,通过ST-Link进行仿真和调试;(所有的资源都可以到IAR 和 ST 官网上下载,资源的获取也是很重要的,要是自己不 培养找资源的功夫,就不是一个好的开发人员,这里就不留网址了)关于编译环境和仿真方法可以参考我的另 一 篇记录环境搭建的文章 EWARM STM32 Use Instructions。_ _ _在成功搭建开发环境之后,我们就可以对STM32 进行深入
4、的学习了, STM32 功能繁多, 不可以一下子学习所有的知识,因此采用各个击破,由简转难的学习方法, 一步步的学会 STM32 的功能。总之,我们需要调通每一个经常使用到的功能。而本篇文章就是记录了调通某些功能的 历程,以及在调试过程中可能会出现的问题。由于自身能力的限制,对有些知识点可能理解的不是很透彻,因此错误难免,希望谅解并给出指导建议。您可以通过 kongst 联系我,谢谢。在使用固件库时,需要自己有点C 语言的相关基础,如结构体、枚举、指针等;1 GPIO Test(端口操作实验)GPIO 实验是最简单,也是一般最先开始的一个实验,他可以搭建一个最小的工程项目, 之后,所有的实验都
5、可以建立在该项目之上,从而节省了在搭建过程中所消耗的时间和精力。 建议,当该实验顺利完成后,作为一个模板,供以后实验使用,确保您可以将精力花费在需要实现的功能上。关于环境的搭建,您可以参考EWARM STM32 Use Instructions;本实验需要实现:四个LED 的简单控制。1.1 硬件设计:1.确认硬件连接:根据开发板原理图,如图,得知:与LED 相连的有PB12、PB13、PB14、PB15;以下就是对这四个引脚的配置,及相关操作;JP3LED+3V31LD2RS1PB12LED1PB13LED2PB14LED3PB15LED41KLEDLD1REDmLD3 RELD4REDRE
6、DUSB5V1.2软件设计:/main()程序开始1.2.1 头文件:#include stm32f10x.h#include main.h/#include k gpio.h#define VECT TAB RAM_ _/main()函数:/已经转移到main 函数中;/选择在RAM 中调试;1.2.2 系统初始化SystemInit();/选择系统运行时钟,默认是72MHz, 可以调试跟踪进行修改;#ifdef VECT TAB RAM /设置仿真调试区域,这里设置成在RAM 中;/ Set the Vector Table base location at 0x20000000NVIC
7、SetVectorTable(NVIC VectTab RAM,Ox0);#else /*VECT TAB FLASH */_ _/ Set the Vector Table base location at 0x08000000NVIC SetVectorTable(NVIC VectTab FLASH,Ox0);#endif1.2.3 GPIO 配置/首先,选择GPIOB 外设时钟;只有选择好时钟后,才可以进行下面的配置;RCC APB2PeriphClockCmd(RCC APB2Periph GPIOB,ENABLE);/配置端口,开始时,不需要知道所有的细节,从字面上理解就ok;gp
8、io.GPIO Pin =GPIO Pin 12|GPIO Pin 13|GPIO Pin 14|GPIO Pin 15;gpio.GPIO Speed=GPIO Speed 50MHz;gpio.GPIO Mode =GPIO Mode Out PP;GPIO Init(GPIOB,&gpio);GPIO SetBits(GPIOB,GPIO Pin 12); /将端口拉高,灭LED 灯;GPIO SetBits(GPIOB,GPIO Pin 13);GPIO SetBits(GPIOB,GPIO Pin 14);GPIO SetBits(GPIOB,GPIO Pin 15);如此, GPI
9、OB 连接LED 的四个端口都配置好了;1.2.4 GPIO操作While(1)GPIO ResetBits(GPIOB,GPIO Pin 12);Delay(Oxffffff);GPIO ResetBits(GPIOB,GPIO Pin 13);Delay(0xffffff);GPIO ResetBits(GPIOB,GPIO Pin 14);Delay(Oxffffff)GPIO ResetBits(GPIOB,GPIO Pin 15);Delay(Oxffffff);Delay(Oxffffff);Delay(Oxffffff);GPIO SetBits(GPIOB,GPIO Pin 1
10、2);Delay(Oxffffff);GPIO SetBits(GPIOB,GPIO Pin 13);Delay(0xffffff);GPIO SetBits(GPIOB,GPIO Pin 14);Delay(Oxffffff);GPIO SetBits(GPIOB,GPIO Pin 15);Delay(Oxffffff);GPIO ResetBits(GPIOB,GPIO Pin 12);GPIO ResetBits(GPIOB,GPIO Pin 13);GPIO ResetBits(GPIOB,GPIO Pin 14);GPIO ResetBits(GPIOB,GPIO Pin 15);如
11、此而已;这是最简单的实验,可以为此建立一个拥有自己特色的工程模板;1.3 Test注意A、 硬件必须首先确保正确;B、 开发环境搭建确保正确;C、 系统时钟的选择要清楚;仿真所处的区域要清楚;D、 外设时钟的配置是第一位的,其他配置都在其后;2 Time2 Test(Time2 定时实验)Timer作为控制器和处理器的一个重要的组成部分,是几乎所有系统都需要的一个模块,可以提高程序的实时性、精确性,以及安全性,是最为重要的一个学习方面;STM32 有着丰富的Time 系统,很容易使初次接触的人产生恐惧,不过,归咎起来,他 的作用也只是定时和计数,只不过衍生的功能比较强大,有PWM, 比较捕获,
12、强制输出等,其实不需要所有的功能都掌握,您只需要用到什么功能再去学习某个功能即可;本实验需要实现:使用Time2 进行定时的功能,使得LED 灯进行相应时间的闪烁。2.1 硬件设计在Time2 上,主要是芯片内部实现,所以Time2 无需关注硬件;操作的LED, 我们需要实现与PB12 引脚相连的LED 的亮灭;2.2软件设计#include stm32f10x.h#include main.h/#include k gpio.h/#include k time2.h#define VECT TAB RAM_ _void main()/已经转移到main 函数中;/本实验增加部分,但已经转移到
13、main 函数中;GPIO InitTypeDef gpio;TIM TimeBaseInitTypeDef time2; /本实验增加部分NVIC InitTypeDef nvic; /本实验增加部分SystemInit();#ifdefVECT TAB RAM_ _/Set the Vector Table base location at 0x20000000NVIC SetVectorTable(NVIC VectTab RAM,0x0);#else /*VECT TAB FLASH */_ _/Set the Vector Table base location at 0x08000
14、000NVIC SetVectorTable(NVIC VectTab FLASH,0x0);#endif/GPIOB 端口配置RCC APB2PeriphClockCmd(RCC APB2Periph GPIOB,ENABLE);gpio.GPIO Pin =GPIO Pin l2|GPIO Pin 13|GPIO Pin 14|GPIO Pin 15;gpio.GPIO Speed =GPIO Speed 50MHz;gpio.GPIO Mode =GPIO Mode Out PP;GPIO Init(GPIOB,&gpio);GPIO SetBits(GPIOB,GPIO Pin 12)
15、;GPIO SetBits(GPIOB,GPIO Pin 13);GPIO SetBits(GPIOB,GPIO Pin 14);GPIO SetBits(GPIOB,GPIO Pin 15);/以上已经有过详细的论述,可以参考先前的Test;/以下是本实验增加的部分;/Time2配置RCC APB1PeriphClockCmd(RCC APB1Periph TIM2/RCC APB2Periph AFIO,ENABLE);NVIC PriorityGroupConfig(NVIC PriorityGroup o);nvic.NVIC IRQChannel=TIM2 IRQn;/nvic.NV
16、IC IRQChannelPreemptionPriority=0;nvic.NVIC IRQChannelSubPriority=1;nvic.NVIC IRQChannelCmd =ENABLE;NVIC Init(&nvic);TIM DeInit(TIM2);/设置Time2 中断向量相关;/设置Time2 相关;time2.TIM CounterMode =TIM CounterMode Up;time2.TIM Prescaler=0;time2.TIM ClockDivision =TIM CKD DIV1;_ _ _time2.TIM Period=1000;/TIM Time
17、BaseStructure.TIM RepetitionCounterTIM TimeBaseInit(TIM2,& time2);TIM PrescalerConfig(TIM2,Ox8c9F,TIM PSCReloadMode Immediate);TIM ARRPreloadConfig(TIM2, DISABLE);TIM ITConfig(TIM2,TIM IT Update, ENABLE);TIM Cmd(TIM2, ENABLE); /启动Time2;while(1)关于系统外设时钟的选择,可以参见相关手册,这是一个比较复杂的关系,这里给个简单的图:(由红色框图中得知, Tim
18、e2 采用的是APB1 之后的时钟系统)8 MHz HSIRCPLLSRCHSIPLLMUL48 MHzUSBPrescaler/1, 1.5anblePercheral clockPerioheral cbCkI2S3CLKI282CLKanabioPeripheral clock enablePeripheral clock enable72 MHz maxClockEnable/8SWUSBCLKto USB interfacetol2S3tol2S2SDIOCLKtD SDIOto FSVCFSMCCLKHCLKto AHB bus, corememory and DMAto Cari
19、ex Syster timerFCLK Cortex,x18 2,3,4HSPLLCLKHSES AHBPrescaler721NHZmax /1,2.512APB1rescaler /1,2,4,8,16ree running clock36 MHz maxPeriphefal Cocx EnabioPCLK1to APB1penpheralsTIM2,3,4,5,8.7;12,13,14If(APB1 prescaler=1)1 1o TIM2,3,4.5.6.7,12,13,14CSSels8 x2 TIMXCLKPeripheral ClockEnabloOSC OUTOSC INOS
20、C32 JN_OSC32 OUT4-16 MHzHSE OSCLSE OSC32.768 kHzLSI RC40 kHzPLLXTPRE/2/128-D RTCLSERTCCLKRTCSEL:0LSIto Indopendent watchdog(IWDG)WDGCLKAPB272 MHz maxPCLK2peripheralsPrescalerto APB2/1,2.4.8,16Perbheral ClockEngbleTIM1,8 ,9 .10 ,11 tmerslf(APB2 prescaler =1)x1 to TIM1.8.9.10 and 11Peripheral Clokelse
21、 x: TIMxCLKEnableADCPrescaller10 ADC1,2 or 3/2,4.6,8ADCCLK 14 MHzmaxHCLK/2/2Peripheral clockenableTo SDIO AHB nterfaceMainClock OutoutMCOvdo/2 PLLCLKHSI-HSESYSCLKLegend:HSE= High speed external clock signalHSI=Hgh-sped interal clock signalLSI= Low-speed nternal clock signalLBE = Lomspeed externalclo
22、ck signal由于本实验,涉及到中断,而且对于端口的操作,是在中断中进行的;其中中断函数名称的由来,在startup stm32f10x hd.s (或其它)文件中,如图:c|k gpio,c |k time2.c|stm32F10x it.c DMAl Channel4 IRQHandlerDCD DCD DCD DCD DCD DCD DCD DCD DCD DCD DCD DCD DCDDCDDCDDCDDCDDCD; DMAl Chanmel 4DNA1 Channe15 IRQHandler DMAl Channel6 IRQHandler DMAl Channel7 IRQHa
23、ndler ADC12 IRQHandlerUSB HP CAN1 TX IRQHandlerUSB LP CANl RXO IRQHandler CAN1 RX1 IRQHandler;CANI SCE IRQHandler :EXTI9 5 IRQHandlerTIM1 BRK IROHandlerTIM1 UP IRQHandlerTIM1 TRG COM IRQHandler TIM1 CC IRQHandlerTIM2 IRQHandlerTIM3 IRQHandlerTIM4 IROHandlerI2Cl EV IRQHandler; DMAl Chanmel 5; DMAl Ch
24、arnel 6; DMAl Channel 7; ADC1 & ADC2: UsB High Priority or CANl TX;USB Low Priority or CANl RXOCAN1 RX1CANl SCE; EXTI Line 9.5;TIMl Break; TIMl Update;TIMl Trigger and Commutation;TIMl Capture Compare; TIM2; TIM3; TIM4; I2Cl Event中断程序如下:u8 ledflag=0;void TIM2 IRQHandler(void)if(TIM GetITStatus(TIM2,
25、TIM FLAG Update)!=RESET)TIM ClearITPendingBit(TIM2,TIM FLAG Update);if(ledflag+%2)GPIO SetBits(GPIOB,GPIO Pin 12)elseGPIO ResetBits(GPIOB,GPIO Pin 12);我想这么简单的中断程序应该没问题吧。2.3 Test注意A、 学会使用以前用过的模板,节省环境搭建时间;B、 学会查看数据手册,理解外设系统时钟的选择原因;C、 学会中断程序的编写,中断向量、函数的获取;V3 USART Test(串口收发实验)只要是 Project, 只要是嵌入式开发,我想都免
26、不了使用通讯,来和外界联系;只要使 用通讯,最先想到的就是USART。 这是一个很是常用的和非常好用的通讯方式。所有的处理器、控制器上,基本上都无一例外的增加USART 功能。初学者在经历了环境搭建、 GPIO 、Time 定时之后,就需要接触USART 相关了。本实验需要实现: USART 的中断接收和发送,实现将收到的数据回发出去。3.1 硬件设计查看开发板原理图,确定好通道连接情况:引脚是否对,跳线是否短接。33UART=C5CN2DB9-male USART11C1+162384Rlout95T2in9R2out-二C8104PC2+TloutRlinT2outR2inCC7104PR
27、S232 TX1ZC6104P 311USARTIUSARTIU2ST3232ECTRC1-TlinRS232 RX1C29104P1210104P2V+VCCGND78PA10TXPA9C2.16RX131514465_图中显示:使用PA9(TX) 和 PA10(RX) 和 STM32 连接。3.2软件设计由上述两个实验,我们可以总结出:1、外设时钟选择时钟是第一位的;2、 只要使用到端口,就需要初始化端口;3、 使用到其他外设,需要一一配置外设时钟;4、 使用中断的,需要配置好中断向量,以及编写中断函数;本实验开始:#include stm32f10x.h#include main.h/#
28、incude k usart.h /已经转移到main 函数中;#defineVECT TAB RAM_ _void main(void)GPIO InitTypeDef GPIO InitStructure;USART InitTypeDef USART InitStructure;NVIC InitTypeDef nvic;/USART ClockInitTypeDef USART InitClockStructure;SystemInit();#ifdef VECT TAB RAM_ _/Set the Vector Table base location at 0x20000000NV
29、IC SetVectorTable(NVIC VectTab RAM,0x0);#else /*VECT TAB FLASH */_ _/Set the Vector Table base location at 0x08000000NVIC SetVectorTable(NVIC VectTab FLASH,Ox0);#endif/以下是USART 的配置部分RCC APB2PeriphClockCmd(RCC APB2Periph USART1|RCC APB2Periph GPIOA,ENABLE);/ /GPIO StructInit(&GPIO InitStructure);GPIO
30、 InitStructure.GPIO Pin= GPIO Pin 9 ;_ _ _ _ _ _ _ _GPIO InitStructure.GPIO Speed=GPIO Speed 50MHz;GPIO InitStructure.GPIO Mode = GPIO Mode AF PP;GPIO Init(GPIOA,&GPIO InitStructure);GPIO InitStructure.GPIO Pin_ _GPIO InitStructure.GPIO Mode_ _= GPIO Pin 10;= GPIO Mode IN FLOATING;GPIO Init(GPIOA,&G
31、PIO InitStructure);nvic.NVIC IRQChannel=USARTl IRQn;nvic.NVIC IRQChannelPreemptionPriority=3;nvic.NVIC IRQChannelSubPriority =2;nvic.NVIC IRQChannelCmd = ENABLE;NVIC Init(&nvic);/USART StructInit(&USART InitStructure);_ _USART InitStructure.USART BaudRate = 115200;USART InitStructure.USART WordLengt
32、h = USART WordLength 8b;USART InitStructure.USART StopBits =USART StopBits l;USART InitStructure.USART Parity =USART Parity No;USART InitStructure.USART Mode =USART Mode Tx|USART Mode Rx;USART InitStructure.USART HardwareFlowControl_ _USART HardwareFlowControl None;_ _USART Init(USART1,&USART InitSt
33、ructure);USART InitClockStructure.USART CPOL=USART CPOL Low,_ _ _ _USART InitClockStructure.USART CPHA=USART CPHA 2Edge;USART InitClockStructure.USART LastBit =USART LastBit Disable;_ _ _ _USART InitClockStructure.USART Clock=USART Clock Disable;_ _ _ _USART ClockInit(USART1,&USART InitClockStructur
34、e)*/USART Cmd(USART1,ENABLE);USART ITConfig(USART1,USART IT RXNE,ENABLE); USART ITConfig(USART1,USART IT TXE,DISABLE);/先使能接收中断; /先禁止发送中断;while(1)/接下来就交给中断处理;USART1 IRQn 中断函数在stm32f10x it.c中:/include stdio.huint32 t RxBuffer_void USARTI IRQHandler(void)if(USART GetITStatus(USART1,USART IT RXNE)!=RESE
35、T)RxBuffer =USART ReceiveData(USART1);USARTITConfig(USART1,USART IT TXE,ENABLE);USART ITConfig(USART1,USART IT RXNE,DISABLE);/printf(R);if(USART GetITStatus(USART1,USART IT TXE)!=RESET)USART SendData(USART1,RxBuffer);USART ITConfig(USART1,USART IT TXE,DISABLE);USART ITConfig(USART1,USART IT RXNE,ENABLE);/printf(S);详细细节在这里不做论述,可以从命名中得知一般配置usart 的步骤;可以F12 去探究 其缘由,以及涉及的相关寄存器;3.3 Test注意1、在中断中,需要注意USART 的中断条件,当发送中断ENABLE 时,只要没有数据处理,就会进入中断,因此需要发送时才打开,不需要时, 一定要关闭;2、还是那句话,先配置外设时钟;3、关于STM32 中断相关配置,可以参考数据手册理解NVIC;4 USART DMA Test(串口DMA 收发实验)
限制150内