STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结
摘自:STM32F103五分鐘入門系列(一)跑馬燈(庫函數+寄存器)+加編程模板+GPIO總結
作者:自信且愛笑‘
發布時間: 2021-04-28 21:17:40
網址:https://blog.csdn.net/Curnane0_0/article/details/116158776
學習板:STM32F103ZET6
跑馬燈實驗
- 前言
- 一、GPIO
- 1、GPIO種類
- 2、GPIO輸入輸出的8種模式:
- 3、模式用途
- 二、點亮LED(庫函數版)
- 1、庫函數的由來
- 2、點亮LED庫函數版編寫順序
- 1、GPIO_Init()
- 2、RCC_APB2PeriphClockCmd()
- 3、將配置函數放在led.c和led.h文件
- 三、點亮LED(寄存器版本)
- 1、新建工程、添加led文件
- 2、配置時鐘
- 3、GPIO配置
- 4、主函數代碼編寫
- 附1 PXout()與PXin()
前言
本來準備先總結一下GPIO、幾種輸入輸出模式以及配置方法、寄存器種類、時鐘及分頻等,但是想了想,還是算了,一步步的來,到時候用到再總結吧 ,不然前面總結了,后面用到還得回顧。
至于前面的安裝庫、安裝軟件、Keil中添加文件等,就不在總結了,因為這些根本并不需要記的,新手可以去跟著視頻走一遍。學習過程中,不用每次都自己去新建工程,直接將官方給的模板拷過來,修改一下文件夾名稱即可。
一、GPIO
1、GPIO種類
本博板子STM32F103ZET6共有7組IO口,每組16個,共16×7=112個,分別為:
GPIOA——>PA0、PA1、PA2…PA15
GPIOB——>PB0、PB1、PB2…PB15
.
.
.
GPIOG——>PG0、PG1、PG2、…PG15
2、GPIO輸入輸出的8種模式:
| GPIO_Mode_AIN | 模擬輸入 |
| GPIO_Mode_IN_FLOATING | 浮空輸入 |
| GPIO_Mode_IPD | 下拉輸入 |
| GPIO_Mode_IPU | 上拉輸入 |
| GPIO_Mode_Out_OD | 開漏輸出 |
| GPIO_Mode_Out_PP | 推挽輸出 |
| GPIO_Mode_AF_OD | 復用開漏輸出 |
| GPIO_Mode_AF_PP | 復用推挽輸出 |
3、模式用途
1、 GPIO_Mode_AIN :模擬輸入
一般用于ADC模擬輸入
2、GPIO_Mode_IN_FLOATING :浮空輸入
可用于按鍵KEY實驗、發送接收信號RX、TX等,不過這些實驗可以不用浮空輸入,如KEY用到上拉和下拉
3、GPIO_Mode_IPD:下拉輸入
4、GPIO_Mode_IPU:上拉輸入
IO內部上拉電阻、下拉電組輸入,使情況而定,比如剛剛說的key按鍵實驗,原理圖如下:
可以看到KEY_UP按下后,IO口應該是3V3電平輸入,未按下時為懸空狀態,而懸空狀態IO輸入是未知的,所以為了防止程序跑飛,采用下拉輸入,在懸空狀態下,使IO輸入下拉到低電平。這樣,在懸空狀態下,IO檢測到的是低電平,不會去執行key_up按下后的程序。
KEY0~2按下后,IO口是低電平輸入。按下時為懸空狀態,而懸空狀態IO輸入是未知的,所以為了防止程序跑飛,采用上拉輸入,在懸空狀態下,使IO輸入上拉到高電平。這樣,在懸空狀態下,IO檢測到的是高電平,不會去執行KEY0 ~2按下后的程序。
5、GPIO_Mode_Out_OD:開漏輸出
IO 輸出 0 接 GND,IO 輸出 1,懸空,需要外接上拉電阻,才能實現輸出 高電平。當輸出為 1 時,IO 口的狀態由上拉電阻拉高電平,但由于是開漏輸出模式,這樣 IO 口也就可以 由外部電路改變為低電平或不變。該模式適合做電流型的驅動,吸收電流能力比較強。
6、GPIO_Mode_Out_PP:推挽輸出
可以輸出高、低電平。導通損耗小、效率高。既提高電路的負載能力,又提高開關速度。廣泛各種實驗,比如接下來要總結的LED。
7、GPIO_Mode_AF_OD:復用開漏輸出
當GPIO為復用IO時的開漏輸出模式,一般用于外設功能,如TX1
8、GPIO_Mode_AF_PP:復用推挽輸出
當GPIO為復用IO時的推挽輸出模式,一般用于外設功能,如I2C
二、點亮LED(庫函數版)
1、庫函數的由來
在學習庫函數之前,應該明白,STM32F1用的是Cortex-M3芯片,是由ARM公司設計的。所以芯片的標準是由ARM公司制定的,芯片內核架構有ARM公司提供。而我們現在用的STM32由ST公司生產,所以關系是:ARM制定內核架構,ST等芯片公司根據ARM公司的標準設計了芯片。ST等公司設計的芯片,不同的是存儲容量、外設、串口數量等等。
以本博的學習板STM32F103ZET6為例,固件庫(庫函數的集合)是由官方提供的,這個官方是ST公司,而不是正點原子官方。也就是說不僅僅這一型號單片機,ST系列其他型號的單片機庫函數依舊可以適用。所以不必擔心更換板子后不知如何去編程。
ST公司推出官方固件庫,將底層寄存器操作都封裝起來,形成一套接口(API)供我們使用,大多數情況下我們不必去考慮底層寄存器。比如本博的LED,只需調用GPIO配置函數、時鐘配置函數,然后主函數初始化后,直接給引腳賦值就可以實現LED的亮滅,而不用去考慮寄存器如何工作的。當然本博會把寄存器版的LED也總結一下。畢竟想要真正理解單片機,還得去真正理解寄存器,庫函數版只是讓我們停留在“會使用”。當然,對應大多數人來講,“會使用”已經完全足夠了。
2、點亮LED庫函數版編寫順序
1、設置時鐘
2、設置GPIO
只要這兩步的配置,再在主函數中給對應引腳傳輸高低電平即可。
打開原理圖文件(下圖我打開了6個文件,都是需要的,而且大部分情況下,有這6個文件足以。都在板子附帶資料的文件夾里)
從原理圖中得到以下信息:
①DS0 LED0陽極接+,陰極接PB5;DS1 LED1陽極接+,陰極接PE5。
②SYS LED由名稱“PWR”顧名思義,為電源指示燈,所以單片機接通電源后,電源指示燈常亮。
③芯片的PB5引腳軟件置0后,LED0亮;PE5引腳軟件置0后,LED1亮。
所以要配置GPIOB(因為PB5)和GPIOE(因為PE5)。
然后是時鐘設置,只要是對GPIO操作,就必須進行時鐘配置(而且時鐘配置在前)。GPIO是掛載在APB2總線上的外設,所以在對GPIO的時鐘進行設置時,通過函數RCC_APB2PeriphClockCmd()來實現。
下面進入實戰:
打開模板文件:(時間久遠了,不知道模板文件原來放哪個文件夾下,找不到的話可以把LED官方例程打開,關于LED的.c和.h文件刪掉,主函數清空,就可以當以后的模板來用了,不用每次都創建工程)
首先查看GPIO配置函數,既然是GPIO,那么先找一下頭文件,在main.c下找GPIO頭文件,并點擊進入。
找到對應函數:(下一博客總結所有GPIO函數的用法、以及延時函數)
上圖標注,GPIO_Init()函數初始化,進行設置GPIO,GPIO_SetBits()函數給對應引腳置1,GPIO_ReSetBits()函數給對應引腳置0。
1、GPIO_Init()
右鍵選中函數,點擊【Go to Definition of …】,進入函數詳細說明
可以看到,函數的形參有兩個,而且都是指針。進入第一個形參“類型”
看到GPIOx指針是指向上圖這個結構體的,也就是每組GPIO都包含的7個寄存器。
比如LED實驗,傳遞GPIOB(PB5)過來后,*GPIOB就指向這七個寄存器,初始化函數就是對七個寄存器的操作,不過被庫函數封裝起來了,emmmm…說太多了,只要知道GPIO_Init()傳過來的第一個參數表示對該組GPIO配置就行了。
察看第二組形參“類型”
看到第二個形參也是結構體指針,指向的結構體含有三個參數GPIO_Pin、GPIO_Speed、GPIO_Mode
到這里就可以用C++語法來說明了。比如第二個形參是a(注意是指針),那么:
a.GPIO_Pin=…
a.GPIO_Speed=…
a.GPIO_Mode=…
就完成了對參數GPIO參數的設置。
接下來我們再看看上面三個賦值語句的右邊究竟是什么東西:
轉回到初始化函數:
1表示第二個形參
2表示對 GPIO_Init()的第一個形參的處理(就是那個結構體里有7個寄存器的東西)
3表示mode的配置
4表示pin的配置
5表示速speed的配置。
點開GPIO_Mode設置函數:
可以看到就是我們第一大部分總結的8中輸入輸出模式
點開pin設置函數
可以看到pin是我們第一大部分總結的一組GPIO的15個IO口
點開速度設置函數
可以看到速度可設置的值:
到這里,GPIO的設置函數應該會寫了:
第一步:設置形參1和形參2
第二步:上面那三個賦值語句的設置
第三步:運行GPIO_Init()函數
程序:(先在主函數中書寫,.c文件中書寫接下來會總結)
GPIO_TypeDef GPIO_B;//形參1GPIO_InitTypeDef GPIO_InitStruct;//形參2GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZGPIO_Init(&GPIO_B,&GPIO_InitStruct);- 1
- 2
- 3
- 4
- 5
- 6
注意GPIO_Init()傳遞的是指針,所以應該用取地址符“&”。
上面的程序還是有問題的,因為定義了GPIO_B為第一個參數,但是程序并不知道GPIO_B是對GPIOB的操作,所以在 GPIO_Init(&GPIO_B,&GPIO_InitStruct);語句中,“&GPIO_B”應該是真正的、物理上的地址,而不能像參數2一樣,只是程序定義參數時分配的地址。
輸入“GPIOB”,并進入
發現官方真的定義了GPIOB,而且還是真正的、物理層的地址
所以之前程序中的GPIO_B可以刪掉了,不是物理層的地址,定義了、傳遞給GPIO_Init()函數也沒用。
正確完整程序:
//GPIO_TypeDef GPIO_B;//形參1GPIO_InitTypeDef GPIO_InitStruct;//形參2GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZGPIO_Init(GPIOB,&GPIO_InitStruct);//注意GPIOB是地址!GPIO_InitStruct是指針,傳遞過去后的倆個實參數都是指針。- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
以上配置了GPIOB是為了點亮LED0,現配置LED1(PE5)的GPIO,參考上面的程序:
GPIO_InitTypeDef GPIO_InitStruct;//形參2GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZGPIO_Init(GPIOB,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;GPIO_Init(GPIOE,&GPIO_InitStruct);- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
因為之前設置了mode和speed,而實參2是沒有指向的,即并不能知道實參2屬于實參1,所以哪怕再重新定義一個GPIOE的實參2,重新定義mode和speed也沒有意義,所以就可以省略了。
接下來可以將LED引腳置高電平,熄滅LED。使初始狀態下LED是滅的。
int main(void){ GPIO_InitTypeDef GPIO_InitStruct;//形參2GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZGPIO_Init(GPIOB,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;GPIO_Init(GPIOE,&GPIO_InitStruct);GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_SetBits(GPIOE, GPIO_Pin_5);}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2、RCC_APB2PeriphClockCmd()
之前說過,GPIO是掛載在APB2總線上的外設,所以在對GPIO的時鐘進行設置時,通過函數RCC_APB2PeriphClockCmd()來實現。打開RCC.h頭文件,找到時鐘函數
同樣的方法確定形參類型
形參1:
形參2:
所以程序:(注意時鐘配置函數應該放在最前面)
GPIO_InitTypeDef GPIO_InitStruct;//形參2RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOE , ENABLE);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZGPIO_Init(GPIOB,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;GPIO_Init(GPIOE,&GPIO_InitStruct);GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_SetBits(GPIOE, GPIO_Pin_5);- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
加入延時函數,形成流水燈:(只在Main.c文件編程)
其中GPIO_SetBits(GPIOB, GPIO_Pin_5)是將PB5引腳置1;GPIO_ReSetBits(GPIOB, GPIO_Pin_5)是將PB5引腳置0
(是通過庫函數對BSRR和BRR寄存器操作完成置0置1,下一博客會涉及到)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
3、將配置函數放在led.c和led.h文件
在LED使用的工程文件夾新建一個LED文件夾
進行下一步驟:
創建一個text文件,命名為led.h,保存在LED group中
將頭文件添加進來
同理。新建一個led.c文件,將.c文件也添加進來
上述步驟是創建一個LED Group,現在將頭文件添加進來:
找到剛剛創建的文件夾并添加
上述步驟是為了之后調用里面生成的led.c和led.h
編輯頭文件:
固定格式:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
本實驗led.h文件可這樣寫:
#ifndef __LED_H //led.h文件 #define __LED_H void LED_Init(void);//初始化 #endif- 1
- 2
- 3
- 4
接下來編輯led.c文件
需要有本.c文件用到的頭文件,如果要用到別的文件中定義的變量,可以采用外部聲明重新聲明該變量。在.c文件實現.h文件聲明的函數
將我們之前main函數中關于GPIO配置和時鐘聲明的函數移植過來得到完整的LED程序:
/**led.h**/ #ifndef __LED_H //led.h文件 #define __LED_H void LED_Init(void);//初始化 #endif/**led.c**/ #include "led.h" #include "stm32f10x.h" void LED_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;//形參2RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOE , ENABLE);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//形參2.mode=推挽輸出GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//形參2.pin=5GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//形參2.speed=50MHZGPIO_Init(GPIOB,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;GPIO_Init(GPIOE,&GPIO_InitStruct);GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_SetBits(GPIOE, GPIO_Pin_5); }/**main.c**/ #include "stm32f10x.h" #include "delay.h" #include "led.h"int main(void){ LED_Init();delay_init(); //延時函數初始化 while(1){GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_SetBits(GPIOE, GPIO_Pin_5);delay_ms(1000); //注意包含頭文件delay.h,這個好像是正點原子官方寫的GPIO_ResetBits(GPIOB, GPIO_Pin_5);GPIO_ResetBits(GPIOE, GPIO_Pin_5);delay_ms(1000); }}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
三、點亮LED(寄存器版本)
1、新建工程、添加led文件
畢竟是32系列第一個博客,還是希望詳細一點,之后的實驗就會慢慢省略一部分東西,寄存器版本完整來一遍
打開模板文件,如果沒有,就把LED庫函數例程打開,刪掉led.c和led.h,當做以后所有實驗的模板就行了。
一般情況下,應該【HARDWARE】中創建.c文件。也可以在文件【HARDWARE】之外建,看個人習慣。
如果懶得去搞模板,就用我這個吧
先將模板文件拷過來,在HARDWARE文件夾下創建LED文件夾
打開模板文件
新建兩個text文件,保存在剛剛創建的LED文件夾下,并改名為led.c、led.h
將led.c文件添加進工程
將LED文件目錄添加進來
現在進入實戰
led.h編輯,之前庫函數版本講過了,直接附代碼:
#ifndef LED_H //led.h文件 #define LED_H int LED_Init(void); #endif- 1
- 2
- 3
- 4
led.c文件編輯
開始還是老規矩:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2、配置時鐘
打開《STM32中文參考手冊》7.3.7 APB2外設時鐘使能寄存器(RCC_APB2ENR)
寄存器下一博客總結,現在只需知道,APB2外設時鐘使能寄存器的第3位和第6位分別對應GPIOB(LED0、DS0)和GPIOE(LED1、DS1)
時鐘使能代碼如下:
RCC->APB2ENR|=1<<3; RCC->APB2ENR|=1<<6;- 1
- 2
解釋一下:
首先RCC->APB2ENR是對外設時鐘使能寄存器的訪問
RCC->APB2ENR|=1的意思是:RCC->APB2ENR=RCC->APB2ENR|0x00000001(32位寄存器),也就是說將該寄存器的第0位軟件置1,其它位保持不變。"<<3"是將剛剛設置的那個第0位的1左移3位,也就是此時第3位為1.同理“<<6”是將第6位設置為1;此時就使能了GPIOB和GPIOE的時鐘
3、GPIO配置
用到端口配置寄存器,由于是對PB5、PE5的配置,是低位IO口(Px0~Px7是低位、Px8 ~Px15是高位),所以用到端口配置低寄存器GPIOx_CRL
打開《STM332中文參考手冊》
看到第21、20位控制模式和速度,為50M輸出,所以這兩位是11;23 、22控制哪種輸出,為推挽輸出,所以這兩位為00,所以GPIOx_CRL的狀態值為:0x00300000;程序如下:
GPIOB->CRL&=0xff0fffff; //PB5GPIOB->CRL|=0x00300000;GPIOE->CRL&=0xff0fffff; //PE5GPIOE->CRL|=0x00300000;- 1
- 2
- 3
- 4
- 5
解釋一下:
GPIOB->CRL&=0xff0fffff 是將GPIOB的20、21、22、23這四位置0,其它位保持不變;
GPIOB->CRL|=0x00300000是將GPIOB的20、21、22、23這四位置1,其它位保持不變;
此時配置好了,然后可以給IO口賦初值,如開始時讓LED處于熄滅狀態,則PB5、PE5均置1。用到的寄存器:端口輸出數據寄存器GPIOx_ODR
代碼:
GPIOB->ODR|=1<<5;GPIOE->ODR|=1<<5;- 1
- 2
led.c文件完整代碼:
#include "led.h" //led.c文件 #include "stm32F10x.h" int LED_Init(void) {RCC->APB2ENR|=1<<3;RCC->APB2ENR|=1<<6;GPIOB->CRL&=0xff0fffff; //PB5GPIOB->CRL|=0x00300000;GPIOE->CRL&=0xff0fffff; //PE5GPIOE->CRL|=0x00300000;GPIOB->ODR|=1<<5;GPIOE->ODR|=1<<5; }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
4、主函數代碼編寫
進入主函數后,首先應調用剛剛寫的LED初始化函數,完成GPIO配置;程序會用到延時函數,將延時函數也初始化,代碼:(頭文件包含led.h)
#include "sys.h"#include "delay.h"#include "led.h"int main(void){ LED_Init();delay_init();}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
然后在死循環中,對PB5和PE5 IO口賦值就行了,還是用到端口輸出數據寄存器GPIOx_ODR
不過給IO口置0時,需要注意,應該和0xffffffdf進行與運算
- 1
- 2
或者移位運算,將第0位置0再向左移5位
GPIOB->ODR&=0xfffffffe<<5;GPIOE->ODR&=0xfffffffe<<5;- 1
- 2
給IO口置1就和0x00000020進行或運算
GPIOB->ODR|=0x00000020;GPIOE->ODR|=0x00000020;- 1
- 2
或者直接位移運算,先和0x00000001進行或運算,使第0位置1,再將第0位向左移動5,代碼:
GPIOB->ODR|=1<<5;GPIOE->ODR|=1<<5;- 1
- 2
main.c文件完整程序:
#include "sys.h" //main.c文件 #include "delay.h" #include "led.h"int main(void){ LED_Init();delay_init();while(1){GPIOB->ODR&=0xffffffdf;//置0GPIOE->ODR&=0xffffffdf;//置0//GPIOB->ODR&=0xfffffffe<<5;//GPIOE->ODR&=0xfffffffe<<5;delay_ms(1000);GPIOB->ODR|=0x00000020;GPIOE->ODR|=0x00000020;//GPIOB->ODR|=1<<5;//GPIOE->ODR|=1<<5;delay_ms(1000);}}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
附1 PXout()與PXin()
打開sys.h頭文件
定義了PXout()與PXin()函數,用法為:
點亮熄滅DS0、DS1,只需:
PBout(5)=0;//點亮 PEout(5)=0;//點亮 delay_ms(1000); PBout(5)=1;//熄滅 PEout(5)=1;//熄滅 delay_ms(1000);- 1
- 2
- 3
- 4
- 5
- 6
或者定義:
#define LED0 PBout(5) #define LED1 PEout(5)LED0=0;//點亮 LED1=0;//點亮 delay_ms(1000); LED0=1;//熄滅 LED1=1;//熄滅 delay_ms(1000);- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
總結
以上是生活随笔為你收集整理的STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 集合系列14之 Map总结(H
- 下一篇: Day22——十字链表