当前位置: 首页 > news >正文

基于HAL库实现GPIO输出状态控制输入状态查询及定时器PWM波和串口收发数据

1.基于HAL库实现GPIO输出状态控制

        相对于标准库的GPIO输出状态控制,HAL库在结合了CubeMX软件后实现GPIO输出状态控制更加简单,一些基本的配置由CubeMX帮助我们完成,且对GPIO输出状态的控制也有相应库函数的实现。我们用三个外部器件LED,BEEP和继电器来展示控制GPIO引脚的电平变化。以控制LED灯为例,我们看CubeMX配置和程序实现。

void LED_Control(uint8_t device,uint8_t cmd);
void LED_Test(void);**
*@brief 控制LED1 LED2 亮灭的函数
*
*@note 详细描述细节,ON 用来控制led亮, OFF用来控制LED熄灭
*
*@param device: 可以是LED1, LED2 , 是两个宏,定义在gpio.h中
*
*@param cmd: 用来控制LED的亮灭命令
*				ON : 点亮LED
*				OFF :熄灭LED
*
*@retval None
*/
void LED_Control(uint8_t device,uint8_t cmd)
{if(device == LED1){if(cmd == ON){HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);}else if(cmd == OFF){HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);}}else if(device == LED2){if(cmd == ON){HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);}else if(cmd == OFF){HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);}}
}/**
* @brief LED1 LED2 测试函数
*
* @note 验证LED1 LED2的功能
*
* @retval None
*/
void LED_Test(void)
{LED_Control(LED1,ON);LED_Control(LED2,OFF);HAL_Delay(500);LED_Control(LED1,OFF);LED_Control(LED2,ON);HAL_Delay(500);
}

采用函数封装,对外接口来实现功能模块化。对于该功能的实现,我们可以看到主要依赖于HAL库中的函数HAL_GPIO_WritePin来实现,该函数的功能就是对相应GPIO口的高低电平状态进行设置。

2.基于HAL库实现GPIO输入状态的读取

        对于GPIO输入状态的读取,同样HAL都有相应的函数来实现,这里我们用其对按键是否按下进行轮询读取,下面时CubeMX配置和程序实现:

#define 	LED1 				1
#define 	LED2 				2
#define 	ON   				1
#define 	OFF  				0
#define 	KEY_UP  		    1
#define 	KEY_DOWN  	        2
#define 	KEY_LEFT  	        3
#define 	KEY_RIGHT           4
#define 	KEY_OK  		    5
#define 	KEY_ESC  		    6uint8_t KEY_Scan(void);
void KEY_Test(void);/**
*@brief 获取键值的函数
*
*@param None
*
*@retval 按键的键值,没有按键按下时返回0
*/
uint8_t KEY_Scan(void)
{if(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port,KEY_UP_Pin) == GPIO_PIN_RESET){return KEY_UP;}else if(HAL_GPIO_ReadPin(KEY_DOWN_GPIO_Port,KEY_DOWN_Pin) == GPIO_PIN_RESET){return KEY_DOWN;}else if(HAL_GPIO_ReadPin(KEY_LEFT_GPIO_Port,KEY_LEFT_Pin) == GPIO_PIN_RESET){return KEY_LEFT;}else if(HAL_GPIO_ReadPin(KEY_RIGHT_GPIO_Port,KEY_RIGHT_Pin) == GPIO_PIN_RESET){return KEY_RIGHT;}else if(HAL_GPIO_ReadPin(KEY_OK_GPIO_Port,KEY_OK_Pin) == GPIO_PIN_RESET){return KEY_OK;}else if(HAL_GPIO_ReadPin(KEY_ESC_GPIO_Port,KEY_ESC_Pin) == GPIO_PIN_RESET){return KEY_ESC;}return 0;
}/**
* @brief 按键测试函数
*
* @note 验证按键的功能
*
* @retval None
*/
void KEY_Test(void)
{if(KEY_Scan() == KEY_UP){LED_Control(LED1,ON);}else if(KEY_Scan() == KEY_DOWN){LED_Control(LED1,OFF);}else if(KEY_Scan() == KEY_LEFT){LED_Control(LED2,ON);}else if(KEY_Scan() == KEY_RIGHT){LED_Control(LED2,OFF);}else if(KEY_Scan() == KEY_OK){BEEP_Control(ON);}else if(KEY_Scan() == KEY_ESC){BEEP_Control(OFF);}
}

在CubeMX中时钟树的配置与GPIO输出电平状态控制一样,将GPIO配置为上拉输入即可,程序依旧采用模块化编写,在.c文件时实现底层逻辑,.h文件中对外公开接口。由以上程序可见读取GPIO口状态主要由HAL_GPIO_ReadPin函数实现,该函数的功能就是读出相应IO口的电平状态。

3.基于HAL库实现PWM

        下面来看实现该功能的CubeMX配置和程序,

        

在main函数中需要对PWM波的最初占空比进行初始化和开始PWM波,程序如下:

__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3,100);  __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4,100);HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);

在外部中断回调函数中,实现按键按下对PWM波占空比的调节。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == KEY_UP_Pin){//LED_Control(LED1,ON);__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3,0);  __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4,0);}else if(GPIO_Pin == KEY_DOWN_Pin){//LED_Control(LED1,OFF);__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3,20);  __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4,20);}else if(GPIO_Pin == KEY_LEFT_Pin){//LED_Control(LED2,ON);__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3,40);  __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4,40);}else if(GPIO_Pin == KEY_RIGHT_Pin){//LED_Control(LED2,OFF);__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3,60);  __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4,60);}else if(GPIO_Pin == KEY_OK_Pin){//BEEP_Control(ON);__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3,80);  __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4,80);}else if(GPIO_Pin == KEY_ESC_Pin){//BEEP_Control(OFF);__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3,100);  __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4,100);}
}

可见在实现该功能时主要用到了函数__HAL_TIM_SET_COMPARE该函数的功能就是设置相应定时器相应通道的PWM波占空比,HAL_TIM_PWM_Start该函数的功能就是开启PWM波的产生。

4.基于HAL库实现串口数据的收发

        对于串口数据的收发有很多种方式,如轮询式,中断式,DMA式,接收数据有定长和不定长,这里我们就实现采用DMA中断接收不定长数据然后阻塞式发送数据。

//DMA接收一半中断
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){uint8_t Length = DMA_BUF_SIZE/2 - RX1_Offset;HAL_UART_Transmit(&huart1,RX1_Buf+RX1_Offset,Length,HAL_MAX_DELAY);printf("HLength=%d\n",Length);RX1_Offset+=Length;}
}//DMA接收满中断
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){uint8_t Length = DMA_BUF_SIZE - RX1_Offset;HAL_UART_Transmit(&huart1,RX1_Buf+RX1_Offset,Length,HAL_MAX_DELAY);printf("CLength=%d\n",Length);RX1_Offset = 0;}
}void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)!=RESET)   //判断是否发生空闲中断{__HAL_UART_CLEAR_IDLEFLAG(huart);                    //清空空闲中断标志位 uint8_t Length = DMA_BUF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx) - RX1_Offset;   //接收到的数据的长度HAL_UART_Transmit(&huart1,RX1_Buf+RX1_Offset,Length,HAL_MAX_DELAY);RX1_Offset += Length;printf("ILength=%d\n",Length);}}
}

可见其主要的函数有HAL_UART_RxHalfCpltCallback该函数是一个回调函数,在串口使用DMA模式接收数据下,接收数据完成一半时会执行该函数。HAL_UART_RxCpltCallback该函数也是一个回调函数,在串口使用DMA模式接收数据下,接收数据完成全部时会执行该函数。HAL_UART_Transmit该函数的为串口发送数据函数,采用的是阻塞机制发送数据只有将要发送的数据全部发送完成程序才会继续执行,__HAL_UART_GET_FLAG该函数的功能是读取相应标志位,在上面的程序中为读取接收空闲中断标志位,若读取到该标志位返回SET,没有读取到返回RESET,__HAL_DMA_GET_COUNTER是一个宏函数,在程序中的功能是读取接收缓冲区中还剩下多少字节空间。

http://www.dtcms.com/a/573640.html

相关文章:

  • 免费html网站哪里有广告设计培训机构
  • mysql三范式
  • RTOS多任务调度在西门子智能交通信号控制系统中的深度实践与优化
  • 【1】视觉SLAM的数学表达
  • Nginx高可用配置实战:负载均衡 + 健康检查 + 动态扩展
  • 邵阳建设银行网站是多少钱企业微信crm
  • 神经网络常见操作
  • GitCode 源启高校|北京邮电大学站:解锁开源力量,启航信息新航道
  • Hibernate之helloworld 案例
  • 建立企业网站的详细步骤爱站云网站建设heikw
  • SSM框架题库
  • 电子基础】逻辑器件全解析:从门电路到FPGA,选型与应用指南
  • 龙岩网站建设平台手机创建自己网站
  • 人工智能学习中深度学习之python基础之 类
  • K8s/Kubernetes(v1.23.17)三节点集群部署全过程的总结与问题回顾
  • 调试oracle函数性能(嵌入存储过程)
  • React 元素渲染
  • 个人开发者短信验证码接入指南-阿里云
  • 移动端优秀网站上海传媒公司名字
  • 建设一个网站的需求分析一个网站开发流程
  • PsPasswd(7.19):远程修改密码的边界与合规建议
  • 【钉钉多元表格(自动化)】钉钉群根据表格 自动推送当天值日生信息
  • LangFlow源码深度解析:Component核心机制与生态体系
  • dede织梦仿站网站建设做网站赚谁的钱
  • DropLoRA技术详解:克服大模型微调过拟合的创新方法
  • 【剑斩OFFER】算法的暴力美学——串联所有单词的字串
  • 学习Linux——进程管理
  • 在k8s中部署seaweedfs,上传文件到seaweedfs方法
  • 极氪与火山引擎深化合作,Data Agent赋能车辆数据管理效率
  • Kotlin 使用命令行编译