打印
[STM32L5]

【STM32L562E-DK试用】4.UART通讯与硬件CRC

[复制链接]
224|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
UART在嵌入式领域应用的非常广泛,这块板子引出了一路串口接到了STLink的串口上,倒也省得再找USB转串口了,直接用这个测试一下串口功能

在之前生成的工程中已经配置好了串口的IO

默认的串口配置参数如图

尝试直接通过串口发送数据到PC,看看通讯是否正常,串口的初始化代码STM32CubeMX已经帮我们写好了,直接调用发送方法就行了
void AppUartSendStr(char *str)
{
    while(*str != '\0')
    {
        LL_USART_TransmitData8(USART1,(uint8_t)*str);
        while(!LL_USART_IsActiveFlag_TXE(USART1));
        str += 1;
    }
}
void AppUserLoop(void)
{
    LL_mDelay(1000);
    AppUartSendStr("STM32L562E-DK试用 code by yuyy1989");
}
开发板连接到PC后会出现一个虚拟串口设备

打开串口通讯软件,配置好串口参数,观察是否有数据发送过来,运行效果如图


顺便完成一下重定向printf到串口,以方便后面调试,打开keil工程设置勾选use microlib

在文件中包含stdio.h头文件,然后重写fputc
int fputc(int ch, FILE *f)
{
    LL_USART_TransmitData8(USART1,(uint8_t)ch);
    while(!LL_USART_IsActiveFlag_TXE(USART1));
    return 0;
}
uint8_t count = 0;
void AppUserLoop(void)
{
    LL_mDelay(1000);
    printf("【STM32L562E-DK试用】printf测试%d code by yuyy1989",count++);
}
写完代码后选择rebuld重新完整编译一次,不然可能会报错,运行效果

接下来实现串口的中断接收功能,生成的工程默认是没有开启中断的,打开STM32CubeMX开启串口中断

重新生成代码,和之前的定时器一样,需要手动使能串口中断,这里开启接收中断和空闲中断
LL_USART_EnableIT_RXNE(USART1);
LL_USART_EnableIT_IDLE(USART1);
触发空闲中断后将接收到的数据原样发送回去
#define UART_BUFFER_LEN 100
uint8_t uart_buffer[UART_BUFFER_LEN] = {0};
uint8_t uart_rxlen = 0;
uint8_t uart_rxfin_flag = 0;
void USART1_IRQHandler(void)
{
    if(LL_USART_IsActiveFlag_RXNE(USART1))
    {
        uart_buffer[uart_rxlen] = LL_USART_ReceiveData8(USART1);
        uart_rxlen += 1;
        if(uart_rxlen == UART_BUFFER_LEN)
        {
            uart_rxfin_flag = 1;
            LL_USART_DisableIT_RXNE(USART1);
        }
    }
    if(LL_USART_IsActiveFlag_IDLE(USART1))
    {
        uart_rxfin_flag = 1;
        LL_USART_DisableIT_RXNE(USART1);
        LL_USART_ClearFlag_IDLE(USART1);
    }
}
void AppUserLoop(void)
{
    uint8_t txindex = 0;
    if(uart_rxfin_flag > 0)
    {
        while(txindex < uart_rxlen)
        {
            LL_USART_TransmitData8(USART1,uart_buffer[txindex]);
            while(!LL_USART_IsActiveFlag_TXE(USART1));
            txindex += 1;
        }
        uart_rxfin_flag = 0;
        uart_rxlen = 0;
        LL_USART_EnableIT_RXNE(USART1);
    }
}
运行效果如图

STM32L562内置有CRC计算模块,可以快速产生CRC码,从而验证数据的完整性和正确性,这个功能在数据通信领域尤为重要,因为它可以确保数据在传输过程中的准确性,例如MODBUS就要用到CRC16,接下来配置CRC功能,将串口接收到的数据进行CRC16-MODBUS校验再通过串口输出结果
打开STM32CubeMX开启CRC,要关闭默认多项式和初始值才能自定义配置多项式和初始值,多项式要注意X16这位不用输入也输入不进去,输入数据按字节翻转,开启输出数据翻转

代码实现计算串口接收到数据的CRC并用printf打印到串口,串口接收部分不用动,将前面的发送过程改一下加入CRC校验过程

void AppUserLoop(void)
{
    uint16_t crc_result = 0;
    if(uart_rxfin_flag > 0)
    {
        LL_CRC_ResetCRCCalculationUnit(CRC);
        while(txindex < uart_rxlen)
        {
            LL_CRC_FeedData8(CRC,uart_buffer[txindex]);
            txindex += 1;
        }
        crc_result = LL_CRC_ReadData16(CRC);
        printf("【STM32L562E-DK试用】CRC计算结果:%04X code by yuyy1989",crc_result);
        uart_rxfin_flag = 0;
        uart_rxlen = 0;
        LL_USART_EnableIT_RXNE(USART1);
    }
}
计算结果和网页工具比对,结果一致


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

156

主题

757

帖子

7

粉丝