嵌入式串口通信原理与程序设计(接收数据处理)
对应发送、接 收数据完成(RI、TI硬件置1)都会触发串口中断,但是无法确定是哪个触发的,所以在串口中断中我们要判断是接收数据产生的中断还是发送数据产生的中断,对于发送数据产生的中断,我们要软件 将TI清0,并将数据就绪标志清0,允许下一字节数据发送,发送数。if(USART1->SR & (1 << 5))//状态寄存器接收到数据检查 RXNE(接收缓冲区非空)标志。//组2,最低优先级。//
STM32的串口通信
串口的最基本设置为波特率设置,即只要配置波特率、数据位长度、奇偶校验位等并开启串口时钟。每个串口有一个自己独立的波特率寄存器USART_BRR
TX/RX波特率=FCLK/(16*USARTDIV)
USARTDIV=DIV_Mantissa+(DIVFraction/16)
void uart_init(u32 pclk2, u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp = (float)(pclk2 * 1000000) / (bound * 16); //得到USARTDIV
mantissa = temp; //得到整数部分
fraction = (temp - mantissa) * 16; //得到小数部分
mantissa <<= 4;
mantissa += fraction;
RCC->APB2ENR |= 1 << 2; //使能PORTA口时钟
RCC->APB2ENR |= 1 << 14; //使能串口时钟
GPIOA->CRH &= 0XFFFFF00F; // 清除PA9(TX)和PA10(RX)的配置位
GPIOA->CRH |= 0X000008B0; //IO状态设置 配置PA9为复用推挽输出,PA10为浮空输入
RCC->APB2RSTR |= 1 << 14; //复位串口1
RCC->APB2RSTR &= ~(1 << 14); //停止复位
//波特率设置
USART1->BRR = mantissa; // 波特率设置
USART1->CR1 |= 0X200C; //1位停止,无校验位.
#ifdef EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1 |= 1 << 8; // 使能PE(奇偶校验错误)中断
USART1->CR1 |= 1 << 5; //使能RXNE(接收缓冲区非空)中断
MY_NVIC_Init(3, 3, USART1_IRQChannel, 2); //组2,最低优先级
#endif
}
void USART1_IRQHandler(void)
{
u8 res;
if(USART1->SR & (1 << 5)) //状态寄存器接收到数据 检查 RXNE(接收缓冲区非空)标志
{
res = USART1->DR; //读取数据寄存器(自动清除 RXNE 标志)
printf( "%c", res ); //返回打印
if(0x0d == res) printf("\n"); //回车的话加换行
if((USART_RX_STA & 0x80) == 0) // 检查是否已完成一帧接收
{
if(USART_RX_STA & 0x40) // 检查是否已收到 0x0D(回车)
{
if(res != 0x0a) // 期望收到 0x0A(换行)
USART_RX_STA = 0; // 未收到换行符,重置状态
else
USART_RX_STA |= 0x80; // 正确收到 0x0A,标记帧完成
}
else // 还未收到 0x0D
{
if(res == 0x0d) // 当前字符是回车符
USART_RX_STA |= 0x40; // 标记已收到 0x0D
else
{
// 存储普通数据到缓冲区
USART_RX_BUF[USART_RX_STA & 0x3F] = res;
USART_RX_STA++; // 数据长度 +1
if(USART_RX_STA > 63) // 缓冲区溢出
USART_RX_STA = 0; // 重置状态
}
}
}

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)