收藏 分享(赏)

stm32 串口中断总结.doc

上传人:精品资料 文档编号:10702181 上传时间:2019-12-29 格式:DOC 页数:15 大小:123.05KB
下载 相关 举报
stm32 串口中断总结.doc_第1页
第1页 / 共15页
stm32 串口中断总结.doc_第2页
第2页 / 共15页
stm32 串口中断总结.doc_第3页
第3页 / 共15页
stm32 串口中断总结.doc_第4页
第4页 / 共15页
stm32 串口中断总结.doc_第5页
第5页 / 共15页
点击查看更多>>
资源描述

1、本文以 USART1 为例,叙述串口中断的编程过程。1、先来讲述一下在应用串口中断时涉及到的一些库文件。首先对于 STM32 外设库文件的应用编程,misc.c 和 stm32f10x_rcc.c 是肯定要添加到。接下来就是我们要用到的相关外设了。毫无疑问,串口文件 stm32f10x_usart.c 是必须的。串口通信是对通用 GPIO 端口引脚的功能复用,所以还需要 stm32f10x_gpio.c 文件。另外,因为有中断的产生,所以中断文件 stm32f10x_it.c 也是必要的,当然这个文件一般和main.c 放在一个文件夹下(一般习惯为 User 文件夹),因为我们的中断响应函数是

2、要在里面自己编写的。当然还有其他的基本必须文件如系统配置文件等在这地方就不说了,这个是创建一个工程应该知道的。2、初始化对于串口通信的初始化,不仅仅只是对串口的初始化(这个地方是比较烦人的,不像别的芯片那样简洁明了)。 首先时钟使能配置。 STM32 内部的时钟有很多,感兴趣的自己看看参考手册。此处以 USART1 为例说明。有 USART1 时钟、GPIOA 时钟、GPIO 复用(AFIO)时钟。由于此处 USART1 和 GPIOA、AFIO 均在 APB2 上,所以可以一次配置完成。如下:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_AP

3、B2Periph_AFIO|RCC_APB2Periph_USART1 ,ENABLE); 其次中断配置。主要有优先级组设定、USART1 中断使能、该中断的优先级,中断初始化。程序如下:void NVIC_Configuration(void)NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);/选择分组方式 0/* 使能 USART1 中断 */NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure

4、.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init( 然后 GPIO 复用功能配置。一般情况下我们使用原始的外设和 GPIO 端口引脚的映射关系,如果要改变其映射的话,请另外查看参考手册上关于 GPIO 重映射部分。对于 GPIO 的复用,其引脚的输入与输出模式都有要求,在参考手册上有详细说明。void GPIO_Configuration(void)GPIO_InitTypeDef GPIO_InitStructure;/* 配置 USART1 Rx 作为浮空输入 *

5、/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(USARTy_GPIO, /* 配置 USART1 Tx 作为推挽输出 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(USARTy_GP

6、IO, 串口初始化配置。主要有串口基本参数配置( 如波特率、数据位、工作方式等),串口中断使能,串口使能。(1) 基本参数配置USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600;/波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;/数据长度USART_InitStructure.USART_StopBits = USART_StopBits_1;/停止位USART_InitStructure.USART_Parit

7、y = USART_Parity_No;/校验USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; /硬件流控制无USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /发送与接受两种方式USART_Init(USART1, /用配置的参数惊喜串口初始化(2) 串口中断使能USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);/使能接受中断,在接受移位 寄存器中有数据是产生USART

8、_ITConfig(USARTy, USART_IT_TXE, ENABLE);/使能发送中断,在发送完数据 后产生。一般情况下,如果与 PC 通信的话,我们只用接受中断即可。(3) 串口使能USART_Cmd(USART1, ENABLE); /USART1 使能好了,经过以上不走之后呢,我们就可以进行数据的收发了。3、发送数据使用函数 USART_SendData(USART1, char data),一次只能发送一个字符。当然我们可以用如下函数发送字符串。void USART1_Puts(char * str) while(*str) USART_SendData(USART1, *st

9、r+); /发送一个字符while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) = RESET); /等待发送完毕 当然我们也可以循环发送字符串数组for(i = 0; TxBuf1 != 0; i+) / TxBuf1 为定义好的字符串数组USART_SendData(USART2 , TxBuf1);while(USART_GetFlagStatus(USART2, USART_FLAG_TC)=RESET);4、接收数据由于我们使用的是接受中断,所以当有数据需要接收时,会执相应的中断函数。此处我们 USART1 的中断函数在 stm32f10x

10、_it.c 文件中。找到函数 void USART1_IRQHandler(void),如果没有的话就自己加上吧,别忘了头文件中需要声明一下。当然你也可以在其他文件中写下该中断函数。当产生中断进入该函数之后,我们就可以进行自己的操作了。void USARTy_IRQHandler(void)if(USART_GetITStatus(USARTy, USART_IT_RXNE) != RESET)/如果寄存器中有数据/* Read one byte from the receive data register */RxBuffer1RxCounter1+ = USART_ReceiveData(

11、USART1);/*if(USART_GetITStatus(USARTy, USART_IT_TXE) != RESET) USART_SendData(USARTy, TxBuffer1TxCounter1+); /这个地方那个之所以把这个写出来主要是想说发送中断和接受中断其实是共用一个/中断函数的,到底是那个中断发生了呢,这就需要我们读取中断状态标志来识别了。*/别忘了在接受完数据进行别的操作之前为了防止数据被覆盖最好先禁止一下接受中断/* 禁止 USART1 接收中断 */USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);/* 禁止 USAR

12、T1 发送中断 */USART_ITConfig(USART1, USART_IT_TXE, DISABLE);5、 main 函数int main(void) /这个地方和特别,我们知道一般 main 函数是没有返回值的,但在STM32 /的编程中其返回类型为 int。RCC_Configuration();NVIC_Configuration();GPIO_Configuration();USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;U

13、SART_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_ITConfig(USART1, USART_IT_RXNE

14、, ENABLE);/USART_ITConfig(USART1, USART_IT_TXE, ENABLE);USART_Cmd(USART1, ENABLE);while (1)/等待中断当然你也可以在 main()中添加一些发送指令之类的东西。以上内容为个人总结,转载请注明出处。若有错误,本人概不负任何责任。STM32 外部中断配NVIC_Configuration 函数实现配置嵌套向量中断中断优先级并使能中断。其中的NVIC_PriorityGroupConfig 函数配置中断优先级的组织方式,STM32 的嵌套向量中断控制器可以配置 16 个可编程的优先等级 ,使用了 4 位表示中断

15、优先级(2 的 4 此方就是 16),16 个可编程的优先等级又可以分为主优先级和次优先级,例如参数 NVIC_PriorityGroup_1 表示 1bit 主优先级(pre-emption priority)3 bits 次优先级(subpriority )。一、配置中断1、 分配中断向量表:/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);2、 设置中断优先级:NVIC_PriorityGroupConfig(NVIC_PriorityGroup

16、_0); /设置中断优先级3、 初始化外部中断:/*允许 EXTI4 中断 */NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel; /中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= PreemptionPriorityValue; /占先优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /响应(次级)优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /通道中断使

17、能NVIC_Init( /初始化中断注意:如果我们配置的外部针脚为 PA4,或 PB4,或 PC4,PD4 等,那么采用的外部中断也必须是 EXTI4,同样,如果外部中断针脚是 PA1,PB1,PC1,PD1 那么中断就要用 EXTI1,其他类推。二、配置 GPIO 针脚作为外部中断的触发事件1、 选择 IO 针脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;注意,如果的针脚是端口的 4 号针脚,配置的中断一定是 EXTI42、 配置针脚为输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;3、 初始

18、化针脚GPIO_Init(GPIOD,3 配置 EXTI 线,使中断线和 IO 针脚线连接上1、 将 EXTI 线连接到 IO 端口上将 EXTI 线 4 连接到端口 GPIOD 的第 4 个针脚上GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource4);注意:如果配置的针脚是 4 号,那么参数必须是 GPIO_PinSource4如果配置的针脚是 3 号,那么参数必须是 GPIO_PinSource32、配置中断边沿/*配置 EXTI 线 4 上出现下降沿,则产生中断*/EXTI_InitStructure.EXTI_Line = E

19、XTI_Line4;注意:如果配置的 4 号针脚,那么 EXTI_Line4 是必须的EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; /下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE; /中断线使能EXTI_Init( /初始化中断EXTI_GenerateSWInterrupt(EXTI_Line4); /EXTI_Line4 中断允许到此中断配置完成,可以写中断处理函数。举例:配置函

20、数/* 函数名 NVIC_Configration* 描述 配置各个中断寄存器*/void NVIC_Configration(void)NVIC_InitTypeDef NVIC_InitStructure;/#ifdef VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);/#else /* VECT_TAB_FLASH */* Set the Vector Table base location at 0x08000000

21、*/NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); /#endif NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /设置中断优先级/*允许 EXTI4 中断 */NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;NVIC_InitStructure.NVIC_IRQChannelSubPr

22、iority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init( /*允许 EXTI9 中断*/NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_I

23、nit( /*配置 SysTick 处理优先级:优先级以及子优先级*/* 函数名 GPIO_Configuration(void)* 描述 配置 TIM2 针脚*/void GPIO_Configuration(void)/* GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed

24、= GPIO_Speed_50MHz;GPIO_Init(GPIOA, */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC,/*配置 GPIOD 的第一个管角为浮动输入 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_

25、IN_FLOATING;GPIO_Init(GPIOD,/*配置 GPIOB 的第 9 个管脚为浮动输入*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB,/* 函数 SysTick_Configuration* 描述 设置 SysTick*/void SysTick_Configuration(void)/*配置 HCLK 时钟做为 SysTick 时钟源*/SysTick_CLKSourceConfig(SysTick_

26、CLKSource_HCLK_Div8); /系统时钟 8分频 72MHzNVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 8,2);/*SysTick Interrupt each 1000Hz with HCLK equal to 72MHz*/SysTick_SetReload(9000);/中断周期 1ms/*Enable the SysTick Interrupt */SysTick_ITConfig(ENABLE);/打开中断 SysTick_CounterCmd(SysTick_Counter_Enable);SysT

27、ick_CounterCmd(SysTick_Counter_Clear); /* 函数名 EXTI_Configuration* 描述 配置 EXTI 线*/void EXTI_Configuration(void)/*将 EXTI 线 4 连接到 PD4*/GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource4);/*配置 EXTI 线 4 上出现下降沿,则产生中断*/EXTI_InitStructure.EXTI_Line = EXTI_Line4;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_

28、Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(EXTI_GenerateSWInterrupt(EXTI_Line4);/*将 EXTI 线 9 连接到 PB9 上*/GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource9);/*将 EXTI 线 9 上出现下降沿产生中断*/EXTI_InitStructure.EXTI_Line = EXTI_Line

29、9;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(EXTI_GenerateSWInterrupt(EXTI_Line9); 中断函数:void EXTI4_IRQHandler(void)if(EXTI_GetITStatus(EXTI_Line4)!= RESET)if(Ledflag = 0)Ledflag = 1;GPIO

30、C-ODR |= 0X00000080;else Ledflag = 0; GPIOC-ODR EXTI_ClearITPendingBit(EXTI_Line4); /清除 EXTI0 线路挂起位注: 时钟设置的时候最好加上这句:RCCRCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); / 使能AFIO 时钟=/* *例程名称:外部中断实验实验硬件:DP-miniSTM32硬件连接:指示灯连接 PA1按钮连接 PA3功能描述:本例程实现外部中断的输入试验,按下按钮,指示灯闪烁一下 */#include / STM32F10x Librar

31、y Definitions#include “STM32_Init.h“ / STM32 Initialization/* 名 称:Delay()*/void Delay(vu16 cnt) uint16 i,j;for (i=0;icnt;i+) for (j=0;j1000;j+) /* 名 称:RCC_Configuration()*/void RCC_Configuration(void)ErrorStatus HSEStartUpStatus;/使能外部晶振RCC_HSEConfig(RCC_HSE_ON);/等待外部晶振稳定HSEStartUpStatus = RCC_WaitFo

32、rHSEStartUp();/如果外部晶振启动成功,则进行下一步操作if(HSEStartUpStatus=SUCCESS)/设置 HCLK(AHB 时钟) =SYSCLKRCC_HCLKConfig(RCC_SYSCLK_Div1);/PCLK1(APB1) = HCLK/2RCC_PCLK1Config(RCC_HCLK_Div2);/PCLK2(APB2) = HCLKRCC_PCLK2Config(RCC_HCLK_Div1);RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_4);/启动 PLLRCC_PLLCmd(ENABLE);/等

33、待 PLL 稳定while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) = RESET);/系统时钟 SYSCLK 来自 PLL 输出RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/切换时钟后等待系统时钟稳定while(RCC_GetSYSCLKSource()!=0x08);/* RCC system reset(for debug purpose) */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO , ENABLE); /给 GPIOA 和重映射

34、提供时钟,注意:一定要设置RCC_APB2Periph_AFIO/* 名 称:GPIO_Configuration()*/void GPIO_Configuration(void)GPIO_InitTypeDef GPIO_InitStructure;/*设置 PA3 为输入*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,/

35、*设置 PA1 为输出*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, /* 名 称:EXTI_Configuration()*/void EXTI_Configuration(void)EXTI_InitTypeDef EXTI_InitStructure;/* Configure EXTI Line3 to generate an

36、 interrupt on falling edge */EXTI_InitStructure.EXTI_Line = EXTI_Line3; /外部中断通道 3EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; /下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE; /使能EXTI_Init(GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinS

37、ource3); /将PA3 连接到外部中断通道 3/* 名 称:NVIC_Configuration()*/void NVIC_Configuration(void)NVIC_InitTypeDef NVIC_InitStructure;#ifdef VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT_TAB_FLASH */* Set the Vector Table base location a

38、t 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endifNVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /抢占式优先级别设置为无抢占优先级NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel; /指定中断源NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /指定响应优先级别1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE

39、; /使能外部中断通道 3NVIC_Init(int main (void)RCC_Configuration(); /配置时钟 GPIO_Configuration(); /配置 IO 口NVIC_Configuration(); /中断配置EXTI_Configuration(); /外部中断配置while(1)/* 说明:将 LED 灯的连接到 PA1*/void EXTI3_IRQHandler (void)if(EXTI_GetITStatus(EXTI_Line3) != RESET)/添加中断处理程序GPIO_WriteBit(GPIOA, GPIO_Pin_1,(BitActi

40、on)0);Delay(1000);GPIO_WriteBit(GPIOA, GPIO_Pin_1,(BitAction)1);Delay(1000);EXTI_ClearFlag(EXTI_Line3); /清除中断标志(必须)EXTI_ClearITPendingBit(EXTI_Line3);/ 以上两条语句作用相同=在使用 EXTI 的时候,因为没有开启时钟没有开启 RCC_APB2Periph_AFIO 时钟,让我调试吃了不少苦头,看来还要好好看看 stm32 的时钟啊现在给出我的 exti8 的配置首先一定要记得配置RCC_APB2PeriphClockCmd(RCC_APB2Pe

41、riph_AFIO, ENABLE); / 使能 AFIO 时钟/GPIOB8 作为中断脚,配置为浮空输入void GPIO_Configuration(void)GPIO_InitTypeDef GPIO_InitStructure; /* Configure PB8 as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;G

42、PIO_Init(GPIOB, 继续配置 NVICvoid NVIC_Configuration(void)NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_I

43、nit( /* Configure the NVIC Preemption Priority Bits*/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);/* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);然后配置 EXTI ,把 PB8 连接到 EXTIvoid EXTI_Configuration(void)EXTI_InitTypeDef EXTI_InitStructure;/*connect PB8 to EXTI*/GPIO_EXTILineConf

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报