举报
【STM32G431】STM32使用STM32CubeMX配置串口接收中断并做简单的CRC校验
2026-01-13 00:31:45
93次阅读
0个评论
最后修改时间:2026-01-13 00:42:22
1.使用STM32CubeMX新建一个工程

2.设置系统主频,我这直接使用内部晶振,输入需要的主频回车会自动配置分频

3.配置串口


4.配置串口中断

5.导出代码


6.串口重定义printf

FILE *_stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0x10);
return ch;
}
7.简单写个接收和crc校验函数
// CRC 计算函数
uint8_t gh_crc8( uint8_t * p_buffer, uint16_t buf_size )
{
uint8_t crc = 0;
if(buf_size <= 0)
{
return crc;
}
while( buf_size-- )
{
for ( uint8_t i = 0x80; i != 0; i /= 2 )
{
if ( (crc & 0x80) != 0)
{
crc *= 2;
crc ^= 0x07; // 多项式:X8 + X2 + X + 1
}
else
{
crc *= 2;
}
if ( (*p_buffer & i) != 0 ){
crc ^= 0x07;
}
}
p_buffer++;
}
return crc;
}
void handle_command(uint8_t command, uint8_t *data, uint8_t data_length) {
// 处理具体命令和数据
printf("Command: %d, Data Length: %d\r\n", command, data_length);
// 在这里根据需要处理具体的命令和数据
}
void handle_crc_error(uint8_t crc) {
// 处理CRC校验失败的情况
printf("0x%02X,CRC Error: Data corrupted!\r\n",crc);
}
void process_received_data() {
if (rx_index < 2) return; // 至少需要3个字节(命令 + 长度 + CRC)
if (rx_index < rx_buffer[1]) return;
uint8_t command = rx_buffer[0];
uint8_t total_length = rx_buffer[1];
// 检查是否接收到完整的数据
if (rx_index >= total_length) { // 3个字节:命令、长度和CRC
uint8_t data_length = total_length-1; // 数据长度
uint8_t *data = &rx_buffer[2]; // 数据起始地址
uint8_t crc_received = rx_buffer[data_length]; // 接收到的CRC
// 计算CRC
uint8_t crc_calculated = gh_crc8(rx_buffer, data_length); // 计算CRC(命令 + 长度 + 数据)
// 校验CRC
if (crc_calculated == crc_received) {
// CRC 校验成功
handle_command(command, data, data_length);
} else {
// CRC 校验失败,处理错误
handle_crc_error(crc_calculated);
}
// 不论成功与否,重置接收索引,为下一个数据包准备
rx_index = 0;
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
// 每次接收到一个字节
if (rx_index < BUFFER_SIZE) {
rx_buffer[rx_index++] = byte;
// 根据协议处理接收到的数据
process_received_data();
} else {
// 清理接收缓冲区以防止溢出
rx_index = 0; // Reset or handle overflow
}
HAL_UART_Receive_IT(&huart1, &byte, 1); // 继续接收下一个字节
} 8.实验现象,简单拼了一个协议:(命令(1B) + 总长度(1B) + 数据(变长) + CRC(1B))

0
0