一、串口基础
1.常用的串口相关寄存器
USART_SR状态寄存器
USART_DR数据寄存器
USART_BRR波特率寄存器
2.串口操作相关库函数(省略入口参数)
void USART_Init(); //串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能
void USART_Cmd();//使能串口
void USART_ITConfig();//使能相关中断
void USART_SendData();//发送数据到串口,
DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
FlagStatus USART_GetFlagStatus();//获取状态标志位
void USART_ClearFlag();//清除状态标志位
ITStatus USART_GetITStatus();//获取中断状态标志位
void USART_ClearITPendingBit();//清除中断状态标志位
3.状态寄存器
第10-31位保留,硬件强制为0
第5位:RXNE(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候我们要做的就是尽快去读取 USART_DR,通过读 USART_DR 可以将该位清零,也可以向该位写 0,直接清除。
第6位:TC(发送完成),当该位被置位的时候,表示 USART_DR 内的数据已经被发送完成了。如果设置了这个位的中断,则会产生中断。该位也有两种清零方式:1)读 USART_SR,写USART_DR。2)直接向该位写 0。
读取串口状态的函数是:FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
例如:
判断读寄存器是否非空(RXNE),操作库函数的方法是:USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
4.数据寄存器
5.串口配置的一般步骤
①串口时钟使能:RCC_APBxPeriphClockCmd();
GPIO时钟使能:RCC_AHB1PeriphClockCmd();
② 引脚复用映射: GPIO_PinAFConfig();
③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF
④串口参数初始化:USART_Init();
⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤) NVIC_Init(); USART_ITConfig();
⑥使能串口:USART_Cmd(); ⑦编写中断处理函数:USARTx_IRQHandler();
⑧串口数据收发:
void USART_SendData();//发送数据到串口,DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
⑨串口传输状态获取: FlagStatus USART_GetFlagStatus(); void USART_ClearITPendingBit();
二、实例编写
1.宏观变量定义
#define USART_REC_LEN 200 //定义最大接收字节数 200
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
u16 USART_RX_STA; //接收状态标记
在这里定义了16位的USART_RX_STA,其中0-13位用于接收数据,第14位用于进行判断0x0d标志,若接收到了置1,反之置0,第15位用于判断接收完成标志,即第14位确定收到0x0d标志后,再进行判断,若收到了0x0a标志,则将该位置为1
2.main函数编写
int main(void)
{
u8 t;
u8 len;
u16 times=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//将中断优先级分组2,2位响应,2位抢断
delay_init(168); //延时初始化
uart_init(115200); //波特率两边要一致,这里设置为115200,若不一致则会产生乱码
LED_Init(); //初始化LED
while(1)
{
//STA为16位,与0x8000与,即判断接收到的数据第15位是否为1,即是否接收到完成
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//接收到的数据长度保存到len中
printf("rn您发送的消息为:rn");
for(t=0;t //将BUF中保存的数据发送到串口1 USART_SendData(USART1, USART_RX_BUF[t]); //等待发送结束 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); } printf("rnrn"); USART_RX_STA=0; //STA清0,以便于下次接收 } else //没有接收到完整结束标志或只接收到一个,跳入else,循环打印提示信息 { times++; if(times%200==0) printf("输入数据,以回车键结束rn"); if(times%30==0) LED0=!LED0;//LED闪烁,系统正在运行 delay_ms(10); } } } 乱码示例:
上一篇:STM32F407-用TB6600驱动器驱动57步进电机
下一篇:STM32F407-串口通信基本原理
推荐阅读最新更新时间:2024-11-07 15:05
设计资源 培训 开发板 精华推荐
- LT1021CCH-5 电压基准作为超线性铂金温度传感器的典型应用
- LTC2946MPMS-1 6V 至 300V 高端电源、电荷和能量监视器的典型应用
- LT1764EQ-3.3 SCR 预稳压器的典型应用可提供跨线路变化的效率
- LT1171HVCQ、5V/2.5A 高效 5V 降压转换器的典型应用
- AD620_AD705放大电路
- 基于 VNI2140J 的高端驱动器
- 简单的电动螺丝刀V1.01
- EVAL-ADM1067TQEB,评估 ADM1067ASU 电压监控器排序器的评估板
- ENC28J60,以太网 PICtail Plus 子板
- 使用 Analog Devices 的 LT1579CS 的参考设计