概述
本文利用中断实现串口不定长接收(非DMA),使用HAL库,将接收的数据打印出去。
DMA接收请查看:https://blog.csdn.net/qq_24312945/article/details/106557538
硬件准备
首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:
选择芯片型号
使用STM32CUBEMX选择芯片stm32f030r8,如下所示:
配置时钟源
HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:
配置时钟树
STM32F0的最高主频到48M,所以配置48即可:
串口配置
本次实验使用的串口1进行串口通信,波特率配置为115200。
中断
GPIO配置
板子上led为PA5端口,故设置PA5闪烁来验证是否正确。
定时器配置
本次实验使用的是TIM3来进行计数。
PWM频率计算如下所示
在上面配置TIM3参数,预分频系数设置为480-1, 自动重载值设置为10000-1,那么PWM频率为48,000,000/((480-1+1)*(10000-1+1))=10Hz,即 100ms一个周期。
生成工程设置
注意在生成工程设置中不能出现中文,不然会报错。
代码生成设置
最后设置生成独立的初始化文件:
生成代码
配置keil
代码
在main.c中,先加入头文件。
/* USER CODE BEGIN Includes */
#include 'stdio.h'//printf头文件
#include 'string.h'//memset头文件
/* USER CODE END Includes */
定义变量存储。
/* USER CODE BEGIN PV */
uint8_t RxBuff[1]; //进入中断接收数据的数组
uint8_t DataBuff[5000]; //保存接收到的数据的数组
int RxLine=0; //接收到的数据长度
int Rx_flag=0; //接受到数据标志
/* USER CODE END PV */
定义printf的重定向函数fputc。
/* USER CODE BEGIN 0 */
void printf_usart(void);//输出内容
int fputc(int ch, FILE* file)//定义printf的重定向函数fputc,满足串口调试打印
{
return HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
}
/* USER CODE END 0 */
打开串口和定时器。
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //打开串口中断接收
HAL_TIM_Base_Start_IT(&htim3);//开启定时器
/* USER CODE END 2 */
串口接受代码,当接受到最后数据为FF时候,直接打印,否则等待100ms打印。
复制
/* USER CODE BEGIN 4 */
void printf_usart(void)
{
printf('数据长度=%d
',RxLine);
for(int i=0;iprintf('数据:[%d] = 0x%x
',i,DataBuff[i]);
memset(DataBuff,0,sizeof(DataBuff)); //清空缓存数组
//memset()作用:可以方便的清空一个结构类型的变量或数组。
//例句:memset(aTxbuffer,0,sizeof(aTxbuffer)) 用memset清空aTxbuffer。
RxLine=0; //清空接收长度
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == htim3.Instance)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
/* Toggle LED */
if(Rx_flag==1)
{
printf_usart();
Rx_flag=0;
}
}
}
// 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
{
RxLine++; //每接收到一个数据,进入回调数据长度加1
DataBuff[RxLine-1]=RxBuff[0]; //把每次接收到的数据保存到缓存数组
Rx_flag=1;
if(RxBuff[0]==0xff) //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff
{
printf_usart();
}
RxBuff[0]=0;
HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //每接收一个数据,就打开一次串口中断接收,否则只会接收一个数据就停止接收
__HAL_TIM_SET_COUNTER(&htim3, 1); // 计数清零,从头开始计
}
/* USER CODE END 4 */
演示效果
可以看到 发送11 12 13需要等待100ms左右才能发送,如果最后加上ff直接发送。
上一篇:STM32CUBEMX(14)--SPI,TLC5947外部PWM移植
下一篇:如何用一个ESP8266加上STM32单片机做一个小产品?
推荐阅读最新更新时间:2024-11-03 04:41
设计资源 培训 开发板 精华推荐
- 交流版12V 6J1前级
- LTC1798CS8-3、2.5V 电池供电电压基准的典型应用电路
- 8002小功放
- 使用 Analog Devices 的 LT3591EDDB 的参考设计
- DER-364 - 14 W调光、高效率(>85%)LED驱动器
- MAXREFDES1265:使用 MAX32625PICO 和 MAX7360 的简单键盘接口
- NCP3337MNADJGEVB:可调输出电压 LDO 稳压器评估板
- AM3G-1212DZ ±12V 3 瓦 DC/DC 转换器的典型应用
- 使用 AD5556 14 位乘法 DAC 的精密交流参考信号衰减器
- LT3009 的典型应用 - 3 uA IQ、20mA 低压差线性稳压器