完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
简介
1、使用到的软件 STM32CubeMX 6.1.0 和keil 5.33 2、芯片 STM32L071CBT6 3、实现功能,按帧接收串口数据,数据存入接收buff,帧长存入全局变量 实现原理 当一帧数据传输结束之后,总线IDLE会维持高电平状态,此时就可以触发MCU的IDLE中断。因此利用IDLE中断进行串口不定长数据的接收。省去了用于检测传输是否完成的判断动作。 然而在HAL库中并未集成IDLE中断的处理,所以,我们可以在串口的中断处理中添加对IDLE总线状态的判断,以检测当前帧是否传输完成。 工程实现 1、CubeMX工程配制 (使能两个串口,串口1发送,串口2接收) 串口DMA设置 中断使能 2、代码编辑 main.c全局变量定义 /* USER CODE BEGIN 0 */ uint8_t gcRXDBuffer[50], gcRXDPointer; //接收的缓冲区、接收指针 uint16_t gcRXDLength; //接收的帧长度 uint8_t gcTXDBuffer[50], gcTXDPointer, gcTXDLength; //发送的缓冲区,发送指针,发送的长度 uint8_t recv_end_flag; //接收完成标识 /* USER CODE END 0 */ 函数 MX_USART2_UART_Init(void) 中添加 /* USER CODE BEGIN USART2_Init 2 */ __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); //使能idle中断 HAL_UART_Receive_DMA(&huart2,gcRXDBuffer,sizeof(gcRXDBuffer)); //打开DMA串口接收 /* USER CODE END USART2_Init 2 */ 串口中断处理函数中modify extern uint8_t gcRXDBuffer[50], gcRXDPointer ; //接收的缓冲区、接收指针、接收的帧长度 extern uint16_t gcRXDLength; extern uint8_t recv_end_flag; void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ uint32_t tmp_flag = 0; uint32_t temp; tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //获取IDLE标志位 if((tmp_flag != RESET))//idle标志被置位 { __HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除标志位 HAL_UART_DMAStop(&huart2); // temp = __HAL_DMA_GET_COUNTER(huart2.hdmarx);// 获取DMA中未传输的数据个数 gcRXDLength = sizeof(gcRXDBuffer) - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数 recv_end_flag = 1; // 接受完成标志位置1 HAL_UART_Receive_DMA(&huart2,gcRXDBuffer,sizeof(gcRXDBuffer));//重新打开DMA接收 } /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */ } 主函数main中 /* USER CODE BEGIN 2 */ strcpy((char*)gcTXDBuffer,"this is test message!"); //include uint8_t sendBuff[] = {"123456789"}; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ int i=0; while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(500); i++; if(i%2) HAL_UART_Transmit(&huart1, gcTXDBuffer,10,0XFFFF); else HAL_UART_Transmit(&huart1, sendBuff,8,0XFFFF); HAL_Delay(100); if(recv_end_flag ==1) { //add code to deal UART message gcRXDLength=0;//清除计数 recv_end_flag=0;//清除接收结束标志位 } HAL_Delay(500); } /* USER CODE END 3 */ CNDTR寄存器设置说明 HAL_UART_Receive_DMA(&huart2,gcRXDBuffer,sizeof(gcRXDBuffer)); ====》》 UART_Start_Receive_DMA(huart, pData, Size) ====》》 HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) ====》》 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength)====》》 /* Configure DMA Channel data length */ hdma->Instance->CNDTR = DataLength; 通过以上调用,最终在DMA_SetConfig函数中,对CNDTR寄存器进行了设置。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 16:53 , Processed in 0.546529 second(s), Total 42, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号