串口数据的接收可以用三种方式:
1、阻塞方式(接收数据很少用到)
2、中断方式(用的比较多,但是在接收不定长协议数据时候,逻辑判断较复杂)
3、DMA IDLE方式(常用做接收不定长数据)
用cubemx配置下串口驱动如下
接收数据用到的结构体
- #define uart_buf_size 256
- typedef union{
- struct{
- uint8_t buf[uart_buf_size];
- uint8_t timeout;
- uint16_t len;
- }bf;
- uint8_t data[uart_buf_size+3];
- }uart_struct_t;
复制代码
使能串口空闲中断
- __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
- HAL_UART_Receive_DMA(&huart1,(uint8_t *)&uart_info.bf.buf[0],uart_buf_size);
- __HAL_UART_CLEAR_IDLEFLAG(&huart1);
复制代码
重定义printf需要在头文件中加入stdio.h,同时也添加下string.h好使用memxxx函数
- int fputc(int ch, FILE *f)
- {
- while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC) != SET);
- HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,100);
- return ch;
- }
复制代码
中断中进行数据的处理
- void USART1_IRQHandler(void)
- {
- /* USER CODE BEGIN USART1_IRQn 0 */
- if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) == SET)
- {
- __HAL_UART_CLEAR_IDLEFLAG(&huart1);
- HAL_UART_DMAStop(&huart1);
- if(uart_info.bf.timeout == 0)
- {
- uart_info.bf.timeout = 1;
- uart_info.bf.len = uart_buf_size - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
-
- HAL_UART_Transmit(&huart1,(uint8_t *)&uart_info.bf.buf[0],uart_info.bf.len,100);
- }
- uart_info.bf.timeout = 0;
- memset(uart_info.bf.buf,0,uart_buf_size);
- HAL_UART_Receive_DMA(&huart1,(uint8_t *)&uart_info.bf.buf[0],uart_buf_size);
- }
- /* USER CODE END USART1_IRQn 0 */
- HAL_UART_IRQHandler(&huart1);
- /* USER CODE BEGIN USART1_IRQn 1 */
-
- /* USER CODE END USART1_IRQn 1 */
复制代码
以上代码是将接收到的数据原样返回
————————————————
版权声明:jiangxinzhumeng
|