ARM32开发——LED驱动开发

2024-06-01 12:12
文章标签 led 开发 驱动 arm32

本文主要是介绍ARM32开发——LED驱动开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🎬 秋野酱:《个人主页》
🔥 个人专栏:《Java专栏》《Python专栏》

⛺️心若有所向往,何惧道阻且长

文章目录

    • 需求介绍
    • 现实问题
    • 需求分析
    • 测试案例构建
    • BSP驱动构建
    • 业务实现

需求介绍

在这里插入图片描述

开发版中有4个灯,现在需要用4个灯显示充电情况:

  1. 开始充电时,需要呈现出流水灯闪烁
  2. 4盏灯表示当前的电量
  3. 充电流水灯起始位置是当前电量,全部点亮后,再次从当前电量位置进入流水灯效果
  4. 结束充电时,关闭充电显示,当前电量进行闪烁3次,然后熄灭。
    在这里插入图片描述

现实问题

  1. 产品最终电路板还没画好,目前只有产品所使用的芯片对应的开发板。
  2. ADC功能是别人开发,还没完成。
  3. 老板要求,如果开发板好了,要尽快完成工作。

需求分析

要啥没啥,还得尽快完成。盘点手头有的东西,开发板。构建测试案例逻辑,方便后续移植。
测试案例设计:

  1. 准备工作,4个灯,3个按钮
  2. 按钮1按下时,模拟开始充电
  3. 按钮2按下时,模拟停止充电
  4. 按钮3按下时,模拟电量增加。
    如果测试方案通过,基本上功能完成,那么后续其他人工作完成后,只需要对接以下逻辑:
  5. 灯对应的引脚和最终设计的电路板引脚进行校准
  6. 开始充电
  7. 电量变化时,更新电量
  8. 结束充电

编码实现分析:

  1. 需要把4个灯作为一个业务逻辑整体,完成一套关于电池电量显示的驱动
  2. 需要抽象出业务逻辑,转换为函数实现

测试案例构建

在这里插入图片描述

● PC0作为:开始按钮
● PC1作为:停止按钮
● PC2作为:电量更新按钮
按钮逻辑构建

static void GPIO_config(){	// PD0	开始充电// PD1 	结束充电// PD5	电量变化// rcu时钟rcu_periph_clock_enable(RCU_GPIOD);// 配置GPIO模式gpio_mode_set(GPIOD,GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5);	
}

int main(void) {// 系统滴答定时器初始化systick_config();// GPIO初始化GPIO_config();// LED初始化Battery_led_init();FlagStatus pre_state0 = SET;// 默认高电平抬起FlagStatus pre_state1 = SET;// 默认高电平抬起FlagStatus pre_state2 = SET;// 默认高电平抬起uint32_t cnt = 0;uint8_t power = 1;while(1) {// PC0FlagStatus state0 = gpio_input_bit_get(GPIOC, GPIO_PIN_0);if (state0 != pre_state0){if(state0 == RESET){   // 当前低电平, 上一次为高电平,按下Battery_led_start(power);}pre_state0 = state0;	}// PC1FlagStatus state1 = gpio_input_bit_get(GPIOC, GPIO_PIN_1);if (state1 != pre_state1){if(state1 == RESET){   // 当前低电平, 上一次为高电平,按下Battery_led_stop();}pre_state1 = state1;	}// PC2FlagStatus state2 = gpio_input_bit_get(GPIOC, GPIO_PIN_2);if (state2 != pre_state2){if(state2 == RESET){   // 当前低电平, 上一次为高电平,按下//				Battery_led_turn_off(LED1);Battery_led_update(++power);}pre_state2 = state2;	}// 间隔50个10ms = 500ms执行一次led的状态更新if(++cnt % 50 == 0){Battery_led_loop();}delay_1ms(10);}}

BSP驱动构建

接口定义

  1. 驱动初始化,属于标配
  2. 业务相关的操作行为抽象化
  3. 时序问题
void Battery_led_int();

具体的业务抽象行为

void Battery_led_start(uint8_t power);
void Battery_led_stop();
void Battery_led_update(uint8_t power);

在涉及到需要控制时间的问题时,我们通常有以下做法:

  1. 自己主动调用 delay来进行延时
  2. 使用统一的延时,到达自己的时间点就去执行
    自己调用delay 不利于后续的移植。
    采用统一时钟,方便移植,也方便时间片统一调度管理

业务实现

  1. 采用bsp独立驱动进行开发
  2. 状态管理,通过status记录当前状态。
  3. 电量记录,记录当前电量。
  4. 充电闪烁计数,记录当前的闪烁的值。
#ifndef __BSP_BATTERY_LED_H__
#define __BSP_BATTERY_LED_H__#include "gd32f4xx.h"#define LED1	1
#define LED2	2
#define LED3	3
#define LED4	4void Battery_led_init();void Battery_led_turn_on(uint8_t led_index);void Battery_led_turn_off(uint8_t led_index);void Battery_led_turn(uint8_t led_index, uint8_t value);void Battery_led_start(uint8_t power);void Battery_led_loop();void Battery_led_update(uint8_t power);void Battery_led_stop();#endif
#include "bsp_battery_led.h"
#include "systick.h"// 声明gpio初始化所需参数的结构体
typedef struct {rcu_periph_enum rcu;uint32_t port;uint32_t pin;
} Led_GPIO_t;// 声明所有gpio对应参数的数组
Led_GPIO_t g_gpio_list[] = {{RCU_GPIOC, GPIOC, GPIO_PIN_6},        // LED_SW{RCU_GPIOD, GPIOD, GPIO_PIN_8},        // LED1{RCU_GPIOD, GPIOD, GPIO_PIN_9},        // LED2{RCU_GPIOD, GPIOD, GPIO_PIN_10},       // LED3{RCU_GPIOD, GPIOD, GPIO_PIN_11},       // LED4
};// 用于计算数组长度的宏
#define MAX_LED_COUNT	(sizeof(g_gpio_list) / sizeof(Led_GPIO_t))/*********************************************************** @brief LED GPIO初始化**********************************************************/
static void GPIO_config(rcu_periph_enum rcu, uint32_t port, uint32_t pin) {// 初始化为推挽输出模式rcu_periph_clock_enable(rcu);gpio_mode_set(port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, pin);gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, pin);
}void Battery_led_init() {uint8_t count = MAX_LED_COUNT;for(uint8_t i = 0; i < count; i++) {Led_GPIO_t gpio = g_gpio_list[i];// 初始化GPIO_config(gpio.rcu,gpio.port, gpio.pin);// 默认全部拉高(关闭)gpio_bit_write(gpio.port, gpio.pin, SET);}// 总开关拉低(打开)gpio_bit_write(g_gpio_list[0].port, g_gpio_list[0].pin, RESET);
}// 开灯
void Battery_led_turn_on(uint8_t led_index) {Led_GPIO_t gpio = g_gpio_list[led_index];gpio_bit_write(gpio.port, gpio.pin, RESET);
}// 关灯
void Battery_led_turn_off(uint8_t led_index) {Led_GPIO_t gpio = g_gpio_list[led_index];gpio_bit_write(gpio.port, gpio.pin, SET);
}/*********************************************************** @brief 设置灯亮灭* @param led_index LED索引* @param value 0亮,其他灭* @return**********************************************************/
void Battery_led_turn(uint8_t led_index, uint8_t value) {Led_GPIO_t gpio = g_gpio_list[led_index];gpio_bit_write(gpio.port, gpio.pin, value ? RESET : SET);
}int state = 0; // 0:停止, 1:充电中
uint8_t current_power = 0;
uint8_t show_power = 0;
/*********************************************************** @brief 开始充电流水灯* @param 当前电量[0,1,2,3,4]**********************************************************/
void Battery_led_start(uint8_t power) {current_power = power;show_power = current_power;state = 1;
}void Battery_led_loop() {if(state == 0) {Battery_led_turn_off(LED1);Battery_led_turn_off(LED2);Battery_led_turn_off(LED3);Battery_led_turn_off(LED4);} else if(state == 1) {Battery_led_turn(LED1, show_power >= 1);Battery_led_turn(LED2, show_power >= 2);Battery_led_turn(LED3, show_power >= 3);Battery_led_turn(LED4, show_power >= 4);if(++show_power > 4) show_power = current_power;}
}void Battery_led_update(uint8_t power) {current_power = power;
}void Battery_led_stop() {// 当前电量闪三次for( uint8_t i = 0; i < 3; i++) {// 关闭所有灯Battery_led_turn_off(LED1);Battery_led_turn_off(LED2);Battery_led_turn_off(LED3);Battery_led_turn_off(LED4);delay_1ms(200);// 根据当前电量闪灯Battery_led_turn(LED1, current_power >= 1);Battery_led_turn(LED2, current_power >= 2);Battery_led_turn(LED3, current_power >= 3);Battery_led_turn(LED4, current_power >= 4);delay_1ms(200);}state = 0;
}

这篇关于ARM32开发——LED驱动开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

使用Go语言开发一个命令行文件管理工具

《使用Go语言开发一个命令行文件管理工具》这篇文章主要为大家详细介绍了如何使用Go语言开发一款命令行文件管理工具,支持批量重命名,删除,创建,移动文件,需要的小伙伴可以了解下... 目录一、工具功能一览二、核心代码解析1. 主程序结构2. 批量重命名3. 批量删除4. 创建文件/目录5. 批量移动三、如何安