【蓝桥杯嵌入式】stm32串口接收(一次性接收多个字符)(使用中断)

附上我的工程链接

链接:https://pan.baidu.com/s/1-WNduviH-wgYQeL-dgM4wA?pwd=f0uh 
提取码:f0uh

2024.1.30补充:如果有判断非法字符的话,那么只能接收一个字符

        且

if (rx_pointer > 0) {
    HAL_Delay(10);
    if (rx_pointer == 2) {
    }
rx_pointer = 0;
memset(rxdata,0,20);

        这里的HAL_Delay非常重要;

2024,1,26  补充:下文是发送一个字符,一个一个判断,但是串口发送快的时候,会出现错误。

因此,我改变了具体要接收的数据位数为7:如下

HAL_UART_Receive_IT(&huart1,rxdat,7);

在main函数里插入这一条代码,7表示接收的位数。

同时,将rxdat由uint8_t rxdat 改为uint8-t rxdat[10]

char rxdata[30];
uint8_t rxdat[10];
unsigned char rx_pointer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){

	for(int i=0;i<7;i++){
		rx_pointer++;
		rxdata[i] = rxdat[i];
	}
	HAL_UART_Receive_IT(&huart1,rxdat,7);
}

还有将里面的rxdata[rx_pointer++] = radat改为了    

for(int i=0;i<7;i++){
        rx_pointer++;
        rxdata[i] = rxdat[i];
}

这样子,一接收到数据,就会把rx_pointer➕为7,那么这个回调函数写完了。我的调用串口接收数据修改如下:

if (rx_pointer>0){
	HAL_Delay(1);
	if (rx_pointer == 7){
		HAL_UART_Transmit(&huart1,(uint8_t *)"yes\r\n",sizeof("yes "),100);
	}
	else
		HAL_UART_Transmit(&huart1,(uint8_t *)"Error\r\n",sizeof("Error "),100);
}
rx_pointer = 0;

我这里将memset删除了,因为每次接收到数据,数据会把rx_pointer重新置为0,覆盖之前的数据,这样子,就可以读取radata里面的数据了,这样子接收的再快,不容易出现错误,比起之前接收一位,然后不停判断好多了

正文:

1. 配置stm32cubemx

        1.1rcc时钟配置

        

        1.2  下载器配置

        1.3 USART1配置

        1.3 时钟树配置

        要选择外部晶振的话,切记一定要是24Mhz的晶振,要不然串口打印的时候会乱码!!!

        1.4 其他项配置

配置完电机generate code,之后打开keil工程。

2. keil代码

        2.1  首先找到stm32g4xx_it.c,在最后面编写

char rxdata[30];
uint8_t rxdat;
unsigned char rx_pointer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *hurat){
	rxdata[rx_pointer++] = rxdat;	
	HAL_UART_Receive_IT(&huart1,&rxdat,1);

}

        2.2 在main函数里声明外部变量

        这里的car_xxxx是存放我们串口一次性要发送的数据

uint8_t ucLcd[21];
char car_type[5];
char car_data[5];
char car_time[13];

extern char rxdata[30];
extern uint8_t rxdat;
extern unsigned char rx_pointer;

        2.3 定义一个函数

        这个函数是接收函数。

void UART_Receice_Proc(void){
	if (rx_pointer > 0){
        HAL_Delay(10); //延时一会,而且NVIC里的basetim优先级要设置高一点
		if (rx_pointer == 6){
			sscanf(rxdata,"%2s:%1s:%1s",car_type,car_data,car_time);
			printf("yes");
		}
		else{
			HAL_UART_Transmit(&htim1,(uint8_t *)"Error\r\n",sizeof("Error\r\n"),50);
		}
	}
	rx_pointer = 0;
	memset(rxdata,0,30);
}

        2.4 在while(1)中调用你这个函数、

        这些判断是为了更加精确的判断是否接收到了数据,最好加上,因为我没这些代码的时候,串口接受十分的不灵敏。估计是串口接收的太快,毕竟是异步通信,没有统一的时序。

		if(rx_pointer > 0)
		{
			int temp = rx_pointer;
			HAL_Delay(1);
			if(temp == rx_pointer)
			UART_Receice_Proc();
		}

        2.5 开启中断

        之后配置好后,你也可以配置lcd显示在屏幕上,但是注意一点,LCD初始化一定要在一大堆的初始化后面。要不然会出现接受不到的现象。

	HAL_UART_Receive_IT(&huart1,&rxdat,1);

 3. 效果

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32HAL库的串口接收到数据时,会触发中断中断处理函数会在接收数据缓冲区中读取数据,并将其存储在一个缓冲区中。一旦接收到完整的数据包,它就会被传递给应用程序处理。 以下是一个简单的示例代码,演示如何使用STM32HAL库接收串口数据中断: ```c #include "stm32f4xx_hal.h" #define BUFFER_SIZE 100 UART_HandleTypeDef huart2; uint8_t rxBuffer[BUFFER_SIZE]; uint8_t index = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart == &huart2) { if (rxBuffer[index - 1] == '\n') { // complete data has been received rxBuffer[index] = '\0'; // add null termination index = 0; // reset index // process data } else { index++; if (index >= BUFFER_SIZE) { // buffer overflow index = 0; } } HAL_UART_Receive_IT(&huart2, &rxBuffer[index], 1); // enable receive interrupt again } } int main(void) { HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_USART2_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2); HAL_UART_Receive_IT(&huart2, &rxBuffer[index], 1); // enable receive interrupt while (1); } ``` 在上面的代码中,当串口接收到数据时,会调用`HAL_UART_RxCpltCallback()`函数。这个函数会检查接收的数据是否已经完整,如果是,则将其存储在缓冲区中,并将缓冲区重置为下一次接收。如果数据还不完整,则继续等待接收下一个字符,并再次启用接收中断。 注意,使用`HAL_UART_Receive_IT()`函数启用接收中断时,需要传递一个指向缓冲区的指针和要接收的字节数。在上面的代码中,我们每次只接收一个字节,因为我们需要检查完整性。如果您的应用程序可以保证数据完整性,那么可以一次性接收多个字节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值