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);
}
}
计算结果和网页工具比对,结果一致
|