嵌入式系统导论(第2版) 课件 第5、6章 STM32的GPIO、CM3异常和STM32中断_第1页
嵌入式系统导论(第2版) 课件 第5、6章 STM32的GPIO、CM3异常和STM32中断_第2页
嵌入式系统导论(第2版) 课件 第5、6章 STM32的GPIO、CM3异常和STM32中断_第3页
嵌入式系统导论(第2版) 课件 第5、6章 STM32的GPIO、CM3异常和STM32中断_第4页
嵌入式系统导论(第2版) 课件 第5、6章 STM32的GPIO、CM3异常和STM32中断_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

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

文档简介

嵌入式系统导论主讲教师:第5章STM32的GPIO本章内容提要5.1GPIO的结构和功能5.2GPIO寄存器5.3GPIO输出应用:LED灯的亮灭控制5.4GPIO输入应用:查询按键状态5.5STM32库编程总结主

机外设接口电路参考资料:STM32F10x系列参考手册参考资料:STM32库帮助文档stm32f10x_stdperiph_lib_um.chmSTM32F10xStandardPeripheralsFirmwareLibrary5.1GPIO的结构和功能STM32提供通用的输入输出引脚(GPIO)输出高低电平控制外设输入0、1检测外设状态可配置为复用的输入输出引脚(AFIO)大多数GPIO都有默认的复用功能:可作为片上外设(如串口、ADC等)的I/O引脚部分GPIO还有重映射功能:把原来是A引脚的默认复用功能,映射到B引脚使用GPIO:General-PurposeInputs/OutputsAFIO:Alternate-FunctionInputs/Outputs通用I/O端口GPIOSTM32F10x微控制器有7组(个)GPIO端口用GPIOx(x是A、B、C、D、E、F、G)表示 即GPIOA、GPIOB、……GPIOG每组端口有16个引脚分别用Px0、Px1、……Px15(x是A~G)表示每组端口具有7个寄存器1.配置寄存器:GPIOx_CRL、GPIOx_CRH2.数据寄存器:GPIOx_IDR、GPIOx_ODR3.位控寄存器:GPIOx_BSRR、GPIOx_BRR4.锁定寄存器:GPIOx_LCKRGPIO端口位的基本结构STM32F10x系列参考手册(Referencemanual)5.2GPIO寄存器每组端口具有7个寄存器实现对GPIO端口初始化配置和数据输入输出控制每个寄存器只能以32位(字)进行访问不允许16位(半字)或8位(字节)访问7个寄存器分成4种1.配置寄存器:选择引脚功能,例如输入或输出2.数据寄存器:保存引脚输入电平或输出电平3.位控寄存器:控制某引脚为1或04.锁定寄存器:锁定引脚配置(不允许修改)GPIO:General-PurposeInputs/OutputsGPIO寄存器名称寄存器缩写寄存器英文名称GPIOx_CRLConfigurationRegisterGPIOx_CRHConfigurationRegisterHighGPIOx_IDRInputDataRegisterGPIOx_ODROutputDataRegisterGPIOx_BSRRBitSet/ResetRegisterGPIOx_BRRBitResetRegisterGPIOx_LCKRConfigurationLockRegister1.GPIO的配置寄存器每组端口有两个32位配置寄存器配置寄存器低(Low)字GPIOx_CRL配置寄存器高(High)字GPIOx_CRH(x是A~G)配置寄存器低字CRL对应配置低8位引脚Px0、Px1、……Px7配置寄存器高字CRH对应配置高8位引脚Px8、Px9、……Px15ConfigurationRegisterGPIO的引脚配置两个32位(一个64位)配置寄存器每4位对应一个引脚低2位设置其工作模式(MODE)高2位设置其配置(CNF:Configuration)共有4种输入功能、4种输出功能GPIO的引脚配置功能表CNF[1:0]MODE[1:0]引脚配置的功能0000(输入)模拟输入模式01浮空输入模式(默认)10上拉输入模式10下拉输入模式0001(输出,10MHz)10(输出,2MHz)11(输出,50MHz)通用推挽输出模式01通用开漏输出模式10复用推挽输出模式11复用开漏输出模式输出模式有3种I/O驱动电路的响应速度可选2.GPIO的数据寄存器每组端口有两个32位数据寄存器一个是输入数据寄存器IDR一个是输出数据寄存器ODR都只使用其低16位、依次对应每个GPIO引脚当设置GPIO引脚为输入模式时从输入数据寄存器GPIOx_IDR的相应位读出该I/O引脚的高(1)、低(0)电平当配置GPIO引脚为输出模式时向输出数据寄存器GPIOx_ODR相应位写入1或0控制该I/O引脚为高(1)、低(0)电平DataRegister端口输入数据寄存器(GPIOx_IDR)IDR:InputDataRegister端口输出数据寄存器(GPIOx_ODR)ODR:OutputDataRegister位输出问题对输出数据寄存器某位写入时要考虑其他位的状态,不能任意改变需要首先读出输出数据寄存器的内容修改相应位再写入GPIO的输出数据寄存器ODR可以读出用以支持位输出控制可以使用CM3的位段别名地址访问数据位更方便的位数据输出是使用位控寄存器3.GPIO的位控寄存器每个端口有两个位控寄存器只能写入、不能读出某位写入1实现I/O引脚复位或置位写入0对I/O引脚无影响(作用)一个是位置位/复位寄存器BSRR高16位控制引脚为低电平(复位BR:BitReset)低16位控制引脚为高电平(置位BS:BitSet)一个是位复位寄存器BRR低16位控制引脚为低电平(复位BR:BitReset)BSRR:BitSet/ResetRegister,BRR:BitResetRegister端口位设置/复位寄存器(GPIOx_BSRR)BSRR:BitSet/ResetRegister端口位复位寄存器(GPIOx_BRR)BRR:BitResetRegister4.GPIO的锁定寄存器这个32位的端口配置锁定寄存器GPIOx_LCKR用于冻结配置寄存器对I/O引脚功能的改变当对端口执行了写入锁定序列后被锁定引脚配置的工作模式不能再改变直到下次复位后才被解锁锁定功能可以防止程序随意改变GPIO配置LockRegisterstm32f10x_gpio.h定义的GPIO结构类型每组端口具有7个寄存器依次作为结构成员定义结构体变量(指针)通过结构成员访问寄存器/*定义*/typedefstruct{__IOuint32_tCRL;__IOuint32_tCRH;__IOuint32_tIDR;__IOuint32_tODR;__IOuint32_tBSRR;__IOuint32_tBRR;__IOuint32_tLCKR;}GPIO_TypeDef;#define__IOvolatile/*使用*/

GPIO_TypeDef

GPIOx;

GPIOx.CRL=0;

GPIO_TypeDef*GPIOx;GPIOx->CRL=0;stm32f10x.h定义的GPIO基地址定义基地址后,每组端口 被定义为指向这个基地址的结构类型指针#definePERIPH_BASE((uint32_t)0x40000000)...#defineAPB2PERIPH_BASE(PERIPH_BASE+0x10000)...#defineGPIOA_BASE(APB2PERIPH_BASE+0x0800)#defineGPIOA((GPIO_TypeDef*)GPIOA_BASE)5.3GPIO输出应用示例:LED等的亮灭控制【例5-1】流水灯或跑马灯程序LED在目标板上的连接使用PB0、PF7和PF8依次连接LED1~LED3GPIO引脚输出 低电平、LED亮GPIO引脚输出 高电平、LED灭【例5-1】用户需要创建或编辑的文件主程序,实现主流程代码:

main.c(文件名可以修改)LED驱动程序:

led.c和led.h(文件名可以修改)【例5-1】应用程序主要流程本例中,程序主流程有3个步骤:(1)开启外设时钟

本例是GPIOF(2)初始化外设

本例是连接LED1~LED4的GPIO引脚(3)控制外设工作

本例是置位、复位GPIO引脚1.开启外设时钟使用复位和时钟控制RCC驱动程序 (stm32f10x_rcc.c)有3个针对不同总线连接的外设时钟命令函数RCC_AHBPeriphClockCmdRCC_APB1PeriphClockCmdRCC_APB2PeriphClockCmdGPIO通过APB2总线连接系统开启GPIO外设时钟的函数

RCC_APB2PeriphClockCmd帮助文档RCC_APB2PeriphClockCmd函数GPIO通过APB2总线连接系统开启GPIOB和GPIOF外设时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);2.初始化外设1.

定义外设初始化结构变量(PPP是外设名称)

PPP_InitTypeDef

PPP_InitStructure;2.

用允许的成员值填充外设初始化结构成员

PPP_InitStructure.member1=val1; …3.

调用PPP_Init函数初始化外设

PPP_Init(PPP,&PPP_InitStructure);4.

允许外设开始工作(不是所有的外设都需要)

PPP_Cmd(PPP,ENABLE);STM32库给出的外设初始化过程GPIO的初始化函数GPIO_Init

voidGPIO_Init(GPIO_TypeDef*GPIOx,

GPIO_InitTypeDef*GPIO_InitStruct)InitializestheGPIOxperipheralaccordingtothespecifiedparametersintheGPIO_InitStruct.

Parameters:

GPIOx,:wherexcanbe(A..G)toselecttheGPIOperipheral.

GPIO_InitStruct,:pointertoaGPIO_InitTypeDefstructurethatcontainstheconfigurationinformationforthespecifiedGPIOperipheral.Returnvalues: NoneDefinitionatline173offilestm32f10x_gpio.c.帮助文档GPIO的初始化结构类型GPIO_InitTypeDef

typedef

struct{uint16_tGPIO_Pin;

/*指定配置的GPIO引脚*/

GPIOSpeed_TypeDef

GPIO_Speed; /*指定GPIO引脚输出的最高频率*/

GPIOMode_TypeDef

GPIO_Mode;

/*指定GPIO引脚配置的工作模式*/}GPIO_InitTypeDef;定义在GPIO头文件(stm32f10x_gpio.h)GPIO_InitTypeDef成员1:GPIO_Pin要进行配置的GPIO引脚编号其值是常量GPIO_Pin_y(y是0…15和ALL)#defineGPIO_Pin_0 ((uint16_t)0x0001)

/*!<Pin0selected*/#defineGPIO_Pin_1 ((uint16_t)0x0002)

/*!<Pin1selected*/ ……#defineGPIO_Pin_15 ((uint16_t)0x8000)

/*!<Pin15selected*/#defineGPIO_Pin_All ((uint16_t)0xFFFF)

/*!<Allpinsselected*/GPIO_InitTypeDef成员2:GPIO_Speed选择最高输出频率定义在枚举类型GPIOSpeed_TypeDef中typedefenum{GPIO_Speed_10MHz=1,

GPIO_Speed_2MHz,

//不赋值的枚举变量自动加1,故此常量值为2GPIO_Speed_50MHz //常量值为3}GPIOSpeed_TypeDef;GPIO_InitTypeDef成员3:GPIO_Mode选择工作模式定义在枚举类型GPIOMode_TypeDef

中typedef

enum{GPIO_Mode_AIN=0x0, //模拟输入模式

GPIO_Mode_IN_FLOATING=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;GPIOB和GPIOF初始化GPIO_InitTypeDef

GPIO_InitStructure;/*配置PB0(LED1)*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_Init(GPIOB,&GPIO_InitStructure);/*配置PF7(LED2)和PF8(LED3)*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_8;GPIO_Init(GPIOF,&GPIO_InitStructure);3.控制外设工作外设驱动库提供控制外设工作的有关函数对GPIO主要是输入和输出数据本例中只需要输出函数,例如字输出GPIO_Write函数位输出GPIO_WriteBit函数置位GPIO_SetBits函数复位GPIO_ResetBits函数帮助文档

void

GPIO_SetBits(GPIO_TypeDef*GPIOx, uint16_tGPIO_Pin)

voidGPIO_ResetBits(GPIO_TypeDef*GPIOx, uint16_tGPIO_Pin)LED驱动头文件led.h#ifndef__LED_H#define __LED_H#include"stm32f10x.h"

void

LED_Config(void);voidLED_On_all(void);voidLED_Off_all(void);voidLED_On(uint8_tled);voidLED_Off(uint8_tled);voidDelay(__IOuint32_tnCount);#endif /*__LED_H*/LED驱动源程序文件led.c-1#include"led.h"voidLED_Config(void) //LED配置函数

{ //声明外设初始化结构体变量

GPIO_InitTypeDef

GPIO_InitStructure;

//启动外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF,ENABLE);//配置LED1、LED2和LED3

…… //初始化外设:LED灯全灭

GPIO_SetBits(GPIOB,GPIO_Pin_0);GPIO_SetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8);}LED驱动源程序文件led.c-2

//LED全亮函数

voidLED_On_all(void){

GPIO_ResetBits(GPIOB,GPIO_Pin_0);GPIO_ResetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8);}//LED全灭函数voidLED_Off_all(void){

GPIO_SetBits(GPIOB,GPIO_Pin_0);GPIO_SetBits(GPIOF,GPIO_Pin_7|GPIO_Pin_8);}LED驱动源程序文件led.c-3

//指定某个LED灯亮函数,不涉及未指定的LED灯

voidLED_On(uint8_tled){switch(led){case1:GPIO_ResetBits(GPIOB,

GPIO_Pin_0);break;

case2:GPIO_ResetBits(GPIOF,

GPIO_Pin_7);break;

case3:GPIO_ResetBits(GPIOF,

GPIO_Pin_8);break;default:break;} }LED驱动源程序文件led.c-4

//指定某个LED灯亮函数,不涉及未指定的LED灯

voidLED_On(uint8_tled){switch(led)

{case1:GPIO_SetBits(GPIOB,GPIO_Pin_0);break;case2:GPIO_SetBits(GPIOF,GPIO_Pin_7);break;case3:GPIO_SetBits(GPIOF,GPIO_Pin_8);break;default:break;}}/*简单延时函数*/voidDelay(__IOuint32_tnCount){for(;nCount!=0;nCount--);}主程序main.c-1

#include"stm32f10x.h"

#include"led.h"

int

main(void)//主函数

{

LED_Config(); //LED初始化

LED_On_all(); //全亮

Delay(5000000);

LED_Off_all();

//全灭

Delay(5000000);主程序main.c-2

while(1){//逐个点亮LED,像跑马灯一样循环

LED_Off_all();

LED_On(1);Delay(1000000); ……

LED_Off_all();

LED_On(3);

Delay(1000000);}}

for(inti=1;i<4;i++)

{

LED_Off_all();

LED_On(i);Delay(1000000);

}程序软件模拟(Simulator)构建工程项目(Project→BuildTarget)启动调试(Debug→Start/StopDebugSession)通过外设(Peripherals)菜单选择GPIO的B端口打开GPIOB寄存器窗口查看其数值以及运行过程中的改变通过查看(View)菜单选择选择分析窗口(AnalysisWindows)的逻辑分析仪(LogicAnalyzer)单击“Setup”按钮设置要观察的外设引脚(本例)PORTB.0、PORTF.7和PORTF.8单步执行观察波形(注意用Zoom放大缩小时间轴)GPIO外设逻辑分析仪的设置逻辑分析仪(LogicAnalyzer)进入while语句:使用单步进入(Step,F11)在while循环中:使用单步通过(StepOver,F10)程序硬件仿真(In-CircuitDebugger)Cortex-M处理器有两种接口调试(Debug)接口:下载程序、调试执行跟踪(Trace)接口:采集数据、事件、性能等常使用JTAG/SWD接口标准连接器硬件仿真的MDK设置在MDK的目标选项Debug和Utilities标签选择使用目标板配套的硬件仿真工具添加CPU支持的Flash设置下载程序后是否自动运行TargetOptions→Debug→Setting→FlashDownload如果不是自动运行,需要目标板手动复位(上电复位或按键复位)选择创建HEX文件(CreateHEXfile)TargetOptions→Output→CreateHEXfile使用在线仿真器安装硬件在线仿真器的驱动程序在目标选项的Debug或Utilities标签中单击“Settings”,弹出仿真器的目标驱动设置(TargetDriverSetup)对话框在“FlashDownload”标签中通过“Add”按钮增加CPU使用的编程算法当打开“Debug”标签时,软件会自动扫描仿真器序列号(SN)选择端口(Port)使用SW才可以在线跟踪程序程序写入目标板命令:Flash→Download5.4GPIO输入应用示例:查询按键状态【例5-2】查询按键状态,控制LED灯亮灭查询方式检测按键KEY状态KEY在目标板上的连接PA0和PC13分别连接KEY1和KEY2按钮按下时, 相应GPIO引脚输入低电平(0), 否则输入高电平(1)【例5-2】查询按键状态引脚可配置为浮空输入模式(GPIO_Mode_IN_FLOATING)也可以配置为上拉输入模式(GPIO_Mode_IN_IPU)程序的功能按下按钮KEYx(x=1,2)对应LEDx亮一段时间, 然后熄灭按键初始函数化KEY_Config

GPIO_InitTypeDef

GPIO_InitStructure; //初始化KEY1(连接PA0)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化KEY2(连接PC13)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;GPIO_Init(GPIOC,&GPIO_InitStructure);

读入GPIO引脚值帮助文档GPIO驱动程序有两个引脚输入函数GPIO_ReadInputData,读取整个端口的16位GPIO_ReadInputDataBit,读取某个位按键检测使用位读取函数更方便

uint8_tGPIO_ReadInputDataBit

(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin)GPIOx指定端口:GPIOA…GPIOGGPIO_Pin指定引脚:GPIO_Pin_0…GPIO_Pin_15返回值是输入引脚的数值:0或1按键扫描函数KEY_Scanuint8_tKEY_Scan(uint8_tkey){

switch(key) //检测key按键,按下返回0{case1:return(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0));case2:return(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13));

default:return1;

}}主程序main.c的循环检测流程

while(1)

{//逐个检测按键,按下某个键对应LED亮

if(KEY_Scan(1)=

=

0) //KEY1按下

{while(KEY_Scan(1)==0); //等待按键结束

LED_On(1); //点亮LED1Delay(5000000);LED_Off(1);}

if(KEY_Scan(2)=

=0) ……

}GPIO_KEY示例的软件模拟启动调试(Debug→Start/StopDebugSession)打开逻辑分析仪窗口运行程序(Run,F5)软件模拟状态,输入引脚默认为低(0),所以: 按键被按下、但没有释放,导致LED引脚为高电平打开GPIOA或GPIOC窗口,改变PA0或PC13状态:

LED引脚(PB0或PF7)对应改变电平按键模拟编辑调试函数,生成仿真文件(key.ini)在目标选项的调试标签窗口输入初始化文件(InitializationFile)软件模拟的按键钮μVision的调试函数(DebugFunctions)μVision的调试函数用于辅助调试应用程序扩展μVision4调试器的功能产生外部中断将存储器内容记录在文件中周期性地更新模拟输入值给芯片上的串行端口输入串行数据μVision的调试函数使用C语言的一个子集与标准C一样,可使用流程控制语句:ifelsewhiledoswitchcasebreakcontinuegoto

调试函数中可定义局部变量,但不允许使用数组详见μVision4用户指南(μVision4User’sGuide)创建调试函数使用调试函数编辑器将调试函数保存于文件Debug—FunctionEditor开启调试函数编辑器函数编写完,使用其中“compile”命令编译通过编辑完成,保存于文件(扩展名.ini)MDK5的帮助文件:\Keil_v5\ARM\Hlp\uv4.chm软件模拟按键的调试函数(key.ini)DEFINEBUTTON"Key1","Key1Press()"//设置Key1按钮DEFINEBUTTON"Key2","Key2Press()"//设置Key2按钮signalvoidKey1Press(void){//Key1按钮的函数

PORTA|=0x01;//PA0引脚高电平

swatch(0.05);//延时0.05sPORTA&=~0x01;//PA0引脚低电平

swatch(0.05);}//PA0引脚,产生高脉冲模拟一次按键signalvoidKey2Press(void){//Key2按钮的函数

PORTC|=(0x01<<13);swatch(0.05);PORTC&=~(0x01<<13);swatch(0.05);}//PC13引脚,产生高脉冲模拟一次按键使用调试函数可在命令窗口输入函数名及参数运行例如运行printf内置函数:>printf("HelloWorld\n")

将在输出窗口的命令页显示“HelloWorld”将调试函数编辑成为一个仿真文件,然后在命令窗口使用INCLUDE命令执行文件内容>INCLUDEKEY.INI或者在设置目标选项,每次启动调试器自动执行OptionsforTarget-Debug-InitializationFile5.5STM32库编程总结安装MDK-ARM和STM32驱动程序库项目创建、配置目标选项编写外设驱动函数和主程序文件软件模拟、硬件仿真总结1:常量定义各种参数值等定义有常量、或者枚举常量一般常量采用大写英文字母表达枚举常量使用下划线分隔各个字段、单词首字大写枚举类型枚举常量及含义FunctionalStateDISABLE=0:禁止ENABLE=1:允许FlagStatus(ITStatus)RESET=0:复位(清除、清零、置0)SET=1:置位(置1)ErrorStatusERROR=0:错误SUCCESS=1:成功GPIO模式常量:GPIOMode_TypeDef引脚配置的功能STM32枚举常量模拟输入模式GPIO_Mode_AIN浮空输入模式(默认)GPIO_Mode_IN_FLOATING上拉输入模式GPIO_Mode_IPD下拉输入模式GPIO_Mode_IPU通用推挽输出模式GPIO_Mode_Out_OD通用开漏输出模式GPIO_Mode_Out_PP复用推挽输出模式GPIO_Mode_AF_OD复用开漏输出模式GPIO_Mode_AF_PP总结2:外设函数外设函数名用一个下划线分隔两个部分下划线前面部分是该外设的缩写PPP(大写字母)下划线后面部分是反映函数功能的词汇,每个单词首字母采用大写字母、后跟小写字母函数名函数功能PPP_InitPPP初始化PPP_DeInit复位PPP寄存器为默认值PPP_StructInit使用默认数据填充PPP结构PPP_Cmd允许或禁止外设PPP

GPIO库函数函数名函数功能GPIO_InitGPIO初始化GPIO_Write字输出GPIO_WriteBit位输出GPIO_SetBits置位GPIO_ResetBits复位GPIO_ReadInputData输入端口的字输入GPIO_ReadInputDataBit输入端口的位输入GPIO_ReadOutputData输出端口的字输入GPIO_ReadOutputDataBit输出端口的位输入总结3:外设结构类型每种外设一般至少有两个结构体数据类型外设寄存器结构体PPP_TypeDef用于访问外设寄存器定义在系统头文件stm32f10x.h外设初始化结构体PPP_InitTypeDef用于配置外设初始化参数定义在外设头文件stm32f10x_ppp.h总结4:使用外设的编程步骤(1)开启外设时钟使用RCC库的外设时钟命令函数(2)初始化外设定义外设初始化结构变量为外设初始化结构变量成员赋值调用外设初始化函数配置外设(3)控制外设使用驱动库函数编写应用程序总结5:GPIO的使用方法(1)开启GPIOx端口外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx,ENABLE);

(2)定义外设初始化结构变量GPIO_InitTypeDef

GPIO_InitStructure;(3)为外设初始化结构变量成员赋值GPIO_InitStructure.GPIO_Pin=GPIO_Pin_y;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_z;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_??;(4)调用外设初始化函数配置外设GPIO_Init(GPIOx,&GPIO_InitStructure);(5)使用驱动库函数编写应用程序GPIO_ResetBits函数

GPIOx->BRR=GPIO_Pin;控制LED1亮:PB0引脚为低、复位、逻辑0

GPIOB->BRR

=

0x0001;

直接对输出数据寄存器ODR编程控制LED1亮:PB0引脚为低、复位、逻辑0 //复位:GPIO_ResetBits函数的功能

GPIOB->ODR&=~(0x1);控制LED1灭:PB0引脚为高、置位、逻辑1 //置位:GPIO_SetBits函数的功能

GPIOB->ODR|=(0x1);直接对配置寄存器编程GPIO初始化(GPIO_Init函数的功能)就是写入配置寄存器CRL(CRH)

GPIOB->CRL=0x44444443;

//PB0引脚50MHz通用推挽输出模式

//对应4位为0011(0x3)

//其他引脚保持默认的浮空输入模式

//对应4位为0100(0x4)直接对寄存器编程的简单对比直接对寄存器编程,代码执行效率较高需要花费时间学习和查阅产品数据手册过程繁琐易错、代码难以移植利用STM32库开发需要熟悉涉及的宏定义、外设库函数,按照要求填写结构体、提供函数参数等不需要详细学习各种寄存器,能够快速进入开发(用宏定义、枚举标识符等代表的数值写入寄存器)频繁地调用函数影响执行效率嵌入式系统导论主讲教师:第6章CM3异常和STM32中断本章内容提要6.1Cortex-M3的异常6.2STM32的中断应用6.3EXTI应用示例:按键中断数据传送方式程序查询传送中断传送DMA传送6.1Cortex-M3的异常异常(Exception)是导致程序流程改变的事件ARM的中断(Interrupt)是异常的一种类型中断通常由外设或外部输入产生有些情况下也可以由软件激发针对中断的异常处理程序也被称为中断服务程序ISR异常由嵌套向量中断控制器NVIC处理(NestedVectoredInterruptController)CM3异常的来源中断请求IRQ(IntrruptRequest)通常来自片上外设或经I/O端口的外部中断输入非屏蔽中断NMI(Non-MaskableInterrupt)请求可来自看门狗定时器或供电电压下降探测电路系统时钟(滴答)SysTick,可以产生周期性中断请求可用于嵌入式操作系统的时间记录或者作为监督的定时控制处理器本身也是异常事件的来源例如,失效事件、软件异常等复位是一种特殊的异常CM3

常异常编号IRQn优先级名称1--3Reset2-14-2NMI3-13-1HardFault4-120MemManage5-111BusFault6-102UsafeFault7—10---11-53SVCall12-44DebugMonitor13---14-25PendSV15-16SysTick16—2550—2557—255IRQ优先级定义CM3的一个异常是否被处理器接收并处理取决于它的优先级以及处理器当前的优先级有些异常(复位、NMI和HardFalult)具有固定优先级是一个负值,表示其优先级高于其他优先级其他异常的优先级可以编程确定,范围是0~255异常优先级数值越小、优先权越高CM3支持3个固定最高优先级和256级可编程优先级但实际支持的优先级有半导体芯片设计者决定多数只支持8、16、32等种优先级优先级编程由优先级寄存器控制8、16、32、256种优先级依次需3、4、5、8位优先级寄存器组(抢占)优先级和子(响应)优先级3~8位的优先级寄存器又分成两个部分组优先级(GroupPriority)确定是否可以打断正在执行的中断,实现嵌套早期技术手册中,被称为抢占优先级(Pre-emptionPriority)子优先级(Sub-Priority)只用于在相同组优先级,多个子优先级同时出现时 高优先权(低优先级值)的异常首先被处理也有译为响应优先级嵌套向量中断控制器NVICNVIC是处理器的一部分,可以编程处理异常和中断的配置、优先权和中断屏蔽6.2STM32的中断应用STM32具有多达68个中断(不包括16个Cortex-M3中断线)STM32把编号-3~6的中断定义为系统异常编号7开始的是外部中断(所有外设都具有中断请求能力)编号为负的3个中断不能设置优先级其他都可以自行设置不同型号STM32微控制器的向量表略有区别启动文件包含了其支持的所有中断并给出了中断服务函数名STM32

断异常编号IRQn优先级名称1607WWDG1718PVD…………22613EXTI023714EXTI124815EXTI225916EXTI3261017EXTI4271118DMA1_Channel1…………392330EXTI9_5…………564047EXTI15_10…………NVIC库函数函数名函数功能NVIC_InitNVIC初始化NVIC_PriorityGroupConfig配置优先权组NVIC_SetVectorTable设置向量表位置和偏移NVIC_SystemLPConfig为系统进入低功耗模式选择条件SysTick_CLKSourceConfig配置系统时钟SysTick时钟源1.NVIC优先级配置STM32使用4位优先级寄存器、支持16种异常优先级4位分成组(抢占)优先级和子(响应)优先级有5组分配形式(下页表)STM32库中文件misc.c提供了NVIC的配置函数

voidNVIC_PriorityGroupConfig(uint32_t

NVIC_PriorityGroup)参数NVIC_PriorityGroup对应5组分配形式NVIC_PriorityGroup_0~NVIC_PriorityGroup_4使用中断一定要在工程项目中添加misc.c文件STM32的5组优先级配置组号组(抢占)优先级子(响应)优先级0无4位都配置子优先级16种子优先级(0~15)11位配置组优先级2种组优先级(0、1级)3位配置子优先级8种子优先级(0~7)22位配置组优先级4种组优先级(0~3级)2位配置子优先级4种子优先级(0~3)33位配置组优先级8种组优先级(0~7级)1位配置子优先级2种子优先级(0、1)44位都配置组优先级16种组优先级(0~15级)无2.NVIC初始化NVIC初始化函数void

NVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct)NVIC_InitTypeDef结构typedef

struct{uint8_tNVIC_IRQChannel;uint8_tNVIC_IRQChannelPreemptionPriority;uint8_tNVIC_IRQChannelSubPriority;

FunctionalState

NVIC_IRQChannelCmd;}

NVIC_InitTypeDef;STM32的外部中断/事件EXTIEXTI控制器具有19个边沿检测器(中断通道)EXTI0~EXTI15:对应GPIOx_Pin0~GPIOx_Pin15EXTI16:连接PVD(电源电源检测)输出EXTI17:连接RTC(实时时钟)的闹钟事件EXTI18:连接USB唤醒事件(EXTI19:连接以太网唤醒事件,仅互联型产品)用于检测19个输入线,每个都可以单独地被配置为中断或事件也都可以选择上升沿、下降沿或上下沿均触发每个输入线都可以单独进行屏蔽EXTI:ExternalInterrupt/event通用I/O引脚作为外部中断所有I/O端口都可以配置为EXTI外部中断模式用来检测外设中断请求,可以配置为 下降沿触发、上升沿触发或上升下降沿触发所有GPIO引脚都可以作为中断源连接到16个EXTI外部中断线(Line)上PAx~PGx引脚连接到EXTIxEXTI0~EXTI4分别占用一个中断向量EXTI9~EXTI5共用一个中断向量、被称为EXTI9_5EXTI15~EXTI10共用一个中断向量、被称为EXTI15_10EXTI:ExternalInterrupt/eventGPIO的EXTI连接PAx~PGx引脚连接到EXTIx同一个时刻EXTIx只能响应一个端口引脚x的中断事件EXTI寄存器寄存器缩写寄存器英文名称EXTI_IMRInterruptMaskRegisterEXTI_EMREventMaskRegisterEXTI_RTSRRisingTriggerSelectionRegisterEXTI_FTSRFallingTriggerSelectionRegisterEXTI_SWIERSoftwareInterrupt/EventRegisterEXTI_PRPendingrequestRegisterEXTI结构中断(Interrupt)与事件(Event)对于外部触发信号来说,没有区别在微控制器芯片内部,处理不同中断是某个事件发生向处理器发出中断请求,并跳转到中断服务程序中可以被更高优先权的中断屏蔽(禁止)事件是检测到某个事件发生可向其他模块发送触发信号对应模块决定如何响应(触发或不触发中断)事件不会被屏蔽,但可以屏蔽发送触发信号(这是事件屏蔽寄存器的作用)EXTI库函数函数名函数功能EXTI_InitEXTI初始化EXTI_DeInitEXTI解除初始化EXTI_StructInit填充EXTI初始化结构成员EXTI_GetITStatus获取中断状态EXTI_ClearITPendingBit中断挂起位清除EXTI_GetFlagStatus获取标志状态EXTI_ClearFlag挂起标志清除EXTI_GenerateSWIInterrupt产生软件中断外设的中断相关函数函数名函数功能PPP_ITConfig设置外设PPP某个(些)中断请求是允许或禁止PPP_GetITStatus获取外设PPP某个中断状态PPP_ClearITPendingBit清除外设PPP某个挂起的中断标志PPP_GetFlagStatus获取标志状态:检测某个外设标志是否置位PPP_ClearFlag挂起标志清除:清除某个外设的挂起标志6.3EXTI应用示例:按键中断【例6-1】根据按键状态控制LED灯亮灭2个按键KEY有按下来,产生中断请求KEY在目标板上的连接PA0和PC13分别连接2个KEY1和KEY2按钮按下时,GPIO引脚输入低电平(0)否则输入高电平(1)程序的功能是按下某个按钮KEYx对应LEDx亮一段时间,然后熄灭中断初始化配置复位后,所有中断都被禁止,并赋予优先级0使用任何中断,都需要设置中断,具体是:1.NVIC初始化配置配置优先级组为每个中断通道进行NVIC初始化2.外设初始化配置3.外设中断配置启动GPIO的复用功能(AFIO)时钟

为每个中断请求的GPIO引脚指明外部中断EXTI线为每个中断请求引脚进行EXTI初始化NVIC初始化配置首先,选择优先级组号(即0~4共5种形式)NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);其次,配置中断通道:PA0(KEY1)NVIC_InitTypeDefNVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn; //指明IRQ通道(EXTI0_IRQn)NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //指明IRQ通道的组(抢占)优先级(0)NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //指明IRQ通道的子优先级(0)NVIC_InitStructure.NVIC_IRQ

温馨提示

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

评论

0/150

提交评论