1、传输速率
比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的比特率为:
10位×240个/秒 = 2400 bps
波特率表示每秒钟调制信号变化的次数, 单位:波特(Baud).
波特率和比特率不总是相同的,对于将数字信号1或0直接用两种不同 电压表示的所谓基带传输,比特率和波特率是相同的。所以,我们也经常用波特率表示数据的传输速率。

STM32的串口通信

 

 串口的最基本设置为波特率设置,即只要配置波特率、数据位长度、奇偶校验位等并开启串口时钟。每个串口有一个自己独立的波特率寄存器USART_BRR

TX/RX波特率=FCLK/(16*USARTDIV)

USARTDIV=DIV_Mantissa+(DIVFraction/16)


USB转串口模块,对应使用RXD线接收数据,用TXD发送数据。每个串口由2个数据缓冲器(相互独立1收1发)、一个移位寄存器 (一字节数据一位一位发送出去)、一个串行控制器和一个波特率发生器(这个比较重要,结合相关的定时器)组成。
对应发送、接 收数据完成(RI、TI硬件置1)都会触发串口中断,但是无法确定是哪个触发的,所以在串口中断中我们要判断是接收数据产生的中断还是发送数据产生的中断,对于发送数据产生的中断,我们要软件 将TI清0,并将数据就绪标志清0,允许下一字节数据发送,发送数
据函数中通过while循环,等待发送数据准备就绪,完了将就绪的数据复制给SBUF;对于接收数据产生的中断,我们要软件将RI清0, 并从SBUF中读取数据。
1) 使能 RX TX 引脚 GPIO 时钟和 USART 时钟;
2) 初始化 GPIO,并将 GPIO 复用到 USART 上;
3) 配置 USART 参数;
4) 配置中断控制器并使能 USART 接收中断;
5) 使能 USART
6) USART 接收中断服务函数实现数据接收和发送

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; // 重置状态
        }
    }
}

Logo

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

更多推荐