完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
初衷
因为学习的需要,需要使用LPUART串口实现数据的整帧传输,所以在网上找了很多的教程,都没有解决我的问题,大家使用的基本上都是DMA传输加空闲中断的方式实现整帧的传输,我跟着很多帖子做了实验,但是均未成功,后来直接使用串口的空闲中断不使用DMA也完成了数据的整帧传输,记录下来,用以复习。 代码思路 STM32CubeMX中的设置 串口使用了UART1和LPUART1,时钟使用了高速外部时钟和低速外部时钟 串口设置 串口1设置 LPUART1设置(此串口与我的NB模块相连接,实现AT指令的发送和模块回传数据的接收) 使能两个串口的中断 时钟频率的设置(重点是LPUART的时钟频率是32.768KHZ) 之后生成MDK5工程 MDK5中的代码 stm32l4xx_it.c 声明变量 #ifndef MAX_RCV_LEN #define MAX_RCV_LEN 1024 #endif extern uint8_t LPUART1RECV[MAX_RCV_LEN]; extern void USART_IDLECallBack(void); extern void LPUART_IDLECallBack(void); 在下面的代码中判断是否发生了空闲中断 void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET)//判断此中断是否为空闲中断 { USART_IDLECallBack();//进入空闲中断处理函数,此函数我定义在main.c中 } /* USER CODE END USART1_IRQn 0 */ HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */ } void LPUART1_IRQHandler(void) { /* USER CODE BEGIN LPUART1_IRQn 0 */ if(__HAL_UART_GET_FLAG(&hlpuart1,UART_FLAG_IDLE)!=RESET)//判断此中断是否为空闲中断 { LPUART_IDLECallBack();//进入空闲中断处理函数,此函数我定义在main.c中 } /* USER CODE END LPUART1_IRQn 0 */ HAL_UART_IRQHandler(&hlpuart1); /* USER CODE BEGIN LPUART1_IRQn 1 */ /* USER CODE END LPUART1_IRQn 1 */ } usart.c 声明变量 extern uint8_t Buftemp; extern uint8_t Buftemp2; 在串口初始化的时候对串口使能第一次中断,就省下了在main.c中进行使能 void MX_LPUART1_UART_Init(void) { hlpuart1.Instance = LPUART1; hlpuart1.Init.BaudRate = 9600; hlpuart1.Init.WordLength = UART_WORDLENGTH_8B; hlpuart1.Init.StopBits = UART_STOPBITS_1; hlpuart1.Init.Parity = UART_PARITY_NONE; hlpuart1.Init.Mode = UART_MODE_TX_RX; hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&hlpuart1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } HAL_UART_Receive_IT(&hlpuart1,&Buftemp,1);//使能第一次中断 } void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } HAL_UART_Receive_IT(&huart1,&Buftemp2,1);//使能第一次中断 } main.c 声明变量 #define MAX_RCV_LEN 1024 uint8_t data[MAX_RCV_LEN]; uint8_t endflag=0; uint8_t Buftemp; uint8_t Buftemp2; uint16_t lpuart1_recv_len=0; uint16_t uart1_recv_len=0; uint8_t data2[MAX_RCV_LEN]; uint8_t LPUART1RECV[MAX_RCV_LEN]; void USART_IDLECallBack(void); void LPUART_IDLECallBack(void); while循环 while (1) { HAL_Delay(10000); HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); uint8_t temp[]={"AT+NATSPEED?rn"};//NB模块的AT命令 int len=sizeof(temp); HAL_UART_Transmit(&hlpuart1,temp,len,0xff);//通过LPUART1发送命令到NB模块 HAL_UART_Receive_IT(&hlpuart1,&Buftemp,1);//避免LPUART串口在使用HAL_UART_Transmit函数后出现问题,再次使能中断接收 HAL_Delay(10000); HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); uint8_t temp1[]={"AT+CGATT?rn"}; int len1=sizeof(temp1); HAL_UART_Transmit(&hlpuart1,temp1,len1,0xff);//通过LPUART1发送命令到NB模块 HAL_UART_Receive_IT(&hlpuart1,&Buftemp,1);//避免LPUART串口在使用HAL_UART_Transmit函数后出现问题,再次使能中断接收 } 其他函数定义在main.c最后 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance==USART1) { //只有第一次中断会调用 if(uart1_recv_len==0) { __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//使能空闲中断 } data2[uart1_recv_len++]=Buftemp2; HAL_UART_Receive_IT(&huart1,&Buftemp2,1); } if(huart->Instance==LPUART1) { //只有第一次中断会调用 if(lpuart1_recv_len==0) { __HAL_UART_ENABLE_IT(&hlpuart1,UART_IT_IDLE);//使能空闲中断 } data[lpuart1_recv_len++]=Buftemp; HAL_UART_Receive_IT(&hlpuart1,&Buftemp,1); } } void LPUART_IDLECallBack() { unsigned int temp; __HAL_UART_CLEAR_IDLEFLAG(&hlpuart1);//清除标志位 temp = LPUART1->RDR; //清除状态寄存器RDR temp = temp; HAL_UART_Transmit(&huart1,data,lpuart1_recv_len,0xff); memset(data,0,MAX_RCV_LEN); lpuart1_recv_len=0; } void USART_IDLECallBack() { unsigned int temp; __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位 temp = USART1->RDR; //清除状态寄存器RDR temp = temp; HAL_UART_Transmit(&hlpuart1,data2,uart1_recv_len,0xff); HAL_UART_Receive_IT(&hlpuart1,&Buftemp,1); memset(data2,0,MAX_RCV_LEN); uart1_recv_len=0; } 实验成功截图 因为放上来的代码删除了无用的printf函数所以有些区别 |
|
|
|
只有小组成员才能发言,加入小组>>
调试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 21:49 , Processed in 0.753238 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号