一个菜鸟的STM32寄存器学习笔记5_串口中断收发
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
用串口中断来进行收发可以节约很多查询的时间。在程序中要实现串口中断收发,在串口初始化部分的代码和查询方式的代码比多了一个接收和发送中断使能部分。其他部分还多了中断分组,中断优先级配置和中断服务函数。
配置方法如下:
1.中断优先级分组SCB->AIRCR
2.串口中断总开关使能NVIC->ISER
3.串口中断优先级配置NVIC->IP[37]
4.使能串口1时钟RCC->APB2ENR
5.使能串口1对应的引脚(PA9_RX,PA10_TX) RCC->APB2ENR
6.配置串口1对应的引脚的工作模式GPIOA->CHR
7.复位串口1 RCC->APB2RSTR
8.停止复位串口1 RCC->APB2RSTR
9.配置串口1波特率,USART1->BRR
10.串口功能配置。接收发送中断使能USART1->CR1
11.接收或者发送数据USART1->DR
12.进入中断服务函数处理事情,完成后清理中断标志位
第一步中断优先级分组
这里优先级分组和外部中断时一样的都是组3
SCB->AIRCR&=0x05FAF8FF;
SCB->AIRCR|=0X05FA0400;
第二步串口中断总开关使能
从上图可以看出串口1的中断号是37
中断使能寄存器NVIC->ISER数组中的一位表示一个中断号。所以37是在元素1中
也就是在NVIC->ISER[1]中。ISER[1]表示的范围是32~63所以37位于ISER[1]的位5上
语句就是
NVIC->ISER[1]|=1<<5;//使能37位上的串口中断
第三步给串口1中断分配优先级
这里用到的是NVIC->IP寄存器。这个寄存器有240个元素。每个元素表示一个中断的优先级。这里用到的是串口37号中断就用IP[37].
我给串口中断分配的是抢占1,子优先级1说以IP[37]用二进制表示就是001 1 0000
所以语句是
NVIC->IP[37]=0X30;
第四步串口功能配置
原来串口的初始化(起始位,数据位,校验位,结束位)不变
USART1->CR1|=0X200C; //1位停止,无校验位.
在程序初始化时先使能接收中断就好了,发送中断在需要的时候再使能(建议使用查询方式发送,因为在接受中断中是不会响应发送中断的。)
使能接收中断只要给位5写1就可以了
USART->CR1|=1<<5;
第五步编写串口中断服务函数
在学习外部中断时我们知道中断服务函数是根据函数名来区分的在.s的启动文件中有说明
函数名是USART1_IRQHander的函数就是串口1的中断服务函数。
我们在串口服务函数中要做的事是:判断是接收中断还是发送中断(如果发送中断使能的话)保存接收的数据,清除中断标志。
判断中断类型我们使用串口状态寄存器SR
位5是接收到数据的标志,位6是发送完成的标志
接收中断我们就判断位5是否是1就好了
if(USART1->SR&(1<<5))//接收到数据
如果接收到了数据,我们就要把接收到的数据保存起来(读取USART1->DR中的值)或者根据接收到的数据进行相应的动作。这里我就是判断接收的内容然后让LED灯点亮。
if(USART1->DR=='M')
GPIOC->BSRR=0x000e0000;//123脚置1
发送就和原来的查询方式一样:给USART1->DR中写入字节,等待发送完成标志。
至此串口中断就结束了下面是我通过串口接收字符然后控制LED灯关灭的程序。发送’K’灯亮,发送’G’灯灭。
#include "stm32f10x.h"
void LED_Init()
{
RCC->APB2ENR|=1<<4;//IOPC设为1复位(GPIOA是2,B是3,C是4以此类推)
GPIOC->CRL&=0XFFFF000F;//1,2,3脚先清理
GPIOC->CRL|=0X00003330;//设置mode1,2,3=11,cnf1,2,3=00,通用推完输出50mhz (每4位表示一个引脚配置CRL的32位标识0~7脚的配置CRH表示8~15脚的配置)GPIOC->BSRR=0x0000000E;//123脚置1
}
void NVIC_Init()
{
SCB->AIRCR&=0x05FAF8FF;
SCB->AIRCR|=0X05FA0400;
NVIC->ISER[1]|=1<<5;
NVIC->IP[37]=0X30;
}
void USART1_Init()
{
RCC->APB2ENR|=0X4000;
RCC->APB2ENR|=0X0004;
GPIOA->CRH&=0XFFFFF00F;
GPIOA->CRH|=0X000004B0;
RCC->APB2RSTR|=0x4000; //复位串口1
RCC->APB2RSTR&=0xbfff;//停止复位
USART1->BRR=0x1D4C; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
USART1->CR1|=0X0020; //接收中断初始化
}
int main()
{
u32 x=65533600;
LED_Init();
NVIC_Init();
USART1_Init();
while(1)
{
while(x) x--;
x=6553360;
USART1->DR='C';
while((USART1->SR&1<<6)!=1<<6);
}
}
void USART1_IRQHandler(void)
{
if(USART1->SR&(1<<5))//接收到数据
{
if(USART1->DR=='K')
GPIOC->BSRR=0x000E0000;//123脚置0 else if(USART1->DR=='G')
GPIOC->BSRR=0x0000000E;//123脚置1 }
}