




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、6.1 STM32 IO 简介本章将要实现的是控制 ALIENTEK战舰STM32开发板上的两个LED实现一个类似跑马灯的效果,该实验的关键在于如何控制 STM32的IO 口输出。了解了 STM32的IO 口如何输出的,就可以实现跑马灯了。通过这一章的学习,你将初步掌握STM32基本IO 口的使用,而这是迈向 STM32的第一步。这一章节因为是第一个实验章节,所以我们在这一章将讲解一些知识为后面的实验做铺垫。为了小节标号与后面实验章节一样,这里我们不另起一节来讲。在讲解STM32的GPIO之前,首先打开我们光盘的第一个固件库版本实验工程跑马灯实验工程(光盘目录为:4,程序源码 标准例程-V3.
2、5库函数版本 实验1跑马灯/USER/LED.UV2 ”),可以看到 我们的实验工程目录:图6.1.1跑马灯实验目录结构接下来我们逐一讲解一下我们的工程目录下面的组以及重要文件。组FWLib下面存放的是ST官方提供的固件库函数,里面的函数我们可以根据需要添加和删除,但是一定要注意在头文件stm32f10x_conf.h文件中注释掉删除的源文件对应的头文件,这里面的文件内容用 户不需要修改。组CORE下面存放的是固件库必须的核心文件和启动文件。这里面的文件用户不需要修改。组SYSTEM是ALIENTEK提供的共用代码,这些代码的作用和讲解在第五章都有讲解,大家可以翻 过去看下。 组HARDWAR
3、E下面存放的是每个实验的外设驱动代码,他的实现是通过调用FWLib下面的固件库文件实现的,比如led.c里面调用stm32f10x_gpio.c里面的函数对led进行初始化,这里面的函数是讲解的 重点。后面的实验中可以看到会引入多个源文件。组USER下面存放的主要是用户代码。但是system_stm32f10x.c文件用户不需要修改,同时stm32f10x_it.c里面存放的是中断服务函数,这两个文件的作用在3.1节有讲解,大家可以翻过去看看。Main.c函窥主要存放的是主函数了,这个大家应该很清楚。针对第步中怎么随意添加和删除固件库文件,这里我们稍微讲解一下。首先从上面的图中可以看到,stm
4、32f10x_gpio.c源文件下面include 了好几个头文件,其中有一个stm32f10x_conf.h ,这个文件会被每个固件库源文件引用。我们可以打开看看里面的内容:EE璃I可衲承值雪吗国色捌 ®睚LED - jKision? - E门电干技本*日常开发*升中版*写书本的整珥X曳够I密吊灯、USERlwmEfh=|L11 Uli MieR- Eraj eel 加卜y Flji'di Fc-upher*!,lols SWCS 11111d/ 生工郡素3 A - Pro0dt Wodptace口 有 tarml E3 USERS 国 riii-H e田 因 EtnlZf
5、lOwJ t. eE 图=yst*n_strt32fiOM. c邑 KAfiTtfAKEl+l 团 IP c£3 STStEU s国a.i呼片 田函<75 . c E 图,asirt. e白 COKEl+l 庄| mr jk3. c 阿 i;l tr tVf_i t*3£ f 1004 t双2324252627国330/n Deline r o pt event recucalve incliaslan#l£ndei _3TM3 S F10x_CGNF_Hdefine -STM32F10t(-CQNF-H/ * I Mludes*/ * fnjcotziie
6、ni:/ C ojmenE the line be lev co e nab Le/ d 1 sail le per Lphetal tieader file IucLubIoii/include /include /Hinclijdc /# include /# iftsCliide include include /Sinjclude #indge /# include /Nlfiflude,r8cra3Z110x_adc.tiH scraSillOKkp.,f stmSZi 10M_cnn, hw,R=tni32ilOM2cE&- hH rrBCft32jEia3c2tKt. I
7、t" ,r3Cjn3211OM2dae. H",r3cm321 lOx_dbgmc u h”10x_c3nja. hN ,p5tm32ilO-eKtiBhN ,R=tm32f i 口算二叠 la-rhh* r,a:r:ft32jEiaw-fsftie. H"/#iaclude /#lnclu«:ie /(llticlude /#includekJ -G=Jgi-占 PMLLL日区=tn3Zfl&M_gpi».fl 匚 =| Ebi32£IOx_fpi&.sbiflOi hrj cure_cwi3# 1 nc I ude
8、 rT3T:n3 2 f 10x_gp lo -11”</#laclud.e tfaxmJZTiEx_LZc-hR /#include ,kscjh32:1 lOxnfldg. h"/WineIvdc ,rstin32i IQk.p革耳,h"i elc 1 u.di= FP3traS2f lOx 工亡eh"sbi32£IOx conf.J Etn32£IOxjrcc.T sbiSflOX-sirtrJ| msc.田因 14gssflQx-rs c ' 田 团 工th32"flCLS4 U-Li± t. c 田苗
9、雨|号工为?2土2口乂_:£1:t.1!1" ,rscra32iiox2scaiai. ti" 情«加3之二1口乂二2口 1,hrt ,h3tm32t lOx tiJEi. hN哥 i Ite l udc 8=53 2 f lOysnirt, hHi岷 1 udEIQx vvdlg;. h."i itc 1 ude "id 1st - h." / * HlgH level f umexj. 口 ns for NVIC and SysTlek add-on co CHS 13 funet .匡h%3EE1O.Ptrcigtai
10、n Size: Cadc-44BD RO-daES*33fi Rff-daEa52 ZI-datS-lB36.FromELFs eiceating heK f 1 le. . u", ,OEJLED. EL、工,二 口工丫0£ |日), ?修1:111口白)白) 口 HuilH A Cqmmflnd 入 FhdinlFZ /"C.:.rtfeK-W3 J-LDfl图 6.1.2 stm32f10x_conf 文件内容从图中可以看出,在头文件stm32f10x_conf.h文件中,我们包含了四个.h头文件,那是因为我们的FWLib组下面引入了相应的 4个.c源文件。
11、同时大家记住,后面三个源文件stm32f10x_rcc.c,stm32f10x_usart.c以及misc.c在每个实验基本都需要添加。在这个实验中,因为 LED是关系到STM32的GPIO,所以我们增加了 stm32f10x_gpio.c和头文件stm32f10x_gpio.h的引入。添加和删除固件库源文件的步骤是:1 .在stm32f10x_conf.h文件引入需要的.h头文件。这些头文件在每个实验的目录STM32F10x_FWLibinc下面都有存放。2 .在FWLib下面加入步骤一中引入的.h头文件对应的源文件。记住最好对应,否则就有可能会报错。这些源文件在每个实验的STM32F10x
12、_FWLibsrc目录下面都有存放。添加方法请参考3.3节的内容。最后我们讲解一下这些组之间的层次结构:图6.1.3代码层次结构图从层次图中可以看出,我们的用户代码和HARDWARE下面的外设驱动代码再不需要直接操作寄存器,而是直接或间接操作官方提供的固件库函数。但是后面我们的为了让大家更全面方便的 了解外设,我们会增加重要的外设寄存器的讲解,这样对底层知识更加了解,方便我们深入学习固件 库。准备内容我们就讲解到这里,接下来我们就要进入我们跑马灯实验的讲解部分了。这里需要说明一下,我们在讲解固件库之前会首先对重要寄存器进行一个讲解,这样是为了大家对寄存器有个初步的了解。大家学习固件库,并不需要
13、记住每个寄存器的作用,而只是通过了解寄存器来对外设一些功能有个大 致的了解,这样对以后的学习也很有帮助。首先要提一下,在固件库中,GPIO端口操作对应的库函数函数以及相关定义在文件stm32f10x_gpio.h和 stm32f10x_gpio.c 中。STM32的IO 口相比51而言要复杂得多,所以使用起来也困难很多。首先 STM32的IO 口可以由软件配置 成如下8种模式: 1、输入浮空 2、输入上拉 3、输入下拉 4、模拟输入 5、开漏输出 6、推挽输出 7、推挽式复用功能 8、开漏复用功能每个IO 口可以自由编程,但IO 口寄存器必须要按32位字被访问。STM32的很多IO 口都是5V
14、兼容的,这 些IO 口在与5V电平的外设连接的时候很有优势,具体哪些IO 口是5V兼容的,可以从该芯片的数据手册管脚描述章节查到(I/O Level标FT的就是5V电平兼容的)。STM32的每个IO端口都有7个寄存器来控制。他们分别是:配置模式的2个32位的端口配置寄存器 CRL和CRH; 2个32位的数据寄存器IDR和ODR; 1个32位的置位/复位寄存器BSRR ; 一个16位的复位寄存器 BRR;1个32位的锁存寄存器LCKR。大家如果想要了解每个寄存器的详细使用方法,可以参考STM32中文参考手册 V10» P105P129。CRL和CRH控制着每个IO 口的模式及输出速率。
15、STM32的IO 口位配置表如表 6.1.4所示:配置模式CNF1CNF0MODE1MODEOPXODR寄存器通用愉出推挽式(Push-Pull)000110。或1n (Open-Drain)10或1旦用功能推挽式(Push-Pull)1011不使用见表3. 1.2输出开漏(OpenRraii)1不使用输入模拟输入0000不便用浮空输入1不使用下拉输入1100上拉输入1表6.1.4STM32的IO 口位配置表STM32输出模式配置如表6.1.5所示:MODE1:0意义00保留01最大输出速度为10MHz10最大输出速度为2MHz11最大输出速度为50M42表6.1.5 STM32输出模式配置表
16、接下来我们看看端口低配置寄存器CRL的描述,如图6.1.6所示:31302928272625242322212019181716CNF7 1:0MODE? :1:QCWF6l:0MODE6E1:01MODE51:0CNF4l:0:MODE41:0:rw rwrT rwrw rwrw rwrw rwrw rwrw rwrw rw151.4131211109876543210CNF31:OM0DE3:l:0CWF2l:0MODE2L1:01CTL J:0:MODE1:1:01CNFO1:0:MODEO1:Q:rw rwrw rwrw rwrw rwrw rwrw rwrw rwrw rw也 31:
17、30 2726 232219181514 11107:63:2CNFy1:0:端口x配置位值 = 口7)软件通过这些位配置相府的I心端口,请参考表15端口位配置表0在输入模式网口0目1:0=口0):00:模想输入模式Oh浮空输入模式(更位后的状态)10:上拉,下拉输入模式1 L保留在输出模式(1 :0>口0人00:通用推挽输出模式01:通用开漏输出模式10:夏用功能推换输出模式TI:亚用功能开漏输出模式位 29:2625:2421:2017:1613:129:8, 5:4 l:0MODEy1:OJ:端口x的模式位(v = 口7)软件通过这些位配置相应的I4端口,请参考表15端口位配置表.
18、00:输入模式(品位后的状态)01;输出模式,最大速度1CIMHZ10:输出模式,最大速度2MHz11:输出模式,最大速度50MHz图6.1.6端口低配置寄存器CRL各位描述该寄存器的复位值为0X4444 4444,从图6.1.4可以看到,复位值其实就是配置端口为浮空 136输入模式。从上图还可以得出: STM32的CRL控制着每组IO端口( AG )的低8位的模式。每个IO端口 的位占用CRL的4个位,高两位为CNF,低两位为MODE。这里我们可以记住几个常用的配置,比如0X0表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,50M速率)、0X8表示上/下拉输入模式(做输入口
19、用)、 0XB表示复用输出(使用IO 口的第二功能,50M速率)。CRH的作用和CRL完全一样,只是CRL控制的是低8位输出口,而CRH控制的是高8位输出口。这里我 们对CRH就不做详细介绍了。下面我们讲解一下怎样通过固件库设置GPIO的相关参数和输出。GPIO相关的函数和定义分布在固件库文件stm32f10x_gpio.c和头文件stm32f10x_gpio.h文件中。在固件库开发中,操作寄存器 CRH和CRL来配置IO日的模式和速度是通过 GPIO初始化函数完成:void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitS
20、truct) ;这个函数石两个参数,第一个参数是用来指定GPIO,取值范而为GPIOAGPIOG 。第二个参数为初始化参数结构体指针,结构体类型为GPIO_InitTypeDef。下面我们看看这个结构体的定义。首先我们打开我们光盘的跑马灯实验,然后找到FWLib组下面的stm32f10x_gpio.c文件,定位到GPIO_Init函数体处,双击入口参数类型GPIO_InitTypeDef后右键选择 Go to definition of ”可以查看结构欣的定义:typedef structuint16_t GPIO_Pin;GPIOSpeed_TypeDef GPIO_Speed;GPIOMo
21、de_TypeDef GPIO_Mode;GPIO_InitTypeDef;下面汨门通过一个GPIO初始化实例来讲解这个结构体的成员变量的含义。通过初始化结构体初始化 GPIO的常用格式是:GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;LED0->PB.5端 口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; / 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 速度 50
22、MHzGPIO_Init(GPIOB, &GPIO_InitStructure);/ 根据设定参数配置 GPIO上面代码的意思是设置 GPIOB的第5个端口为推挽输出模式,同时速度为 50M。从上面初始化代码可以 看出,结构体GPIO_InitStructure的第一个成员变量 GPIO_Pin用来设置是要初始化哪个或者哪些IO 口;第二个成员变量GPIO_Mode是用来设置对应IO端口的输值输入模式,这些模式是上面我们讲解的8个模式,在MDK中是通过一个枚举类型定义的:typedef enum GPIO_Mode_AIN = 0x0,/ 模拟输入GPIO_Mode_IN_FLOATI
23、NG = 0x04,/ 浮空输入GPIO_Mode_IPD = 0x28,/ 下拉输入GPIO_Mode_IPU = 0x48,/ 上拉输入GPIO_Mode_Out_OD = 0x14,/ 开漏输出GPIO_Mode_Out_PP = 0x10,/ 通用推挽输出GPIO_Mode_AF_OD = 0x1C,/ 复用开漏输出GPIO_Mode_AF_PP = 0x18/ 复用推挽GPIOMode_TypeDef;第三个参数层IO 口速度设置,有三个可选值,在 MDK中同样是通过枚举类型定义:typedef enumGPIO_Speed_10MHz = 1,GPIO_Speed_2MHz,GPI
24、O_Speed_50MHzGPIOSpeed_TypeDef;这些入口参薮的取值范围怎么定位,怎么快速定位到这些入口参数取值范围的枚举类型,在我们上面章节4.7的快速组织代码”章节有讲解,不明白的朋友可以翻回去看一下,这里我们就不重复讲解,在后面的实验中,我们也不再去重复讲解怎么定位每个参数的取值范围的方法。IDR是一个端口输入数据寄存器,只用了低16位。该寄存器为只读寄存器,并且只能以16位的形式读出。该寄存器各位的描述如图 6.1.7所示:3130292S272625242322212019181716保留1514131211109876543210二匕匕IDR111JK13IDR12ID
25、E11IDRLO工DR。IDRSIDR7LDR6二血1DR1IDR31DR2LDR1IDR&rrrrrrrrrrrrrrr位31:16 保留,始翳读为0.位 15:0IDRyl5:0?端H输入数据国=0 ,15)这些位为只读并只能以字(傕位)的形式读出*读山的值为对应!/0!的状态.图6.1.7端口输入数据寄存器IDR各位描述要想知道某个IO 口的电平状态,你只要读这个寄存器,再看某个位的状态就可以了。使用起来是比较 简单的。在固件库中操作IDR寄存器读取IO端口数据是通过 GPIO_ReadInputDataBit函数实现的: uint8_t GPIO_ReadInputDataBi
26、t(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)比如我要读GPIOA.5的电平状态,那么方法是:GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);返回值是 1(Bit_SET)或者 0(Bit_RESET);ODR是一个端口输出数据寄存器,也只用了低16位。该寄存器为可读写,从该寄存器读出 来的数据可以用于判断当前IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。该寄存器的各位描述如图6.1.8所示:3130292S272625212322212019181716保留151413121110986543
27、210DDE? 15''ORI 1C:R13DORICODR11i-OF.100DR9OCRSODR70DR6ODR50DK10DR30DR20DR1ODROrwrwrwYWrwrwrwYWrwrwrwrwrwrwrw位31:16保留.始终读力。.图6.1.8端口输出数据寄存器 ODR各位描述在固件库中设置 ODR寄存器的值来控制IO 口的输出状态是通过函数 GPIO_Write来实现的:void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);该函数一所来往一次,li 一个 GPIO的多个端口设值。BSRR寄存器是端口位设置
28、/清除寄存器。该寄存器和ODR寄存器具有类似的作用,都可以 用来设置GPIO端口的输出位是1还是0。下面我们看看该寄存器的描述如下图:31302928272625242322212019181716RR15HR I IBR13BRI 2BRIOBR90R8BR7BR6BR5BR4BR3BR2BRIBROwwwwwwwwwwwwwwww15141312111098 i654320BS15B514BS13BS12BS11BS10BS9E5EBS7BS6BS5BS4BS3BS2BS1BSOW W W W W W W W W W W tf W W W17.31:16BRy:清除端口算的与y(v = 0
29、. 15) (Pori k Reset bity)这些位只能写入并只能以字(16位)的形式操作,0;时时应的。口Ry位不产生影响3清除对应的ODRy位为0注:如果同时设置了BSyfilBRy的对应位,BSy位起作用“位150BSy:设置端口1的位v (y = 0,.15) (Port x Set bit y)这些位只能写入并只能以字(16位)的形式操作n0:对对应的。口Ry位不产生影响设苴对应的。DRy位为1图6.1.9端口位设置/清除寄存器BSRR各位描述该寄存器通过举例子可以很清楚了解它的使用方法。例如你要设置GPIOA的第1个端口值为1,那么你只需要往寄存器BSRR的低16位对应位写1即
30、可:GPIOA->BSRR=1<<1;如果你要设置GPIOA的第1个端口值为0,你只需要往寄存器高 16位对应为写1即可:GPIOA->BSRR=1<<(16+1)该寄存器往相应位写0是无影响的,所以我们要设置某些位,我们不用管其他位的值。BRR寄存器是端口位清除寄存器。该寄存器的作用跟BSRR的高16位雷同,这里就不做详细讲解。在STM32固件库中,通过BSRR和BRR寄存器设置GPIO端口输出是通过函数GPIO_SetBits()和函数 GPIO_ResetBits()来完成的。void GPIO_SetBits(GPIO_TypeDef* GPIOx,
31、 uint16_t GPIO_Pin);void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint?6_t GPIO_Pin)在多数情加下,我们都是采用这两个函数来设置GPIO端口的输入和输出状态。比如我们要设置GPIOB.5输出1,那么方法为:GPIO_SetBits(GPIOB, GPIO_Pin_5);反之如果要设置GPIOB.5布H位0,方法为:GPIO_ResetBits (GPIOB, GPIO_Pin_5);GPIO而关的函数我们先讲解到这里。虽然IO操作步骤很简单,这里我们还是做个概括性的总结,操作步骤为:1) 使能 IO 时钟。调用函数为 RC
32、C_APB2PeriphClockCmd()。2)初始化IO参数。调用函数GPIO_Init();3)操作IO。操作IO的方法就是上面我们讲解的方法。上面我们讲解了 STM32 IO 口的基本知识以及固件库操作 GPIO的一些函数方法,下面我们来讲解我们的 跑马灯实验的硬件和软件设计。6.2硬件设计本章用到的硬件只有LED (DS0和DS1)。其电路在ALIENTEK战舰STM32开发板上默认 是已经连接好了的。DS0接PB5, DS1接PE5。所以在硬件上不需要动任何东西。其连接原 理图如图6.2.1下:"1PE4 T7Vi+PE5| LED5PE6Kt 复QtFL?KLI Jv
33、<vir n iPH3 KACEDO FSX:C_A19 PE4TRACED 1.FSVc2a-CiPE 5 TRACED : FS M C_A21PFMKXCEDS.FSX:C A22LEDO DSOLEDJ I DFIFO RCLK., JTg.Vl|福rPB5 135VMT)AC PB6 136U"U 口 匚 J JUD二口口 LZPB3 HDO;TRACESWO. SPI.;_SPB4, JNTRST. SPI3_MISOH: IKI SXH-M S-H u> PB6I2C1 SCL TE<4 CHI3专门 MDRr 1f图6.2.1LED与STM32连接原
34、理图6.3软件设计跑马灯实验我们主要用到的固件库文件是:stm32f10x_gpio.c /stm32f10x_gpio.hstm32f10x_rcc.c/stm32f10x_rcc.hmisc.c/misc.hstm32f10x_usart /stm32f10x_usart.h其中stm32f10x_rcc.h头文总£每个实验中都要引入,因为系统时钟配置函数以及相关的外设时钟使能函数都在这个其源文件 stm32f10x_rcc.c中。stm32f10x_usart.h和misc.h头文件在我们 SYSTEM文件夹中 都需要使用到,所以每个实验都会引用。在stm32f10x_conf
35、.h文件里面,我们注释掉其他不用的头文件,只引入以下头文件:#include "stm32f10x_gpio.h"#include "stm32f10x_rcc.h"#include "stm32f10x_usart.h"#include "misc.h"首先,找到之前3.3节新建的Template程,在该文件夹下面新建一个HARDWARE的文件 夹,用来存储以后与硬件相关的代码,然后在HARDWARE文件夹下新建一个LED文件夹, 用来存放与LED相关的代码。如图6.3.1所示:励f电子技术常开发1京华触'
36、;妄华版库请教黎理1支势盅马灯Qd|x文件9 编辑 登看值 收雅 工具。 帮助如。后退I番,搜索 好快图,力比R' 2E电子技术Z日常开发I窟华版、豪华版函函数整理'实睑I跑回灯文件和文件妻仔爵大二也建一个新文件夹感将这个交件夹发布到5HRU井室比文件夹其它位置妾平版库函数整理 我的交档共享交替 我的电的 网上邻居陋j STM32F10x_FWLihkiilkilll. hat MS-DOS批处理文件1 KEf T对象3S9号节 j我的电胭图6.3.1新建HARDWARE文件夹然后我们打开USER文件夹下的LED.UV2工程(如果是使用的上面新建的工程模板,那么就是Templa
37、te.Uv2 ,大家可以将其重命名为 LED.Uv2) ,按按钮新建一个文件, 然后保存在HARDWARE->LED文件夹下面,保存为led.c。在该文件中输入如下彳弋码:#include "led.h"初始化PB5和PE5为输出口 .并使能这两个口的时钟/LED IO 初始化void LED_Init(void) GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);/ 使能 PB,PE端口时钟GPIO
38、_InitStructure.GPIO_Pin = GPIO_Pin_5;/LED0->PB.5推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; / 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_5);/PB.5 输出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;/LED1->PE.5推挽输出
39、GPIO_Init(GPIOE, &GPIO_InitStructure);GPIO_SetBits(GPIOE,GPIO_Pin_5); /PE.5 输出高该代码里面就包含了一个函数void LED_Init(void) ,该函数的功能就是用来实现配置PB5和PE5为推挽输出。这里需要注意的是:丸配置 STM32外设的时候,任何时候都要先使能该外设的时钟! GPIO是挂载在APB2总线上的外设,在固件库中对挂载在 APB2总线上的外设时钟使能是通过函数 RCC_APB2PeriphClockCmd() 来实现的。对于这个入口参数设置,在我们前面的 “快速组织 代码 ”章节已经讲解很清
40、楚了。看看我们的代码:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);/ 使能 GPIOB,GPIOE 端口时钟这行代码的作用是使能 APB2总线上的GPIOB和GPIOE的时钟。在配置完时钟之后,LED_Init配置了 GPIOB.5和GPIOE.5的模式为推挽输出,并且默认输出1。这样就完成了对这两个IO 口的初始化。函数代码是:GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;/LED0->GPIOB.5端口配置GPIO_InitStructure.G
41、PIO_Mode = GPIO_Mode_Out_PP; / 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/IO 口速度为 50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);/ 初始化 GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5);/GPIOB.5 输出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;/LED1->GPIOE.5 推挽输出GPIO_Init(GPIOE, &GPIO_InitStructure)
42、;/ 初始化 GPIOE.5GPIO_SetBits(GPIOE,GPIO_Pin_5); /GPIOE.5 输出高这里需要说明的是,因为 GPIOB和GPIOE的IO 口的初始化参数都是设置在结构体变量GPIO_InitStructure中,因为两个IO 口的模式和速度都一样,所以我们只用初始化一次,在GPIOE.5的初始化的时候就不需要再重复初始化速度和模式了。最后一行代码:GPIO_SetBits(GPIOE,GPIO_Pin_5);的作用是在初始化中将 GPIOE石输出设置为高。保存led.c代码,然后我们按同样的方法,新建一个led.h文件,也保存在LED文件夹下面。在led.h中输
43、入如下代码:#ifndef _LED_H#define _LED_H#include "sys.h"/LED 端口定义 #define LED0 PBout(5)/ DS0#define LED1 PEout(5)/ DS1void LED_Init(void);/ 初始化#endif这段代码里面最关键就是2个宏定义:#define LED0 PBout(5)/ DS0#define LED1 PEout(5)/ DS1这里使用的是位带操作来实现操作某个IO 口的 1个位的, 关于位带操作前面第五章5.2.1 已经有介绍, 这里不再多说。需要说明的是,这里同样可以使用固件库
44、操作来实现IO 口操作。如下:GPIO_SetBits(GPIOB,GPIO_Pin_5);/ 设置 GPIOB.5 输出 1,等同 LED0=1;GPIO_ResetBits(GPIOB,GPIO_Pin_5);/ 设置 GPIOB.5 输出 0,等同 LED0=0;有兴施的朋友不妨修改我们的位带操作为库函数直接操作,这样也有利于学习。将led.h也保存一下。接着,我们在Manage Components管理里面新建一个 HARDWARE的组,并把led.c加入到这个组里面,如图 6.3.2所示:图6.3.2给工程新增HARDWARE组单击OK,回到工程,然后你会发现在 Project Wo
45、rkspace里面多了一个 HARDWARE的组,在改组下 面有一个led.c的文件。如图6.3.3所示:Project Worfcspacex三j Target 1B 曰 VSEE+ 囱 main, c+5t»32fl0xi t. c+ 国 syst«m_itmi2fl0xL c-b KimAEES 圃 Itlct 浮 SYSTEM王闺册1盯.CE U sys c土囱 us art. cB m C0R£+ 国 core_cii3. c£ 5tartup_5tn32fl0x_Jid. st 曰 FWLib+ 囱 mi sc. c+ 画 stm32flQx
46、_gpio. c+ 1 stfi32fl0x_rec. c+' 因 stiB32fl0x_usart. c+ 国 s tn32 fl 0x_dbgjn cu. c图 6.3.3新增 HARDWARE 组然后用之前介绍的方法(在3.3.3节介绍的)将led.h头文件的路径加入到工程里面。回到主界面,在main函数里面编写如下代码:#include "led.h"#include "delay.h"#include "sys.h"/ALIENTEK战舰STM32开发板实验1/跑马灯实验 int main(void)delay_in
47、it();/延时函数初始化LED_Init();/初始化与LED连接的硬件接口while(1)LED0=0;LED1=1;delay_ms(300);/延时 300msLED0=1;LED1=0;delay_ms(300);/延时 300ms 一代码包含了 #include "led.h"这句,使得LED。、LED1、LED_Init等能在main()函数里被调用。这里我们需要重申的是,在固件库 V3.5中,系统在启动的时候会调用system_stm32f10x.c中的函数SystemInit()对系统时钟进行初始化,在时钟初始化完毕之后会调用main()函数。而以我们不需
48、要再在main()函数中调用SystemInit()函数。当然如果有需要重新设置时钟系统,可以写自己的时钟设置代码,SystemInit()只是将时钟系统初始化为默认状态。main()函数非常简单,先调用delay_init()初始化延时,接着就是调用LED_Init()来初始化GPIOB.5和GPIOE.5为输出。最后在死循环里面实现LED0和LED1交替闪烁,间隔为300ms。上面是通过位带操作实现的IO操作,我们也可以修改 main()函数,直接通过库函数来操作IO达到同样的效果,大家不妨试试。int main(void)delay_init();/延时函数初始化LED_Init();/
49、初始化与LED连接的硬件接口while(1)GPIO_ResetBits(GPIOB,GPIO_Pin_5);/PB5 输出低,LED0=0;GPIO_SetBits(GPIOE,GPIO_Pin_5);/PE5 输出高,LED1=1;delay_ms(300);/延时 300msGPIO_SetBits(GPIOB,GPIO_Pin_5);/PB5 输出高,LED0=1;GPIO_ResetBits(GPIOE,GPIO_Pin_5);/PE5 输出低,LED1=0;delay_ms(300);/延时 300ms 一将主函数替换为上面代码,然后重新执行,可以看到,结果跟用位带操作一样的效果。大家可以对比一下。这个代码在我们光盘的实验代码实验1跑马灯-库函数操作中。手后按l|j ,编译工程,得到结果如图6.3.4所示:M tfinipillhig sEJis3Zf 10K_usare -u|COmplllDQp 3tl»3 Z r 10K_dEiQTftC!ll > C
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中国苯酞项目商业计划书
- 伊春市人民医院药物治疗质量控制考核
- 签了协议书离婚
- 中国橡胶板橡胶带行业市场前景预测及投资价值评估分析报告
- 中国丙烯腈项目商业计划书
- xx县供热管网改造工程可行性研究报告
- 中国羟甲基脲项目商业计划书
- 煤电硅一体化项目可行性研究报告
- 光电子信息材料产业项目可行性研究报告
- 赤峰市中医院医用耗材药品合理使用管理督查试题
- 预防医学考试题+答案
- 二年级上册数学北师大版课件第5课时 小熊开店
- 跌倒坠床原因分析预防措施
- 52206马工程组织行为学课件
- 我和我的祖国课件
- 各类食物营养与配餐(蛋类的营养)课件
- 公司内账管理系统
- 全国细菌耐药监测网信息系统-附件
- 妇产科产前诊断技术服务临床医师考核题(附答案)
- 校园欺凌工作台账(完整资料)
- DB33∕T 1146-2018 浙江省城市轨道交通规范
评论
0/150
提交评论