HAL库用UART发送数据产生pwm控制灯的亮度实验

2023-10-31 13:58

本文主要是介绍HAL库用UART发送数据产生pwm控制灯的亮度实验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近花了两天时间,踩了大量的坑,总算是把hal库的串口收发数据相关的函数大概给弄明白了,把uart相关的函数逻辑设计的过于复杂可以说是hal库的一个问题,下面开始对hal库内有关串口通讯的函数内容做一个大致的解析

对于收发数据来说,假如不以dma方式进行收发,那么我们主要会接触到的函数有以下四个

HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
 

其中HAL_UART_Transmit与HAL_UART_Receive两个函数比较好理解,函数的定义也很详细,简单来说就是一定时间内完成发送,若设定的最大时间内仍然未完成则报一个溢出,我们在单片机内利用重映射来使用printf与scanf时,也是使用了这两个函数。这两个函数与中断无关。

在这里写一下printf和scanf的原型,平时大家可能会用得上。

int fputc(int ch, FILE *f)
{uint8_t ch;HAL_UART_Transmit(&huart1, (uint8_t *)&ch,1, 0xFFFF);return ch;
}
int fgetc(FILE *f)
{uint8_t  ch;HAL_UART_Receive(&huart1,(uint8_t *)&ch, 1, 0xFFFF);return  ch;
}

然后是重头戏,也是我花了两天去研究的程序逻辑:

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

直接查看函数的定义基本上不会有任何收获,这一点也是我觉得hal库比较讨厌的地方,像这种逻辑比较跳跃的地方却没有多少注释。

我们来看一下执行一次串口中断的流程:

 (感谢正点原子的资料)

顺序是这样的UARTx_IRQHandler->HAL_UART_IRQHandler->UART_Receive_IT->HAL_UART_RxCpltCallback

你没有看错——UART_Receive_IT这个函数又是一个新的函数,不在我们上面讲的四个函数之列。这个函数的定义相对而言比较简单,大家自己可以很容易的看定义看懂。

然后关于HAL_UART_Receive_IT,它的一个工作流程,我理解成它是把我在函数入口处的输入传递给指针*pdata和RxXferCount,并且使能中断,这个中断以中断回调函数RxCpltCallback结尾,并且在中断结束之后就自动关闭中断(这点非常重要),因此一般会在while(1)或者中断回调函数中调用。

另外有一个问题,当我以这样的方式写程序时,数据的收发是失败的,我个人偏向于把这个问题的原因理解成通过Transmit这个函数之后,串口中断被结束了,导致整个中断无法再被使能,而把Transmit改成Transmit_IT后,这个问题就得到了解决。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{HAL_UART_Transmit(&huart1,aRxbuffer,5,100);		HAL_UART_Receive_IT(&huart1,aRxbuffer,5);}

贴一下我成功实现控制的代码:

unsigned char pwm_buff=0;
unsigned char aRxbuffer[2]={0};
uint8_t aTxbuffer[] = "*******开始启用串口*********\r\n";
uint8_t message[] = "the value of the light is:";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();MX_TIM2_Init();HAL_TIM_Base_Start_IT(&htim2);HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_UART_Receive_IT(&huart1,aRxbuffer,2);TIM2->CCR2 = 100-pwm_buff;/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){pwm_buff=(aRxbuffer[0]-48)*10+(aRxbuffer[1]-48);HAL_UART_Transmit(&huart1,message,sizeof(message),100);HAL_UART_Transmit(&huart1,aRxbuffer,2,100);HAL_UART_Transmit(&huart1,"\r\n",2,100);}	
}

以及失败的代码:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{HAL_UART_Transmit_IT(&huart1,aRxbuffer,2);HAL_UART_Receive_IT(&huart1,aRxbuffer,2);counter=(aRxbuffer[0] - 0x30)*10 + (aRxbuffer[1] - 0x30);TIM2->CCR2 = counter;
}

匪夷所思的是下面这段代码是能够成功实现控制的 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{HAL_UART_Transmit_IT(&huart1,aRxbuffer,1);HAL_UART_Receive_IT(&huart1,aRxbuffer,1);if(aRxbuffer[0]=='1')counter=0;else if(aRxbuffer[0]=='0')counter=100;TIM2->CCR2 = counter;
}

目前还没有想明白到底问题出在哪里,有想法的同学可以在评论里留言

 

这篇关于HAL库用UART发送数据产生pwm控制灯的亮度实验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/315831

相关文章

Java研学-RBAC权限控制(八)

九 登录登出 1 登录作用   判断员工是否有权限访问,首先得知道现在操作的人是谁,所以必须先实现登录功能 2 登录流程   ① 提供登录页面,可输入用户名与密码信息,并添加执行登录的按钮。(登录页面不能被拦截)   ② 给按钮绑定点击事件(异步操作,POST请求)   ③ 事件中发送登录请求,使用 AJAX 方式提交。(使用 AJAX 原因:用户体验更好,既可保留用户刚输入的用户名和密码

高性能并行计算华为云实验五:

目录 一、实验目的 二、实验说明 三、实验过程 3.1 创建PageRank源码 3.2 makefile的创建和编译 3.3 主机配置文件建立与运行监测 四、实验结果与分析 4.1 采用默认的节点数量及迭代次数进行测试 4.2 分析并行化下节点数量与耗时的变化规律 4.3 分析迭代次数与耗时的变化规律 五、实验思考与总结 5.1 实验思考 5.2 实验总结 E

ROS2从入门到精通4-4:局部控制插件开发案例(以PID算法为例)

目录 0 专栏介绍1 控制插件编写模板1.1 构造控制插件类1.2 注册并导出插件1.3 编译与使用插件 2 基于PID的路径跟踪原理3 控制插件开发案例(PID算法)常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。 🚀详情:《ROS2从入门到精通》 1 控制插

MQTT之CONNECT控制报文详解

目录 1.  MQTT协议规范 2.  名词解释 3.  CONNECT控制报文详解 3.1  固定报头 Fixed header 3.2  可变报头 Variable header 3.2.1  协议名 Protocol Name 3.2.2  协议级别 Protocol Level 3.2.3  连接标志 Connect Flags 3.2.4  保持连接 Keep

物联网系统运维——移动电商应用发布,Tomcat应用服务器,实验CentOS 7安装JDK与Tomcat,配置Tomcat Web管理界面

一.Tomcat应用服务器 1.Tomcat介绍 Tomcat是- -个免费的开源的Ser Ivet容器,它是Apache基金会的Jakarta 项目中的一个核心项目,由Apache, Sun和其他一 些公司及个人共同开发而成。Tomcat是一一个小型的轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。 在Tomcat中,应用程序的成部署很简

STM32HAL库--SDRAM实验(速记版)

STM32F429IGT6 自带了 256K 字节的 SRAM,对一般应用来说,已经足够了,不过在一些对内存要求高的场合, STM32F429 自带的这些内存就不够用了。比如使用 LTDC 驱动RGB 屏、跑算法或者跑 GUI 等,就可能不太够用,所以阿波罗 STM32F429 开发板板载了一颗 32M 字节容量的 SDRAM 芯片:W9825G6KH,满足大内存使用的需求。 1

STM32单片机PWR电源控制详解

文章目录 1. PWR概述 2. 电源结构框图 3. 上电复位和掉电复位 4. 可编程电压监测器 5. 低功耗模式 6. 模式选择 6.1 睡眠模式 6.2 停止模式 6.3 待机模式 7. 代码示例 1. PWR概述 PWR(Power Control)电源控制,负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能。 可编程电压监测器

轻松解决 linux平台 下编辑文档产生的 ^M 符号问题

一、^M:产生的原因:          windows平台下 使用“回车键”,则会在 行尾 产生 ^M 二、产生的后果:        在执行脚本时,shell解析器 会执行错误,弹出类似于:./XXXXX.sh: /bin/sh^M:bad interpreter:No such file or directory         ------解析器会将 末尾 带 ^M 的字段视为 文

基于动力学的六自由度机器人阻抗恒力跟踪控制

1.整个代码的控制流程图如下: 2.正逆运动学计算 略 3.动力学模型 采用拉格朗日法计算机械臂的动力学模型,其输入的是机械臂的关节角度、角速度和角加速度;其中M、C、G本别是计算的惯性力、科式力和重力项,相关部分如下: 4.RBF神经网络自适应参数调节 采用RBF自适应调节阻抗控制器参数,末端每个方向单独进行参数的调整,其中rbf的输入的是力和位置,输出的是阻抗控制器的参数,rb

芯片后端之 PT 使用 report_timing 产生报告如何阅读

今天,就PT常用的命令,做一个介绍,希望对大家以后的工作,起到帮助作用。 在PrimeTime中,使用report_timing -delay max命令生成此报告。switch -delay max表示定时报告用于设置(这是默认值)。 首先,我们整体看一下通过report_timing 运行之后,报告产生的整体样式。 pt_shell> report_timing -from start_