STM32F4_HAL控制GPIO輸出——跑馬燈實驗

1、GPIO工作模式

1.1 端口輸入數據寄存器(IDR)

1.2?端口輸出數據寄存器(ODR)

1.3 端口置位/復位寄存器(BSRR)

????????為什么有了 ODR 寄存器,還要這個 BSRR 寄存器呢?我們先看看 BSRR 的寄存器描述,首先 BSRR 是只寫權限,而 ODR 是可讀可寫權限。 BSRR 寄存器 32 位有效,對于低 16 位(0- 15),我們往相應的位寫 1(BSy=1),那么對應的 IO 口會輸出高電平,往相應的位寫 0(BSy=0),對 IO 口沒有任何影響,高 16 位(16-31)作用剛好相反,對相應的位寫 1(BRy=1)會輸出低電平,寫 0(BRy=0)沒有任何影響, y=0~15。

????????也就是說,對于 BSRR 寄存器,你寫 0 的話,對 IO 口電平是沒有任何影響的。我們要設置某個 IO 口電平,只需要相關位設置為 1 即可。而 ODR 寄存器,我們要設置某個 IO 口電平,我們首先需要讀出來 ODR 寄存器的值,然后對整個 ODR 寄存器重新賦值來達到設置某個或者某些 IO 口的目的,而 BSRR 寄存器,我們就不需要先讀,而是直接設置即可,這在多任務實時操作系統中作用很大。 BSRR 寄存器還有一個好處,就是 BSRR 寄存器改變引腳狀態的時候,不會被中斷打斷,而 ODR 寄存器有被中斷打斷的風險。

2、硬件設計

要使用一個外設,首先要進行初始化,hal庫初始化函數為:

void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);

形參1為端口號,形參2為結構體變量,結構體如下:

typedef struct
{
uint32_t Pin; /* 引腳號 */
uint32_t Mode; /* 模式設置 */
uint32_t Pull; /* 上拉下拉設置 */
uint32_t Speed; /* 速度設置 */
uint32_t Alternate; /* 復用功能 */
} GPIO_InitTypeDef;

GPIO寫函數:

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx,
uint16_t GPIO_Pin,
GPIO_PinState PinState);

形參1為端口號,形參2為引腳號,形參3為輸出狀態。

GPIO電平翻轉函數:

void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);

形參1為端口號,形參2為引腳號。

要進行輸出配置,首先使能對應的GPIO時鐘再進行初始化配置。再通過寫函數控制GPIO輸出高低電平。

3、軟件設計

流程圖

?led.h

#ifndef __LED_H
#define __LED_H#include "./SYSTEM/sys/sys.h"/******************************************************************************************/
/* 引腳 定義 */#define LED0_GPIO_PORT                  GPIOF
#define LED0_GPIO_PIN                   GPIO_PIN_9
#define LED0_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0)             /* PF口時鐘使能 */#define LED1_GPIO_PORT                  GPIOF
#define LED1_GPIO_PIN                   GPIO_PIN_10
#define LED1_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0)             /* PF口時鐘使能 *//******************************************************************************************//* LED端口定義 */
#define LED0(x)   do{ x ? \HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \}while(0)       /* LED0 = RED */#define LED1(x)   do{ x ? \HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \}while(0)       /* LED1 = GREEN *//* LED取反定義 */
#define LED0_TOGGLE()    do{ HAL_GPIO_TogglePin(LED0_GPIO_PORT, LED0_GPIO_PIN); }while(0)       /* LED0 = !LED0 */
#define LED1_TOGGLE()    do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0)       /* LED1 = !LED1 *//******************************************************************************************/
/* 外部接口函數*/
void led_init(void);                                                                            /* 初始化 */#endif

led.c

#include "./BSP/LED/led.h"/*** @brief       初始化LED相關IO口, 并使能時鐘* @param       無* @retval      無*/
void led_init(void)
{GPIO_InitTypeDef gpio_init_struct;LED0_GPIO_CLK_ENABLE();                                 /* LED0時鐘使能 */LED1_GPIO_CLK_ENABLE();                                 /* LED1時鐘使能 */gpio_init_struct.Pin = LED0_GPIO_PIN;                   /* LED0引腳 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽輸出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(LED0_GPIO_PORT, &gpio_init_struct);       /* 初始化LED0引腳 */gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引腳 */HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引腳 */LED0(1);                                                /* 關閉 LED0 */LED1(1);                                                /* 關閉 LED1 */
}

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"int main(void)
{HAL_Init();                                 /* 初始化HAL庫 */sys_stm32_clock_init(336, 8, 2, 7);         /* 設置時鐘,168Mhz */delay_init(168);                            /* 延時初始化 */led_init();                                 /* 初始化LED */while(1){LED0(0);                                /* LED0 亮 */LED1(1);                                /* LED1 滅 */delay_ms(500);LED0(1);                                /* LED0 滅 */LED1(0);                                /* LED1 亮 */delay_ms(500);}
}

本實驗源碼來自正點原子探索者開發板HAL庫跑馬燈例程。重點不是點燈,點燈很簡單,主要是理解STM32如何控制GPIO進行輸出高低電平。

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

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

相關文章

23種設計模式(持續輸出中)

一.設計模式的作用 設計模式是軟件從業人員長期總結出來用于解決特定問題的通用性框架,它提高了代碼的可維護性、可擴展性、可讀性以及復用性。 二.設計模式 1.工廠模式 工廠模式提供了創建對象的接口,而無需制定創建對象的具體類,工廠類…

hive表在HDFS的每個文件的大小加大

配置參數: spark.hadoop.hive.exec.orc.default.stripe.size78643200 spark.hadoop.orc.stripe.size78643200 spark.hadoopRDD.targetBytesInPartition78643200 spark.hadoop.hive.exec.dynamic.partition.modenonstrict spark.sql.sources.partitionOverwriteMode…

華為OD機試 - 剩余銀飾的重量(Java 2024 C卷 100分)

華為OD機試 2024C卷題庫瘋狂收錄中,刷題點這里 專欄導讀 本專欄收錄于《華為OD機試(JAVA)真題(A卷B卷C卷)》。 刷的越多,抽中的概率越大,每一題都有詳細的答題思路、詳細的代碼注釋、樣例測試…

【Python】 如何對對象列表進行排序,有點意思

在Python中,我們經常需要對對象列表進行排序,這可以通過多種方式實現。當對象是一個自定義類實例時,排序通常基于對象的一個或多個屬性。Python提供了內置的sorted()函數和列表的sort()方法,它們都允許我們指定一個排序的關鍵字。…

iPhone徹底刪除的照片怎么恢復?專業技巧助您解憂

在使用iPhone的過程中,我們可能會因為誤操作或其他原因將一些重要的照片徹底刪除。然而,即使照片被徹底刪除,也并不意味著它們就永遠消失了,它們只是被打上了“可覆蓋的空間”的標簽。 在照片被新數據覆蓋之前,我們仍…

C語言學習【C控制語句:循環】

C語言學習【C控制語句:循環】 while循環 /* 根據用戶鍵入的整數求和 */#include "stdio.h"int main(void) {long num;long sum 0L; /* 把sum初始化為0 */int status;printf("Please enter an integer to be summed");printf(&quo…

基于微信小程序的校園捐贈系統的設計與實現

校園捐贈系統是一種便捷的平臺,為校園內的各種慈善活動提供支持和便利。通過該系統,學生、教職員工和校友可以方便地進行捐贈,并了解到相關的項目信息和捐助情況。本文將介紹一個基于Java后端和MySQL數據庫的校園捐贈系統的設計與實現。 技術…

Java日期Date和LocalDateTime的工具類

Date package com.qiangesoft.utils.date;import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;/*** 日期工具類** author lq* date 2024-05-23*/ public class DateUtil {public static final String[] CHINESE_WEEK_DAY new String[]{&q…

Excel 公式積累

1.獲取當前位置的左側單元格 引用當前單元格左側的第一個單元格:OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),0,-1) ROW()返回當前單元格的行號,COLUMN()返回當前單元格的列號。 ADDRESS函數可以根據指定行號和列號獲得工作表中的某個單元格的地址。例如…

go全部版本下載目錄

linux安裝教程: Download and install - The Go Programming Language rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gzexport PATH$PATH:/usr/local/go/bin go version 全部版本下載目錄: All releases - Th…

鴻蒙本機通信

demo地址 https://github.com/MartinLi89/WanHarmony 目前只學到一部分,不正確的地方,還望大家指正,我會及時更新,謝謝,歡迎評論留言 線程內通信,線程間通信,進程間通信 本篇帖子中描述的比較寬…

快速開發 Chrome插件

什么是 Chrome 插件 Chrome 插件程序是一種用于增強 Google Chrome 瀏覽器功能的小型軟件應用程序。它們可以幫助用戶自定義瀏覽體驗、添加新功能、集成外部服務以及自動化任務等。擴展程序使用 HTML、CSS 和 JavaScript 編寫,利用 Chrome 提供的 API 來與瀏覽器及…

18.分布式監控zabbix-proxy

zabbix proxy 使用場景: 監控遠程區域設備監控本地網絡不穩定區域當 zabbix 監控上千設備時,使用它來減輕 server 的壓力簡化分布式監控的維護 環境規劃: zabbix-server:外網IP地址192.168.111.66 zabbix-proxy:外網IP地址192.168.111.11 內網IP地址…

AI工具推薦:提升工作效率與生活質量

有哪些好用,且國內可用的AI工具? 副本 在AI大發展的年代,還有人在工作、生活中沒有使用過AI嗎? 今天為大家推薦幾款國內可用、好用的AI工具,不論是自媒體文案寫作、打工人匯報PPT、還是論文、公文寫作,總…

設計系統采購與安裝:乙級資質申請的技術準備

在設計系統采購與安裝方面,為乙級資質申請所做的技術準備涉及多個方面。以下是一些關鍵的技術準備事項: 明確技術需求:首先,需要明確乙級資質申請所需的技術系統類型和規格。這可能包括但不限于設計軟件、工程管理系統、項目管理系…

【Linux】之【Get√】查看linux CPU 架構 ---- amd64、x86、x86_64、arm64

關于Linux軟件下載時:amd64、x86、x86_64、arm64 的說明 archuanme -alscpu

【設計模式深度剖析】【2】【創建型】【工廠方法模式】

👈?上一篇:單例模式 | 下一篇:抽象工廠模式👉? 目錄 工廠方法模式概覽工廠方法模式的定義英文原話直譯 工廠方法模式的4個角色抽象工廠(Creator)角色具體工廠(Concrete Creator)角色抽象產品&#x…

關于光照模型

關于光照模型 早期學習筆記,轉載自早期Excel。 存在大量格式錯誤、可讀性非常低,建議等待作者修復后閱讀、或者作為查找性材料使用。 中文名英文名/縮寫說明長什么樣蘭伯特光照模型Lambert Lighting1.蘭伯特反射(Lambert)是最常見的一種漫反射&#x…

iptables防火墻【其二 實驗篇】

保存&#xff0c;還原規則 防火墻規則的備份和還原 導出&#xff08;備份&#xff09;所有表的規則 iptables-save > /opt/ipt.txt 導入&#xff08;還原&#xff09;規則 iptables-restore < /opt/ipt.txt 將iptables規則文件保存在 /etc/sysconfig/iptables 中&#xf…

亞馬遜賣家賬號注冊復雜嗎?需要什么輔助工具嗎?

在當今數字化的商業世界中&#xff0c;亞馬遜作為全球最大的電商平臺之一&#xff0c;吸引著無數的賣家和買家。對于想要進入亞馬遜銷售市場的賣家來說&#xff0c;首先要完成的一項重要任務就是注冊亞馬遜賣家賬號。本文將詳細介紹亞馬遜注冊的步驟、所需時間&#xff0c;以及…