历史上的今天
今天是:2025年01月29日(星期三)
2019年01月29日 | STM32基础设计(3)---中断串口通信
2019-01-29 来源:eefocus
本文介绍,通过中断方式运用STM32串口USART1。
首先,总结全文,设计步骤主要如下:
1,初始化GPIO
2,初始化USART1
3,初始化NVIC(嵌套向量中断控制器)
4,编写中断服务函数
5,编写主函数
详细步骤如下:
1,初始化GPIO
void IO_Init()
{
GPIO_InitTypeDef Uart_A;
GPIO_InitTypeDef led;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);
led.GPIO_Pin = GPIO_Pin_13;//博主开发板上的LED灯接的GPIOC的13引脚
led.GPIO_Mode = GPIO_Mode_Out_PP;
led.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&led);
Uart_A.GPIO_Pin = GPIO_Pin_9;
Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&Uart_A);
Uart_A.GPIO_Pin = GPIO_Pin_10;
Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&Uart_A);
}
以上代码不在详细介绍,前参看STM32基础设计(1)---点亮LED灯、SEM32基础设计(2)---查询串口通信
2,初始化USART1
void Usart1_Init()
{
USART_InitTypeDef Uart;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
Uart.USART_BaudRate = 115200;
Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
Uart.USART_Parity = USART_Parity_No;
Uart.USART_StopBits = USART_StopBits_1;
Uart.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&Uart);
USART_Cmd(USART1,ENABLE);
USART_ClearFlag(USART1,USART_FLAG_TC);
}
以上代码不在详细介绍,具体请参看STM32基础设计(2)---查询串口通信
3,初始化NVIC
首先,让我们来了解库函数中的NVIC结构体:
typedef struct
{//指明那个中断通道
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
This parameter can be a value of @ref IRQn_Type
(For the complete STM32 Devices IRQ Channels list, please
refer to stm32f10x.h file) */
//抢占优先级
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
specified in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
//子优先级
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
//中断通道使能
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
will be enabled or disabled.
This parameter can be set either to ENABLE or DISABLE */
} NVIC_InitTypeDef;
了解了这个结构体后,就可以在初始化函数中定义这个变量了
NVIC_InitTypeDef nvic;
另外在NVIC初始化中还设置优先级分组(哪怕只有一个中断也要分组,这是规定)。具体使用这个库函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
关于优先级分组此处不再赘述,请大家参考这位博主的博客:
http://blog.csdn.net/DLUTXIE/article/details/7059184?locationNum=4&fps=1
接下来,设置结构体中变量的值:
nvic.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
nvic.NVIC_IRQChannelSubPriority = 0;//子优先级
nvic.NVIC_IRQChannel = USART1_IRQn;//中断通道
nvic.NVIC_IRQChannelCmd = ENABLE;//通道使能
NVIC_Init(&nvic);//NVIC寄存器初始化
4,编写中断服务函数
先贴代码,在解释
void USART1_IRQHandler(void)//注意,这个函数名必须这样写,否则进不了USART1中断。详见库函数中的 IRQn_Type 结构体
{
char temp= '0';
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)//判断是否接收到数据
{
temp = USART1->DR;//如果接收到数据,就将其读出,这样才可将RXNE寄存器清除
if(temp == 'G')//如果接收到G 则关灯
{
GPIOC->BRR = GPIO_Pin_13;
}else if(temp == 'K')//开灯
{
GPIOC->BSRR = GPIO_Pin_13;
}
}
if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')//如果发送寄存器为空,即可以发送数据
{
USART1->DR = temp;将接收到的数据再发送回去
while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));等待数据发送完毕
}
}
5,编写主函数
老规矩,先贴代码再解释:
int main()
{
IO_Init();
Usart1_Init();
Nvic_Init();
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//这里是打开串口的接收中断,以便在USART1收到数据时,进入中断函数。这里特别提一下,现在不用打开发送中断,只有在准备发送数据时才应打开,否则会直接进入中断函数。
GPIOC->BSRR = GPIO_Pin_13;
while(1){}
}
额。。。突然发现没什么好解释的。
中断串口通信介绍到此完毕。
本文完整代码如下:
#include
#define uint unsigned int
#define uchar unsigned char
void delay(uint n)
{
int i,j;
for(i=0;i for(j=0;j<8500;j++); } void IO_Init() { GPIO_InitTypeDef Uart_A; GPIO_InitTypeDef led; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE); led.GPIO_Pin = GPIO_Pin_13; led.GPIO_Mode = GPIO_Mode_Out_PP; led.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC,&led); Uart_A.GPIO_Pin = GPIO_Pin_9; Uart_A.GPIO_Speed = GPIO_Speed_50MHz; Uart_A.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&Uart_A); Uart_A.GPIO_Pin = GPIO_Pin_10; Uart_A.GPIO_Speed = GPIO_Speed_50MHz; Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //page 110 GPIO_Init(GPIOA,&Uart_A); } void Usart1_Init() { USART_InitTypeDef Uart; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); Uart.USART_BaudRate = 115200; Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None; Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; Uart.USART_Parity = USART_Parity_No; Uart.USART_StopBits = USART_StopBits_1; Uart.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&Uart); USART_Cmd(USART1,ENABLE); USART_ClearFlag(USART1,USART_FLAG_TC); //page 540 } void Nvic_Init() { NVIC_InitTypeDef nvic; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); nvic.NVIC_IRQChannelPreemptionPriority = 1; nvic.NVIC_IRQChannelSubPriority = 0; nvic.NVIC_IRQChannel = USART1_IRQn; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); } int main() { IO_Init(); Usart1_Init(); Nvic_Init(); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); GPIOC->BSRR = GPIO_Pin_13; while(1){} } void USART1_IRQHandler(void) { char temp= '0'; if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET) { temp = USART1->DR; if(temp == 'G') { GPIOC->BRR = GPIO_Pin_13; }else if(temp == 'K') { GPIOC->BSRR = GPIO_Pin_13; } } if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0') { USART1->DR = temp; while(!USART_GetFlagStatus(USART1,USART_FLAG_TC)); } }
史海拾趣
|
继成功推出一系列Green model AC-DC PWM电源控制IC后,昂宝电子目前又推出一系列CCFL控制器IC,可广泛用于LCD监视器、LCD-TV、笔记本电脑以及工业设备、汽车、手持设备中的液晶显示器。 目前昂宝电子所推出CCFL控制器IC产品包括:OB3316/OB3316 ...… 查看全部问答> |
|
本文介绍了uC/GUI 的组织结构, PROTEUS 仿真环境, 以及在PROTEUS 仿真环境下实现uC/GUI 移植到MCS51 系列单片机P89C51RD2 的过程; 并且对移植过程中涉及到的修正C51 调用树和代码优化等问题进行了简明阐述。… 查看全部问答> |
|
一个LED的N种玩法(五)----WatchDog Timer 一个LED的N种玩法(五)--WatchDog Timer Author: chenzhufly Email: chenzhufly@126.com 2010-05-02 一.WatchDog Timer 概述 看门狗的目的是当进入错误状态一定时间后复位微控制器。当看门狗使能时,如果用户没有在一定时间内喂狗(看门狗定时 ...… 查看全部问答> |
|
是这样的,写了verilog的一个小程序,编译成功了,然后创建bdf文件以后,再编译,就出错。 报错是: Error: Can\'t compile duplicate declarations of entity \"sig\" into library \"work\" Error: Instance could be entity \" ...… 查看全部问答> |
|
eboot显示一个 logo, 但进去系统的中间黑屏,我想继续在 oal中显示 logo, 去掉lcd初始化函数调用, 可看 OEMInit 函数,没见 初始化LCD部分代码, OEMInit 上下文周围也没找到 初始LCD有关的函数. 麻烦给个提示,谢谢 平台是 PXA270+WINCE6.0… 查看全部问答> |
|
我现在正在弄EBOOT启动(用网络下载NK.BIN), 有几个问题想请教一下,希望各位帮帮忙,多谢 1.PB中本来有提供eboot.bin,我需要再重新编译吗? 2.Target ->ConnectivityOptions里面应该怎么设? 3.除了这两个地方,还有哪里需要注意的. 感激!(我没分了 ...… 查看全部问答> |
|
请教台达VFD-P系列11KW的\"CFF\"故障 一台达VFD-P系列11KW变频器,驱动一惯量较大的负载(外接有BRAKE单元),以前正常,现在出现\"CFF\"故障. \"CFF\"的意义是:“变频器有异常输出现象.输出接地(接地电流大于额定电流的50%以上时),功率模组 ...… 查看全部问答> |
|
为什么STR710的PLL1有输入限制?如果超过了有什么影响吗? 我的有源晶振是16MHz的,2分频后,输入PLL1,然后倍频16倍,再2分频,输出64MHz给MCLK,相关实验都做过了,没有什 ...… 查看全部问答> |




