【STM32】編寫程序控制開發板的RGB LED燈

目錄

    • 1、原理圖
    • 2、文件結構
    • 3、使用寄存器模式點亮
      • 3.1、什么是寄存器
      • 3.2、寄存器開發的本質
      • 3.3、寄存器開發步驟
      • 3.4、主要源碼
        • 3.4.1、main.c
        • 3.4.2、drv_gpio.h
        • 3.4.3、drv_gpio.c
        • 3.4.4、使用BSRR和BRR影子寄存器優化`drv_gpio.c`
        • 3.4.5、效果演示
    • 4、使用標準庫模式點亮
      • 4.1、使用標準庫模式的好處
      • 4.2、主要源碼
        • 4.2.1、main.c
        • 4.2.2、drv_gpio.h
        • 4.2.3、drv_gpio.c
        • 4.2.4、效果演示多了白燈

1、原理圖

在這里插入圖片描述
如圖知,拉低為點亮

  • LED

    引腳狀態
    D3紅PB5輸出, 拉低為亮
    D3綠PB0輸出, 拉低為亮
    D3藍PB1輸出, 拉低為亮

2、文件結構

在這里插入圖片描述

3、使用寄存器模式點亮

3.1、什么是寄存器

寄存器是微控制器(MCU)內部的一種特殊存儲器,用于存儲配置參數、狀態信息或控制信號。每個寄存器通常有固定的地址,并且每一位或一組位對應特定的功能。

3.2、寄存器開發的本質

寄存器開發的本質是直接與硬件交互,繞過高級庫(如 HAL 庫或標準庫)的封裝,直接操作底層硬件。
STM32 的寄存器開發是通過直接讀寫寄存器來實現對外設的控制。

3.3、寄存器開發步驟

(1) 查找寄存器地址

  • 根據 STM32 的參考手冊(Reference Manual),找到目標外設的寄存器地址。
  • 每個外設(如 GPIO、TIMER、USART 等)都有一組寄存器,用于配置和控制其行為。

(2) 配置寄存器

  • 通過指針操作或直接訪問寄存器地址,向寄存器寫入特定的值,以配置外設的工作模式、中斷、時鐘等。

(3) 讀取寄存器

  • 通過讀取寄存器的值,獲取外設的狀態信息(如標志位、數據等)。

3.4、主要源碼

3.4.1、main.c
#include "drv_gpio.h"// SysTick 初始化
void SysTick_Init(void)
{SysTick->LOAD = 72000000 / 1000 - 1; // 1ms 延時SysTick->VAL = 0;					 // 清空當前值SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;
}// 精確延時函數(單位:ms)
void Delay_ms(uint32_t ms)
{for (uint32_t i = 0; i < ms; i++){while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));}
}int main()
{// 初始化 SysTickSysTick_Init();// 初始化 RGB LEDRGB_Init();while (1){RGB_RedOn();Delay_ms(500);  // 延時 500msRGB_RedOff();RGB_GreenOn();Delay_ms(500);  // 延時 500msRGB_GreenOff();RGB_BlueOn();Delay_ms(500);  // 延時 500msRGB_BlueOff();}
}
3.4.2、drv_gpio.h
#ifndef _DRV_GPIO_H_
#define _DRV_GPIO_H_//ARM提供的,有所有外設寄存器的信息
#include "stm32f10x.h"void RGB_Init(void);void RGB_RedOn(void);void RGB_RedOff(void);void RGB_GreenOn(void);void RGB_GreenOff(void);void RGB_BlueOn(void);void RGB_BlueOff(void);#endif
3.4.3、drv_gpio.c
#include "drv_gpio.h"void RGB_Init(void)
{// 1.配置RCCRCC->APB2ENR |= (1 << 3);// 2.配置PB5的功能// bit 20~23 全部置為0//  bit 20 置為1//pb5GPIOB->CRL &= (uint32_t)(~(0xF << 20));GPIOB->CRL |= (uint32_t)(1 << 20);  //配置為通用推挽輸出模式(0b0001)//pb0GPIOB->CRL &= (uint32_t)(~(0xF));GPIOB->CRL |= (uint32_t)(1);//pb1GPIOB->CRL &= (uint32_t)(~(0xF << 4));GPIOB->CRL |= (uint32_t)(1 << 4);  // 3.將pb5、pb0、pb1的初始值改為1,防止配置完就亮燈GPIOB->ODR |= (1 << 5);GPIOB->ODR |= 1;GPIOB->ODR |= (1 << 1);}void RGB_RedOn(void)
{// 3.拉低PB5對應的ODR寄存器地址GPIOB->ODR &= ~(1 << 5);
}void RGB_RedOff(void)
{GPIOB->ODR |= (1 << 5);
}void RGB_GreenOn(void)
{GPIOB->ODR &= ~(1);
}void RGB_GreenOff(void)
{GPIOB->ODR |= 1;
}void RGB_BlueOn(void)
{GPIOB->ODR &= ~(1 << 1);
}void RGB_BlueOff(void)
{GPIOB->ODR |= (1 << 1);
}
3.4.4、使用BSRR和BRR影子寄存器優化drv_gpio.c

由于對ODR直接操作, 可能有意無意修改到其他引腳的狀態

#include "drv_gpio.h"void RGB_Init(void)
{// 1.配置RCCRCC->APB2ENR |= (1 << 3);// 2.配置PB5的功能// bit 20~23 全部置為0//  bit 20 置為1//pb5GPIOB->CRL &= (uint32_t)(~(0xF << 20));GPIOB->CRL |= (uint32_t)(1 << 20);  //配置為通用推挽輸出模式(0b0001)//pb0GPIOB->CRL &= (uint32_t)(~(0xF));GPIOB->CRL |= (uint32_t)(1);//pb1GPIOB->CRL &= (uint32_t)(~(0xF << 4));GPIOB->CRL |= (uint32_t)(1 << 4);  // 3.將pb5、pb0、pb1的初始值改為1,防止配置完就亮燈GPIOB->ODR |= (1 << 5);GPIOB->ODR |= 1;GPIOB->ODR |= (1 << 1);}void RGB_RedOn(void)
{// 3.拉低PB5對應的ODR寄存器地址//GPIOB->ODR &= ~(1 << 5); GPIOB->BRR &= (1 << 5);// 直接將PB5拉低,同時不影響其他位
}void RGB_RedOff(void)
{//GPIOB->ODR |= (1 << 5);GPIOB->BSRR |= (1 << 5); //直接拉高,并不影響
}void RGB_GreenOn(void)
{//GPIOB->ODR &= ~(1);GPIOB->BRR &= (1);
}void RGB_GreenOff(void)
{//GPIOB->ODR |= 1;GPIOB->BSRR |= (1);
}void RGB_BlueOn(void)
{//GPIOB->ODR &= ~(1 << 1);GPIOB->BRR &= (1 << 1);
}void RGB_BlueOff(void)
{//GPIOB->ODR |= (1 << 1);GPIOB->BSRR |= (1 << 1);
}
3.4.5、效果演示

在這里插入圖片描述

4、使用標準庫模式點亮

4.1、使用標準庫模式的好處

標準庫封裝了底層寄存器的操作,提供了易于理解的API函數,開發者無需直接讀寫寄存器。

4.2、主要源碼

4.2.1、main.c
#include "drv_gpio.h"// SysTick 初始化
void SysTick_Init(void)
{SysTick->LOAD = 72000000 / 1000 - 1; // 1ms 延時SysTick->VAL = 0;					 // 清空當前值SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;
}// 精確延時函數(單位:ms)
void Delay_ms(uint32_t ms)
{for (uint32_t i = 0; i < ms; i++){while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));}
}int main()
{// 初始化 SysTickSysTick_Init();// 初始化 RGB LEDRGB_Init();while (1){RGB_RedOn();Delay_ms(500);  // 延時 500msRGB_RedOff();RGB_GreenOn();Delay_ms(500);  // 延時 500msRGB_GreenOff();RGB_BlueOn();Delay_ms(500);  // 延時 500msRGB_BlueOff();RGB_WriteOn();Delay_ms(500);  // 延時 500msRGB_WriteOff();}
}
4.2.2、drv_gpio.h
#ifndef _DRV_GPIO_H_
#define _DRV_GPIO_H_//使用gpio標準庫
#include "stm32f10x_gpio.h"#define RGB_Port GPIOB
#define RGB_Pin_R GPIO_Pin_5
#define RGB_Pin_G GPIO_Pin_0
#define RGB_Pin_B GPIO_Pin_1void RGB_Init(void);void RGB_RedOn(void);void RGB_RedOff(void);void RGB_GreenOn(void);void RGB_GreenOff(void);void RGB_BlueOn(void);void RGB_BlueOff(void);void RGB_WriteOn(void);void RGB_WriteOff(void);#endif
4.2.3、drv_gpio.c
#include "drv_gpio.h"void RGB_Init(void)
{// 1.RCC配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 2、配置紅、綠、藍燈輸出GPIO_InitTypeDef gpio_initStruct = {0};gpio_initStruct.GPIO_Pin = RGB_Pin_R | RGB_Pin_G | RGB_Pin_B;gpio_initStruct.GPIO_Speed = GPIO_Speed_50MHz;gpio_initStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(RGB_Port, &gpio_initStruct);GPIO_SetBits(RGB_Port, RGB_Pin_R | RGB_Pin_G | RGB_Pin_B);
}void RGB_RedOn(void)
{// 3.拉低PB5對應的ODR寄存器地址GPIO_ResetBits(RGB_Port, RGB_Pin_R);
}void RGB_RedOff(void)
{GPIO_SetBits(RGB_Port, RGB_Pin_R);
}void RGB_GreenOn(void)
{GPIO_ResetBits(RGB_Port, RGB_Pin_G);
}void RGB_GreenOff(void)
{GPIO_SetBits(RGB_Port, RGB_Pin_G);
}void RGB_BlueOn(void)
{GPIO_ResetBits(RGB_Port, RGB_Pin_B);
}void RGB_BlueOff(void)
{GPIO_SetBits(RGB_Port, RGB_Pin_B);
}void RGB_WriteOn(void)
{GPIO_ResetBits(RGB_Port, RGB_Pin_R | RGB_Pin_G | RGB_Pin_B);
}void RGB_WriteOff(void)
{GPIO_SetBits(RGB_Port, RGB_Pin_R | RGB_Pin_G | RGB_Pin_B);
}
4.2.4、效果演示多了白燈

在這里插入圖片描述

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

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

相關文章

MyBatis-Plus 的加載及初始化

在 Spring Boot 啟動過程中&#xff0c;MyBatis-Plus 的加載和初始化涉及多個階段的工作。這些工作包括 MyBatis-Plus 自身的配置解析、Mapper 接口的掃描與注冊、SQL 語句的動態注入以及底層 MyBatis 的初始化等。以下是對整個過程的詳細分析&#xff1a; 1. Spring Boot 啟動…

SpringBoot中安全的設置阿里云日志SLS的accessKey

眾所周知,阿里云的服務都是基于accesskeyId和accesskeySecret來進行身份鑒權的,但唯獨日志因為需要寫入到.xml文件里對于accesskeyId和accesskeySecret需要進行一定程度的改進,尤其是使用了jasypt進行加密的參數傳遞進去logback.xml更是會遇到需要對參數進行解密的問題,而官網只…

關于解決Ubuntu終端及系統字體大小的問題

在Ubuntu中調整終端和系統字體大小可以通過以下方法&#xff08;可能不僅僅只是這幾種&#xff09;實現&#xff1a; 1. 調整系統字體大小 打開終端并輸入以下命令&#xff0c;安裝GNOME Tweaks&#xff0c;等待安裝完成&#xff1a; sudo apt install gnome-tweaks 接著進行…

Rust vs. Go: 性能測試(2025)

本內容是對知名性能評測博主 Anton Putra Rust vs. Go (Golang): Performance 2025 內容的翻譯與整理, 有適當刪減, 相關數據和結論以原作結論為準。 再次對比 Rust 和 Go&#xff0c;但這次我們使用的是最具性能優勢的 HTTP 服務器庫---Hyper&#xff0c;它基于 Tokio 異步運…

【NLP 48、大語言模型的神秘力量 —— ICL:in context learning】

目錄 一、ICL的優勢 1.傳統做法 2.ICL做法 二、ICL的發展 三、ICL成因的兩種看法 1.meta learning 2.Bayesian Inference 四、ICL要點 ① 語言模型的規模 ② 提示詞prompt中提供的examples數量和順序 ③ 提示詞prompt的形式&#xff08;format&#xff09; 五、fine-tune VS I…

兩數之和解題記錄

開始打算用一個數組保存差值&#xff0c;arr[target-nums[i]] i, 只要arr[nums[i]]有內容就能滿足target&#xff0c;返回arr[nums[i]]和i。但是會出現復數的情況&#xff0c;所以換成map。 換成map就只用一邊遍歷&#xff0c;一遍檢查和存入對應key就行了&#xff0c;value就…

P1722 矩陣Ⅱ - 洛谷

題源&#xff1a;P1722 矩陣 II - 洛谷 看了題目之后&#xff0c;需要注意的是&#xff1a; ①在1 ~ i 個格子中紅色數量 > 黑色數量 ②最后&#xff0c;在2 * n 個格子中&#xff0c;紅色數量 黑色數量 根據這兩個約束條件&#xff0c;可以知道&#xff0c;第一個格…

數據庫——MySQL基礎操作

一、表結構與初始數據 假設存在以下兩張表&#xff1a; 1. student 表 字段名數據類型描述idINT學生唯一標識符nameVARCHAR(100)學生姓名ageINT學生年齡sexVARCHAR(10)學生性別 初始數據&#xff1a; idnameagesex1張三20男2李四22女3王五21男 2. course 表 字段名數據類…

行業白皮書2025 | 益企研究院:AI時代的存儲基石

在當今科技飛速發展的時代&#xff0c;AI技術已成為推動各行業變革的關鍵力量。日前&#xff0c;益企研究院重磅發布《AI時代的存儲基石》白皮書。 下載方式&#xff1a;關注“渡江客涂鴉板”&#xff0c;回復st250326獲取免費下載地址 數據需求與技術挑戰&#xff1a; AI技術…

音視頻新人如何快速上手nginx-rtmp-module

一、整體設計架構 nginx-rtmp-module 是 Nginx 的一個擴展模塊&#xff0c;專門為 Nginx 添加了對 RTMP 協議的支持。其核心功能包括&#xff1a; RTMP推流&#xff08;publish&#xff09; RTMP拉流&#xff08;play&#xff09; 流轉發&#xff08;relay&#xff09; 流錄…

vue 封裝 Axios菜鳥教程

1、Axios依賴下載 $ npm install axios 2、以下鏈接為Axios 的api Axios 實例 | Axios中文文檔 | Axios中文網 3、 項目新建request.js&#xff0c;文件名稱按照駝峰命名法就可以 4、封裝request.js代碼如下 import axios from "axios"//創建axios實例&#xff0…

[項目]基于FreeRTOS的STM32四軸飛行器: 十一.MPU6050配置與讀取

基于FreeRTOS的STM32四軸飛行器: 十一.MPU6050 一.芯片介紹二.配置I2C三.編寫驅動四.讀取任務的測試五.MPU6050六軸數據的校準 一.芯片介紹 芯片應該放置在PCB中間&#xff0c;X Y軸原點&#xff0c;敏感度131表示范圍越小越靈敏。理想狀態放置在地面上X&#xff0c;Y&#xf…

iOS常見網絡框架

URLSession、Alamofire 和 Moya 1. URLSession 1.1 核心概念 URLSession 是 Apple 官方提供的網絡請求 API&#xff0c;封裝在 Foundation 框架中。它支持 HTTP、HTTPS、FTP 等協議&#xff0c;可用于&#xff1a; ? ? 普通網絡請求&#xff08;GET/POST&#xff09; ? …

AOA(到達角度)與TOA(到達時間)兩個技術的混合定位,MATLAB例程,自適應基站數量,三維空間下的運動軌跡,濾波使用UKF(無跡卡爾曼濾波)

本文介紹一個MATLAB代碼,實現了三維動態目標非線性定位與濾波系統,通過融合 到達角(AOA) 和 到達時間(TOA) 的混合定位方法,結合 無跡卡爾曼濾波(UKF) 處理非線性觀測模型,優化軌跡精度。代碼支持自適應基站數量配置,適用于復雜非線性場景的定位研究。 文章目錄 運行…

Ubuntu 重置密碼方法

目錄 修改過 root 密碼&#xff0c;重置密碼的方法沒改過 root 密碼?&#xff0c;重置密碼的方法 修改過 root 密碼&#xff0c;重置密碼的方法 Ubuntu 默認禁用root用戶&#xff0c;意思就是安裝好Ubuntu系統后&#xff0c;root用戶默認是沒有密碼的&#xff0c;普通用戶通過…

Leetcode 路徑總和 III

java 解法一&#xff1a;雙遞歸 class Solution {public int pathSum(TreeNode root, long targetSum) { //外層遞歸,把每個節點都當作路徑起點if(root null) return 0;int ret rootSum(root, targetSum);ret pathSum(root.left, targetSum);ret pathSum(root.right, targ…

WEB安全--SQL注入--利用log寫入webshell

一、原理&#xff1a; 這也是對之前文章的補充&#xff1a;WEB安全--SQL注入--INTO OUTFILE-CSDN博客 我們可以通過修改MySQL的log文件&#xff0c;用select關鍵字寫入木馬文件放在服務器物理地址中&#xff0c;通過訪問物理地址getshell。 二、條件&#xff1a; 用戶有寫入權限…

C++11中引入的比較常用的新特性講解(上)

目錄 1、C11簡介 2、統一的列表初始化 2.1、&#xff5b;&#xff5d;初始化 2.2、std::initializer_list 3、變量類型推導 3.1、auto 3.2、decltype 3.3、nullptr 4、范圍for循環 5、STL中一些變化 6、右值引用和移動語義 6.1、左值引用和右值引用 6.2、右值引用…

hugo+github pages 部署實驗室網站

&#xff01;&#xff01;太爽了&#xff0c;看了很久教程&#xff0c;自己試了好久&#xff0c;終于搞懂怎么把hugo和public單獨進行部署了&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 目的是什么&#xff1f;目的當然是為了修改這天殺的hugo的模板。現在…

兩頭文件互引問題解決(前置聲明)

問題&#xff1a; 想必正在基礎階段學習的朋友們都遇見過以下問題吧 widget.h otherwidget.h 如上問題是&#xff0c;我在widget.h中引用了otherwidget.h ,在ohterwidget中又引用了widget.h&#xff0c;兩個頭文件互相引用產生了報錯 解決辦法&#xff1a; 那么我們該如何解…