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;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20181.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20181.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20181.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

618大促有哪些好物是最值得入手的的?請收下這份618必買好物清單!

最近聊的最多的話題就是618&#xff0c;年中購物大狂歡馬上來了&#xff01;&#xff01;今天整理了一下之前購買的好物&#xff0c;發現相比之前的價格真的是太劃算了&#xff0c;趕緊分享出來給大家&#xff0c;趁著這個大促趕緊多存入手~ 推薦1、南卡Neo 2——不傷耳黑科技…

SPHINX的輸出文檔格式

SPHINX的輸出文檔格式 SPHINX的輸出文檔格式更多信息 SPHINX的輸出文檔格式 用rst編寫&#xff0c;然后用sphinx-build進行編譯&#xff0c;還是效果相當不錯地&#xff0c;只要掌握了格式&#xff0c;可以一次編譯&#xff0c;多種格式輸出&#xff0c;主要是用的可能是html和…

記一次netty客戶端的開發

背景 近日要開發一個tcp客戶端程序去對接上游廠商的數據源&#xff0c;決定使用netty去處理&#xff0c;由于很久沒有開發過netty了&#xff0c;順便學習記錄下 netty搭建 考慮到我們需要多個client去對接server服務&#xff0c;所以我們定義一個公共的AbstractNettyClient父…

機器學習:人工智能中實現自動化決策與精細優化的核心驅動力

機器學習在人工智能中確實扮演著實現自動化決策與精細優化的核心驅動力角色。以下是關于這一點的詳細分析: 一、機器學習在自動化決策中的應用 數據驅動:機器學習依賴于大量的數據來進行模型訓練和評估,從而確保決策的準確性。通過自動化數據分析和處理,機器學習能夠從海量…

LabVIEW與Arm控制器之間的通訊

LabVIEW是一個強大的圖形化編程環境&#xff0c;廣泛應用于自動化控制、數據采集和測試測量等領域。而Arm控制器則是嵌入式系統中常用的處理器架構&#xff0c;廣泛用于各種控制和計算任務。將LabVIEW與Arm控制器進行通訊控制&#xff0c;可以結合二者的優勢&#xff0c;實現高…

vue3 中可緩存的方法

場景&#xff1a;在列表中&#xff0c;有這么一個屬性&#xff0c;需要通過同行的其他屬性&#xff0c;進行復雜的計算&#xff0c;才能得出&#xff0c;如果我們用方法&#xff0c;然后傳參&#xff0c;得到這個屬性&#xff0c;那么每次更改列表后&#xff0c;每行都會重新計…

WordPress plugin MStore API SQL注入漏洞復現(CVE-2023-3077)

0x01 產品簡介 WordPress和WordPress plugin都是WordPress基金會的產品。WordPress是一套使用PHP語言開發的博客平臺。該平臺支持在PHP和MySQL的服務器上架設個人博客網站。WordPress plugin是一個應用插件。 0x02 漏洞概述 WordPress plugin MStore API 3.9.8 版本之前存在S…

Linux 深入講解自動化構建工具

各位大佬好 &#xff0c;這里是阿川的博客 &#xff0c; 祝您變得更強 個人主頁&#xff1a;在線OJ的阿川 大佬的支持和鼓勵&#xff0c;將是我成長路上最大的動力 阿川水平有限&#xff0c;如有錯誤&#xff0c;歡迎大佬指正 Linux一系列的文章&#xff08;質量分均在93分…

配置arduino和ESP8266

首先準備好arduino 的IDE和ESP8266的驅動以及板子 1.安裝驅動&#xff0c;雙擊x64的版本驅動&#xff0c;安裝好以后&#xff0c;在資源管理器檢查端口&#xff0c;比如下下圖出現的COM4就是esp8266所使用的端口 2.安裝好arduino最好不要在路徑中存在中文符號&#xff0c;打開…

水滴式粉碎機:多功能飼料粉碎設備

飼料粉碎機是一種專門用于將各種飼料原料進行粉碎處理的機械設備。無論是玉米、小麥等谷物&#xff0c;還是豆粕、魚粉等動物性原料&#xff0c;甚至是一些粗纖維含量較高的秸稈、牧草等&#xff0c;都可以經過飼料粉碎機的處理&#xff0c;變成適合畜禽消化吸收的精細飼料。這…

521源碼-游戲源碼-2024卡牌回合自走棋手游《夢間集》推出全新Linux手工服務端

首款稀有卡牌回合自走棋手游《夢間集》推出全新Linux手工服務端整理 更多網站源碼&#xff0c;游戲源碼&#xff0c;學習教程&#xff0c;請點擊&#x1f449;-521源碼-&#x1f448;獲取最新資源 本游戲下載地址&#xff1a;2024卡牌回合自走棋手游《夢間集》推出全新Linux手…

【再探】設計模式—中介者模式、觀察者模式及模板方法模式

中介者模式讓多對多的復雜引用關系變成一對多&#xff0c;同時能通過中間類來封裝多個類中的行為&#xff0c;觀察者模式在目標狀態更新時能自動通知給訂閱者&#xff0c;模版方法模式則是控制方法的執行順序&#xff0c;子類在不改變算法的結構基礎上可以擴展功能實現。 1 中…

003 MySQL

文章目錄 左外連接、右外連接 的區別where/having的區別執行順序聚合 聚合函數MySQL約束事務一致性一致性的含義一致性在事務中的作用如何維護一致性 存儲引擎 Innodb MyIsam區別事務的ACID屬性數據庫的隔離級別MySQL中的并發問題1. 鎖等待和死鎖2. 并發沖突3. 臟讀、不可重復讀…

理解接口回調及其在 RabbitMQ 中的實際運用

介紹 接口回調是一種常見的編程模式&#xff0c;它在異步編程中發揮著重要作用。本文將通過一個簡單的示例介紹接口回調的概念和原理&#xff0c;并探討它在 RabbitMQ 中的實際應用。 接口回調的概念 接口回調是一種編程模式&#xff0c;用于在異步編程中實現回調機制。它允許…

ChatGPT AI專題資料合集【65GB】

介紹 ChatGPT & AI專題資料合集【65GB】 &#x1f381;【七七云享】資源倉庫&#xff0c;海量資源&#xff0c;無償分享√

stm32和esp32硬件資源上有什么區別 哪個更適合初學者

對于初學者來說&#xff0c;ESP32和STM32都有各自的優點和適用場景&#xff0c;但通常ESP32被認為是更適合初學者的選擇&#xff0c;原因如下&#xff1a; 內置無線通信&#xff1a;ESP32集成了WiFi和藍牙功能&#xff0c;這意味著初學者可以更容易地構建無線通信應用&#xff…

文件系統小冊(FusePosixK8s csi)【1 Fuse】

文件系統小冊&#xff08;Fuse&Posix&K8s csi&#xff09;【1 Fuse&#xff1a;用戶空間的文件系統】 Fuse(filesystem in userspace),是一個用戶空間的文件系統。通過fuse內核模塊的支持&#xff0c;開發者只需要根據fuse提供的接口實現具體的文件操作就可以實現一個文…

【測評|白嫖】雨云寧波新區,2C4G200M,公測期間全免費!

雨云香港三區云服務器&#xff0c;高性能的 Xeon Platinum 處理器 企業級 NVME SSD 高性能云服務器。 一鍵白嫖鏈接&#xff1a;https://www.rainyun.com 本篇純測評&#xff0c;無任何廣告&#xff0c;請放心食用&#xff01;&#xff01; 本次測評服務器配置如下&#xff1…

用萬界星空科技低代碼平臺能快速搭建一個云MES系統

一、低代碼平臺與MES:智能制造的新篇章 隨著工業4.0和智能制造的興起&#xff0c;企業對于生產過程的數字化、智能化需求日益迫切。傳統的MES系統實施周期長、成本高&#xff0c;成為許多企業數字化轉型的瓶頸。而低代碼開發平臺的出現為這一問題提供了新的解決思路。 二、萬界…

linux可觀測性ebpf(一) ----------- 環境搭建

參考書籍 開發環境 Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-150-generic x86_64) 1.1 下載內核源碼 cd /usr/src/ sudo git clone -b v5.4 https://github.com/torvalds/linux.git1.2 下載書中代碼 git clone https://github.com/bpftools/linux-observability-with-bpf1.3 編…