完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在STM32F103中使用空闲中断的时候,经常会出现丢数据的情况,我猜测是因为连接环境中有延时,造成标志位误触发的情况。
解决思路,直接使用LL库代替HAL库,不用DMA也不用空闲中断,用最原始的办法就是直接接收中断触发的方式做。 使用定时器1,用于接收延时处理,达到不定长字符串接收的目的。 1,CUBEMX配置 不用DMA 中断勾选 定时器配置 2 部分工程代码 需要定义的变量 #define DEBUG 1 #define ERROR_LOG(x) if(DEBUG)printf("error_%d:%s.rn",__LINE__,x); #ifndef NULL #define NULL ((void*)0) #endif //用于包缓冲或者组包的Buf #define BUFFER_SIZE 256 int8_t S1recvEnd=0; int8_t S1TimeOut=0; int16_t S1recvLen=0; int8_t S2recvEnd=0; int8_t S2TimeOut=0; int16_t S2recvLen=0; int8_t S3recvEnd=0; int8_t S3TimeOut=0; int16_t S3recvLen=0; uint8_t mS1SendBuf[BUFFER_SIZE]; uint8_t mS1RecvBuf[BUFFER_SIZE]; uint8_t mS2SendBuf[BUFFER_SIZE]; uint8_t mS2RecvBuf[BUFFER_SIZE]; uint8_t mS3SendBuf[BUFFER_SIZE]; uint8_t mS3RecvBuf[BUFFER_SIZE]; void TestUsartRecvTask(void const * argument) { //串口初始化 LL_USART_EnableIT_RXNE(USART1); LL_USART_EnableIT_PE(USART1); LL_USART_EnableIT_RXNE(USART2); LL_USART_EnableIT_PE(USART2); LL_USART_EnableIT_RXNE(USART3); LL_USART_EnableIT_PE(USART3); //定时器开中断 HAL_TIM_Base_Start_IT(&htim1); //I2C_Init(); while(1) { if(S1recvEnd) { S1recvEnd = 0; USART_SendData(USART1,mS1RecvBuf,S1recvLen); HAL_GPIO_WritePin(RS485_DE3_GPIO_Port,RS485_DE3_Pin,GPIO_PIN_SET); USART_SendData(USART3,mS1RecvBuf,S1recvLen); HAL_GPIO_WritePin(RS485_DE3_GPIO_Port,RS485_DE3_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(RS485_DE2_GPIO_Port,RS485_DE2_Pin,GPIO_PIN_SET); USART_SendData(USART2,mS1RecvBuf,S1recvLen); HAL_GPIO_WritePin(RS485_DE2_GPIO_Port,RS485_DE2_Pin,GPIO_PIN_RESET); //HAL_UART_Transmit(&huart1,mS1RecvBuf,S1recvLen,0xFFFFFFFF); //HAL_UART_Receive_DMA(&huart1,mS1RecvBuf,BUFFER_SIZE); S1recvLen = 0; } if(S2recvEnd) { S2recvEnd = 0; USART_SendData(USART1,mS2RecvBuf,S2recvLen); //HAL_UART_Transmit(&huart1,mS2RecvBuf,S2recvLen,0xFFFFFFFF); //HAL_UART_Receive_DMA(&huart2,mS2RecvBuf,BUFFER_SIZE); S2recvLen =0; } if(S3recvEnd) { S3recvEnd = 0; USART_SendData(USART1,mS3RecvBuf,S3recvLen); //HAL_UART_Transmit(&huart1,mS3RecvBuf,S3recvLen,0xFFFFFFFF); //HAL_UART_Receive_DMA(&huart3,mS3RecvBuf,BUFFER_SIZE); S3recvLen = 0; } ReadSensor(); //HAL_Delay(1000); } //HAL_Delay(10); } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim==&htim1) { static uint32_t timeLed=1000; static GPIO_PinState msate = GPIO_PIN_RESET; if(msate)msate = GPIO_PIN_RESET; else msate = GPIO_PIN_SET; if(timeLed--==0) { timeLed = 1000; HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,msate); } if(S1TimeOut)S1TimeOut--; else if(S1recvLen>1) { S1recvEnd =1; } if(S2TimeOut)S2TimeOut--; else if(S2recvLen>1) { S2recvEnd =1; } if(S3TimeOut)S3TimeOut--; else if(S3recvLen>1) { S3recvEnd =1; } //HAL_UART_Transmit(&huart1,"heesl",5,20); //printf("mrn"); } } void USART_SendData(USART_TypeDef *uart,uint8_t *tmpData,int16_t len) { int16_t iLen=0; for(iLen=0;iLen LL_USART_TransmitData8(uart,tmpData[iLen]);//将数据准备好 while(!LL_USART_IsActiveFlag_TC(uart)); //发送完数据再返回 } } void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ if(LL_USART_IsActiveFlag_RXNE(USART1)) { S1TimeOut =UART_TIMEOUT; mS1RecvBuf[S1recvLen] = LL_USART_ReceiveData8(USART1); //LL_USART_TransmitData8(USART1,mS1RecvBuf[S1recvLen]); S1recvLen++; if(S1recvLen >=BUFFER_SIZE)S1recvLen=0; //LL_USART_TransmitData8(USART1,tmp); } /* USER CODE END USART1_IRQn 0 */ /* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */ } /** * @brief This function handles USART2 global interrupt. */ void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ if(LL_USART_IsActiveFlag_RXNE(USART2)) { S2TimeOut =UART_TIMEOUT; if(S2recvLen >=BUFFER_SIZE)S2recvLen=0; mS2RecvBuf[S2recvLen++] = LL_USART_ReceiveData8(USART2); //LL_USART_TransmitData8(USART1,tmp); } /* USER CODE END USART2_IRQn 0 */ /* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */ } /** * @brief This function handles USART3 global interrupt. */ void USART3_IRQHandler(void) { /* USER CODE BEGIN USART3_IRQn 0 */ if(LL_USART_IsActiveFlag_RXNE(USART3)) { S3TimeOut =UART_TIMEOUT; if(S3recvLen >=BUFFER_SIZE)S3recvLen=0; mS3RecvBuf[S3recvLen++] = LL_USART_ReceiveData8(USART3); //LL_USART_TransmitData8(USART1,tmp); } /* USER CODE END USART3_IRQn 0 */ /* USER CODE BEGIN USART3_IRQn 1 */ /* USER CODE END USART3_IRQn 1 */ } 大致思路就是: 产生中断--》缓存-》定时器检查》超时接收完成。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1621 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1546 浏览 1 评论
980 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
686 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1599 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
650浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
534浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 19:20 , Processed in 0.911572 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号