标题:
STM32f407串口轮询和中断 源程序详细注释
[打印本页]
作者:
hcf007
时间:
2021-2-5 09:58
标题:
STM32f407串口轮询和中断 源程序详细注释
这是刚接触串口一些心得体会:轮询方式将接收函数放在while循环中,每次循环cpu主动询问并判断是否有数据接收,接收占用CPU资源较多,所以一般使用串口中断方式接收数据,串口接收到数据后触发中断,cpu被打断,中断当前任务去处理接收的数据。个人理解轮询和中断最大区别就是cpu主动和被动请求,如果大家还有其他理解,欢迎提出
单片机源程序如下:
#include "led.h"
#include "key.h"
#include "usart.h"
#include "systick.h"
#include "beep.h"
int main(void)
{
u8 buf[50];
LED_Init(); //LED初始化
KEY_Init(); //按键初始化
BEEP_Init(); //蜂鸣器初始化
USART1_Init(9600);//串口1初始化
while(1)
{
USART1_ReceString(buf);
printf("%s\r\n",buf);
if(strcmp((char*)buf,"开灯")==0)
{
LED1_ON;
LED2_ON;
LED3_ON;
LED4_ON;
printf("主人,已为您开灯\r\n");
}
else if (strcmp((char*)buf,"关灯")==0)
{
LED1_OFF;
LED2_OFF;
LED3_OFF;
LED4_OFF;
printf("主人,已为您灯关\r\n");
}
else if (strcmp((char*)buf,"启动蜂鸣器")==0)
{
BEEP_ON;
printf("回禀大人,蜂鸣器已响\r\n");
}
else if (strcmp((char*)buf,"关闭蜂鸣器")==0)
{
BEEP_OFF;
printf("回禀大人,蜂鸣器已关\r\n");
}
}
}
复制代码
#include "usart.h"
//输出重定向 (重新定义输出方向)
int fputc(int ch,FILE *f)
{
while(!(USART1->SR&(1<<6)));//等待传送已完成
USART1->DR = ch;
return ch;
}
/**********************************************************************
*函数名:u1_printf
*功 能:自定义的打印函数
*参 数:格式参数
*返 回:无
*备 注:等效于库 函数printf
**********************************************************************/
void u1_printf(char* fmt,...)
{
unsigned int i,length;
char TxBuff[100];
va_list ap;
va_start(ap,fmt);
vsprintf(TxBuff,fmt,ap);
va_end(ap);
length=strlen((const char*)TxBuff);
for(i = 0;i < length;i ++)
{
while(!(USART1->SR&(1<<6)));
USART1->DR = TxBuff[i];
}
}
/**********************************************************************
*函数名:USART1_Init
*功 能:串口1初始化
*参 数:波特率
*返 回:无
*备 注:
1.时钟使能 GPIOA 和串口1
2.串口1引脚 TXD(PA9) RXD(PA10)配置为复用模式
**********************************************************************/
void USART1_Init(u32 bound)
{
float usartdiv;
u16 DIV_Mantissa;//整数部分
u16 DIV_Fraction;//小数部分
RCC->APB2ENR |= 1<<4;//串口1时钟使能
RCC->AHB1ENR |= 1<<0;//PA端口使能
//PA9配置复用模式,且映射到USART1
GPIOA->MODER &=~(3<<9*2); //清零
GPIOA->MODER |=2<<9*2; //复用模式
GPIOA->OTYPER &=~(1<<9); //推挽
GPIOA->OSPEEDR &=~(3<<2*9); //清零
GPIOA->OSPEEDR &=1<<2*9; //速度25MHZ
GPIOA->AFR[1] &=~(0xf<<4);//4~7位清理
GPIOA->AFR[1] |=7<<4; //映射(选择)
//PA10配置复用,且映射到到USART1
GPIOA->MODER |=2<<10*2; //复用功能
GPIOA->AFR[1] &=~(0xf<<8); //位清理
GPIOA->AFR[1] |=7<<8; //PA10映射到USART1
//CPU帮我们算波特率
usartdiv=84*1000000/16.0/bound;
DIV_Mantissa=usartdiv;
DIV_Fraction=(usartdiv-DIV_Mantissa)*16;
USART1->BRR=DIV_Mantissa<<4|DIV_Fraction;
USART1->CR1 |=1<<13|1<<3|1<<2;//串口使能,发送使能,接收使能
printf("串口1初始化\r\n");
}
/**********************************************************************
*函数名:USART1_ReceByte
*功 能:串口1接收单个字节
*参 数:无
*返 回:字节数据
*备 注:
**********************************************************************/
u8 USART1_ReceByte(void)
{
while(!(USART1->SR&(1<<5)));//等待接收完成
return USART1->DR;//读取数据
}
/**********************************************************************
*函数名:USART1_ReceByte
*功 能:串口1接收单个字节
*参 数:无
*返 回:字节数据
*备 注:
**********************************************************************/
void USART1_ReceString(u8 *buf)
{
u8 ch;
while(1)
{
ch=USART1_ReceByte();
if(ch=='\r'||ch=='\n')
{
break;//接收
}
*buf++=ch;
}
*buf=0;//构成字符串
}
复制代码
全部程序51hei下载地址:
USART串口中断.7z
(292.74 KB, 下载次数: 20)
2021-2-5 15:20 上传
点击文件名下载附件
下载积分: 黑币 -5
USART(轮询法接收数据).7z
(299.78 KB, 下载次数: 13)
2021-2-5 15:20 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1