欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

STM32HAL库串口DMA接收不定长数据

时间:2023-04-24

上一期配置https://blog.csdn.net/zy19981110/article/details/123005092?spm=1001.2014.3001.5501

参考他人的代码https://blog.csdn.net/euxnijuoh/article/details/81638676?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3 DMA为默认设置,普通模式。

单独创建.c和.h文件,以便查看整理

#ifndef __USARTDMA_H#define __USARTDMA_H#include "usart.h"#include "dma.h"#include "stm32g0xx_hal.h"#include "string.h"#define UART1_RX_MH440D_SIZE 9#define USART_BUFFER_SIZE 128struct _UsartDMA_Rx{ struct {volatile uint8_t Len; //DMA中接收一帧数据的长度volatile uint8_t Flag; //数据接收完成标志 uint8_t Buffer[128]; //接收数据缓存 }U1; //串口1 struct { volatile uint8_t Len; //DMA中接收一帧数据的长度volatile uint8_t Flag; //数据接收完成标志 uint8_t Buffer[128]; //接收数据缓存 }U2; //串口2};extern struct _UsartDMA_Rx UsartDMA_Rx;void UsartIDLE_Init(void);void USART1_IDLE(void);#endif

可以自行增加多个串口 ,在主函数前调用

#include "UsartDMA.h"struct _UsartDMA_Rx UsartDMA_Rx;void UsartIDLE_Init(){ __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); HAL_UART_Receive_IT(&huart1,UsartDMA_Rx.U1.Buffer,USART_BUFFER_SIZE);__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); HAL_UART_Receive_IT(&huart2,UsartDMA_Rx.U2.Buffer,USART_BUFFER_SIZE);}

 这个代码放到it.c中对应的串口中断服务函数中,注意放到用户代码区域,防止代码被cubemx生成后清空。

 

void USART1_IDLE(void) //串口中断{ uint32_t tmp_flag = 0; uint32_t temp; if(USART1 == huart1.Instance){ tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位 if((tmp_flag != RESET))//idle标志被置位 { UsartDMA_Rx.U1.Flag = 1; // 接受完成标志位置1 __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位 HAL_UART_DMAStop(&huart1); // temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数 UsartDMA_Rx.U1.Len = USART_BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数 HAL_UART_Receive_DMA(&huart1,UsartDMA_Rx.U1.Buffer,USART_BUFFER_SIZE);//重新打开DMA接收 } } }

忘了说要在usart.h文件中进行外部声明,不然会找不到定义。 

实际应用,直接发完就读,测试传感器时没写太多功能函数

uint8_t GetCheckSum(uint8_t *packet,uint8_t start,uint8_t end){uint8_t i, checksum;for( i = start; i < (end-1); i++){checksum += packet[i];}checksum = 0xff-checksum +1;return checksum;}void MH440D_SendCom(_MH440D* MH440D){uint8_t i;uint8_t Sendbuff[9]={0xff,MH440D->CH4_N,MH440D->CH4_Com,0,0,0,0,0,0};MH440D->CheckSum=GetCheckSum(Sendbuff,1,8);Sendbuff[8]=MH440D->CheckSum;memcpy(MH440D->SendBuff,Sendbuff,9); //复制数组HAL_UART_Transmit_DMA(&huart1,MH440D->SendBuff ,9); //发送一次}FlagStatus MH440D_Read(_MH440D* MH440D){ if(UsartDMA_Rx.U1.Flag==1) {UsartDMA_Rx.U1.Len = 0;//清除计数UsartDMA_Rx.U1.Flag = 0;//清除接收结束标志位 memcpy(MH440D->RecBuff,UsartDMA_Rx.U1.Buffer,UART1_RX_MH440D_SIZE);if( MH440D->RecBuff[0]==0xFF && MH440D->RecBuff[1] ==0x86) //判断设备首地址和命令{ MH440D->CheckSum =GetCheckSum(MH440D->RecBuff,1,8); if(MH440D->RecBuff[8]==MH440D->CheckSum) { MH440D->CH4_H=MH440D->RecBuff[2]; //读出传感器数据 MH440D->CH4_L=MH440D->RecBuff[3]; memset(UsartDMA_Rx.U1.Buffer,0,sizeof(UsartDMA_Rx.U1.Buffer)); //清空数组return 1; } elsereturn 0;}elsereturn 0;} else return 0;}

FlagStatus SF6_ReadData(uint8_t ID){ if(UsartDMA_Rx.U2.Flag==1) {UsartDMA_Rx.U2.Len = 0;//清除计数UsartDMA_Rx.U2.Flag = 0;//清除接收结束标志位 memcpy(SF6.RecBuff,UsartDMA_Rx.U2.Buffer,7); } else return 0;if(SF6.RecBuff[0]==ID){SF6.CRC_Val=CRC16(SF6.RecBuff,5,&SF6.Recv_CRC_L,&SF6.Recv_CRC_H); if(SF6.RecBuff[5]==SF6.Recv_CRC_L && SF6.RecBuff[6]==SF6.Recv_CRC_H){if(SF6.RecBuff[1]==SF6_ReadGas && SF6.RecBuff[2]==0x02){SF6.PPM_L=SF6.RecBuff[4];SF6.PPM_H=SF6.RecBuff[3];return 1;}else ;}elsereturn 0;}else return 0;}

 

 

 

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。