完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
开发环境
STM32CUBMX
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); printf("hello wroldrn"); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_UART_Receive(&huart1,receive_buff,10,0xff);// 接收10个字符 if(receive_buff[0] != 0) { printf("recive buff is %s rn",receive_buff); memset(receive_buff,0,20); // 清除接收内容 } } /* USER CODE END 3 */ } 实验现象 第二种方式:中断方式 时钟准备和串口初始化如上一种方式所示,实例从设置中断开始 设置中断 生成代码 定义相关变量 uint8_t aRxBuffer; //接收中断缓冲 uint8_t Uart1_RxBuff[256] = {0}; //接收缓冲 uint8_t Uart1_Rx_Cnt = 0; //接收缓冲计数 uint8_t Uart1_RxFlag = 0; uint8_t cAlmStr[] = "数据溢出(大于256)rn"; 在usart.h 中编写回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); /* NOTE: This function Should not be modified, when the callback is needed, the HAL_UART_TxCpltCallback could be implemented in the user file */ if(Uart1_Rx_Cnt >= 255) //溢出判断 { Uart1_Rx_Cnt = 0; memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff)); HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF); } else { Uart1_RxBuff[Uart1_Rx_Cnt++] = aRxBuffer; //接收数据转存 if((Uart1_RxBuff[Uart1_Rx_Cnt-1] == 0x0A)&&(Uart1_RxBuff[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位 { Uart1_RxFlag = 1; } } HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中断 } main函数内内容 int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart1,&aRxBuffer,1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(Uart1_RxFlag != 0) { printf("recive buff is %srn",Uart1_RxBuff); Uart1_RxFlag = 0; Uart1_Rx_Cnt = 0; memset(Uart1_RxBuff,0x00,256); } HAL_Delay(10); } /* USER CODE END 3 */ } 实验现象 第三种方法:定时器中断判断串口是否传输完成 此方法可以看做是看作中断接收的一种拓展用法,不同于上一种方法介绍的需要特定的格式的数据帧来判定,此方法结合了定时器,以5ms为界限,如果5ms后没有接收新的数据则认为一包数据已经发送完成。下面是配置的具体方法 1.配置时钟和串口中断的同上,然后配置定时器中断 定时器基础配置 打开定时器中断 我们设置的5ms检测串口是否发送完成 我们使用的定时器的主频是84MHZ 那么定时器频率可用下列方式计算 F = 84 M H Z ( P r e s c a l e r + 1 ) × ( C o u n t e r P e r i o d + 1 ) ; F = frac{84MHZ}{(Prescaler+1)times (CounterPeriod+1)}; F=(Prescaler+1)×(CounterPeriod+1)84MHZ; 配置完成后生成代码 程序部分 定义相关变量 uint8_t aRxBuffer; //接收中断缓冲 uint8_t Uart1_RxBuff[256] = {0}; //接收缓冲 uint8_t Uart1_Rx_Cnt = 0; //接收缓冲计数 uint8_t Uart1_RxFlag = 0; uint8_t cAlmStr[] = "数据溢出(大于256)rn"; 编写串口中断服务函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart -> Instance == USART1) { if(Uart1_Rx_Cnt == 0) { __HAL_TIM_CLEAR_FLAG(&htim6,TIM_FLAG_UPDATE); HAL_TIM_Base_Start_IT(&htim6); Uart1_RxBuff[Uart1_Rx_Cnt] = aRxBuffer; Uart1_Rx_Cnt ++; } else { Uart1_RxBuff[Uart1_Rx_Cnt ++] = aRxBuffer; } if(Uart1_Rx_Cnt >= 255) { Uart1_Rx_Cnt = 0; Uart1_RxFlag = 0; memset(Uart1_RxBuff,0x00,256); } HAL_UART_Receive_IT(&huart1,&aRxBuffer,1); } } 编写定时器中断回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim ->Instance == TIM6) { HAL_TIM_Base_Stop(&htim6); __HAL_TIM_SetCounter(&htim6,0); Uart1_RxFlag = 1; } } 编写主程序 int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM6_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart1,&aRxBuffer,1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(Uart1_RxFlag == 1) { printf("rec buff is %srn",Uart1_RxBuff); memset(Uart1_RxBuff,0x00,256); Uart1_Rx_Cnt = 0; Uart1_RxFlag = 0; } HAL_Delay(10); } /* USER CODE END 3 */ } 实验现象 第四种方法:串口空闲中断加DMA 使用DMA可以减少CPU负荷,当接收大批量数据的时候,可以防止频繁进入中断。这样有助于提高效率,下面我们介绍STM32带有的串口空闲中断来配合DMA接收数据的例子。 配置部分 1 串口配置 基本部分 配置DMA 中断配置 生产代码 定义宏定义 #define USART1_DMA_REC_SIZE 600 #define USART1_REC_SIZE 1200 编写结构体 typedef struct { uint8_t UsartRecFlag; // 标志位 uint16_t UsartRecLen; // 接收数据长度 uint16_t UsartDMARecLEN; // DMA 接收长度 uint8_t Usart1DMARecBuffer[USART1_DMA_REC_SIZE]; // DMA 接收数组 uint8_t Usart1RecBuffer[USART1_REC_SIZE]; // 接收组 }teUsart1type; 编写打开中断函数 // 打开相关中断 void EnableUsart_It(void) { __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); __HAL_UART_CLEAR_IDLEFLAG(&huart1); HAL_UART_Receive_DMA(&huart1,Usart1type.Usart1DMARecBuffer,USART1_DMA_REC_SIZE); } 改写中断服务函数(在stm32f4xx_it.c中) void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ uint16_t temp = 0; __HAL_UART_CLEAR_IDLEFLAG(&huart1); HAL_UART_DMAStop(&huart1); // 关闭DMA temp = huart1.Instance -> SR; // 清除SR状态寄存器 temp = huart1.Instance -> DR; // 清除DR数据寄存器,用来清除中断 temp = hdma_usart1_rx.Instance -> NDTR; // 获取未传输的数据个数 //temp = hdma_usart2_rx.Instance -> NDTR; // F4 Usart1type.UsartDMARecLEN = USART1_DMA_REC_SIZE - temp; HAL_UART_RxCpltCallback(&huart1); /* USER CODE END USART1_IRQn 0 */ HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */ HAL_UART_Receive_DMA(&huart1,Usart1type.Usart1DMARecBuffer,USART1_DMA_REC_SIZE); /* USER CODE END USART1_IRQn 1 */ } 编写中断回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart -> Instance == USART1) { if(Usart1type.UsartRecLen > 0) { memcpy(&Usart1type.Usart1RecBuffer[Usart1type.UsartRecLen],Usart1type.Usart1DMARecBuffer,Usart1type.UsartDMARecLEN); Usart1type.UsartRecLen += Usart1type.UsartDMARecLEN; } else { memcpy(&Usart1type.Usart1RecBuffer,Usart1type.Usart1DMARecBuffer,Usart1type.UsartDMARecLEN); Usart1type.UsartRecLen += Usart1type.UsartDMARecLEN; } memset(Usart1type.Usart1DMARecBuffer,0x00,600); Usart1type.UsartRecFlag = 1; } } 编写主程序 int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ EnableUsart_It(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(Usart1type.UsartRecFlag == 1) { printf("rec buff is %srn",Usart1type.Usart1RecBuffer); memset(Usart1type.Usart1RecBuffer,0x00,USART1_REC_SIZE); Usart1type.UsartRecLen = 0; Usart1type.UsartRecFlag = 0; } HAL_Delay(20); } /* USER CODE END 3 */ } 实验现象 END |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1535 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1484 浏览 1 评论
905 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
651 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1530 浏览 2 评论
1841浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
590浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
491浏览 3评论
492浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
472浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-3 00:21 , Processed in 0.816567 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号