?一、初始LED原理圖
共陰極led
LED發光二極管,需要有電流通過才能點亮,當有電壓差就會產生電流
二極管兩端的電壓差超過2.7v就會有電流通過
電阻的作用
由于公式I=V/R
不加電阻容易造成瞬間電流無窮大
發光二極管工作電流為10-20MA
3.3v / 1kΩ? = 3.3mA
電阻作用限流電阻。
二、分析GPIO寄存器
2.1 前言
編程的目的是為了操作硬件,硬件分布在地址上,所以轉變為編程操作地址,因為地址是唯一的。
編程的目的就操作地址間接操作硬件
地址分布比較廣,硬件都會把地址用寄存器的方式來分布
某個地址到某個地址屬于某個寄存器
這樣的話我們操作硬件實際上就是在操作地址,操作地址實際上就是轉化為操作寄存器。
2.2 本節目標
?
操控PA1-PA4輸出高電平
????????經過前言分析可知,這幾個問題編程找到一個或者某幾個寄存器,這幾個寄存器可以讓我們的PA1-PA4進行高電平的輸出。
?????????另一個要注意的我們的gpio口,當前pa1-pa4要輸出高低電平,那么當前這個pa1-pa4他所對應的功能是通用的輸入輸出。 這時候pa1-pa4是輸出功能,還有其他功能,當前處理器有48個管腳,每一個管腳有多個功能,某一時刻只用一個功能,這就是管腳的復用。找寄存器,那幾個可以管理我們的pa1-pa4,讓這個四個管腳可以當做輸入輸出功能中的輸出功能來用。?
為了更好的實現分析,這時候需要去看stm32的中文參考手冊
其中第八節是對gpio的描述
GPIO描述:每個gpio端口有兩個32位配置寄存器,兩個數據寄存器,一個32位置位/復位寄存器,一個16位復位寄存器,一個32位鎖定寄存器,總共有七個寄存器,我們就是通過操作這些寄存器來控制我們的GPIO的。
注:1字節=8位(bit)
其中GPIO每個端口又可以配置成如下八種模式:
對于具體gpio配置成什么模式,8.1.11節外設的GPIO配置有詳細解釋
2.3 寄存器描述
?首先看8.2.1端口配置低寄存器(GPIOx_CRL)x=A..E
4位一組?
?分別配置輸入輸出模式和速度。
從表中可以看到低寄存器對應的是GPIO0-7
正好對應32的八組。
端口配置高寄存器是8-15
?因為我們要配置的是PA1-4,所以我們只關系低寄存器的1-4也就是4-19位
對于輸出模式,大多數gpio采用推挽輸出模式即可?
?2.4 寄存器地址確定
當我們確定好要操作的寄存器后,下一步就需要找到寄存器對應的地址,然后在相應的位寫入數據即可
寄存器地址由基地址+偏移地址組成
gpio的基地址在
的寄存器映像中可以找到
整個地址被分為0x0000 0000? 到 0Xffff? FFFF,
當前stm32是32位的處理器。就是2的32次方。
最多能管理從0開始一直到2的32次方減1.
由寄存器映像可知,gpioA的基地址是0x4001 0800
所以我們要操作的低寄存器地址就是基地址+偏移地址=0x4001 0800 + 0x00
一會就要向這個地址里面的4到19位寫0011 0011 0011 0011?
根據寄存器配置說明可知00是通用推挽輸出,11是最大速度50MHz,這樣gpioA1-4就都配置成了最大速度50Mhz ,推挽輸出模式
2.5 輸出寄存器配置
當知道gpio1-4的地址并配置好輸出模式后,我們應該考慮輸出數據了,應該會有一個寄存器會完成這部分操作。?
找到了端口輸出數據寄存器
首先確定其地址,地址=基地址+偏移地址=0x4001 0800 + 0xCH =?0x4001 08CH
這16位就占了我們寄存器中的低16位。
端口輸出寄存器干什么用的呢,你往哪一個端口寫1,哪一個就輸出高電平 ,哪一個端口寫0就輸出低電平。
gpio我們只用到了pa1-pa4,所以這個寄存器我們只需要關心
三、寄存器配置代碼
控制低寄存器地址?
?
我們現在是要往地址里面去寫 值,那么我們現在要修改的不是地址指向的位置而是要修改我們地址里面的值,地址里面的內容,也就是說我們要取出這地址里面的內容把里面的內容做一個修改,要如何修改如何取出地址里面的值,我們就需要再加一個強制類型轉換。?
這個代表了地址了:?
?取出地址里面的內容:
用到了兩個*,第一個*是強制類型轉換,將我們的0x40010800轉成了一個用來表示地址的指針,如何取出地址里面的值呢,取值操作符。
取出地址里面的值了下一步要干什么,我是不是要修改這個地址里面的值。
如何修改呢,我們要修改的是這個地址里面的4-19位就可以了。
如何修改4-19位最好的 做法是先給他清零,然后再寫入我們的新值,
?這一部分屬于C語言的內容
分別用到了
& | 按位與 | 如果兩個相應的二進制位都為1,則該位的結果值為1,否則為0 |
I | 按位或 | 兩個相應的二進制位中只要有一個為1,該位的結果值為1 |
^ | 按位異或 | 若參加運算的兩個二進制位值相同則為0,否則為1 |
~ | 取反 | ~是一元運算符,用來對一個二進制數按位取反,即將0變1,將1變0 |
<< | 左移 | 用來將一個數的各二進制位全部左移N位,右補0 |
>> | 右移 | 將一個數的各二進制位右移N位,移到右端的低位被舍棄,對于無符號數,高位補0 |
1.與運算(&)
參加運算的兩個數據,按二進制位進行“與”運算。
運算規則:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即:兩位同時為“1”,結果才為“1”,否則為0
例如:3&5 即 0000 0011 & 0000 0101 = 0000 0001 因此,3&5的值得1。
兩個數與的結果一定是比任意兩個數都小,換句話說,越與數越小
2.或運算(|)
參加運算的兩個對象,按二進制位進行“或”運算。
運算規則:0|0=0; 0|1=1; 1|0=1; 1|1=1;
即 :參加運算的兩個對象只要有一個為1,其值為1。
例如:3|5 即 0000 0011 | 0000 0101 = 0000 0111 因此,3|5的值得7。
兩個數或的結果一定是大于其中的任意一個數,換句話說,越或數越大
3.異或運算(^)
參加運算的兩個數據,按二進制位進行“異或”運算。
運算規則:0^0=0; 0^1=1; 1^0=1; 1^1=0;
即:參加運算的兩個對象,如果兩個相應位為“異”(值不同),則該位結果為1,否則為0。
例如:9^5可寫成算式如下: 00001001^00000101=00001100 可見9^5=12
4.取反運算(~)
參加運算的數據,按二進制位進行“取反”運算。
運算規則:~0=1; ~1=0;
即:參與運算的數據,對應的二進制取反后 0 變成 1 ,1 變成 0 。
例如: 3 :00000011 ; ~3 :11111100 = 252
5.左移運算(<<)
參與運算的數據,二進制全部向左移動 n 位,左邊舍去,右邊補 0
運算規則:00000101 << 1 = 00001010
即:參與運算的數據,對應的二進制位向左移動 n 位,左邊舍去,右邊補 0 。
例如:2 << 1 = 4 ; 00000010 << 1 = 00000100
左移一位相當于乘以 2
6.右移運算(>>)
參與運算的數據,二進制全部向右移動 n 位,右邊舍去,左邊補 0
運算規則:00000101 >> 1 = 00000010
即:參與運算的數據,對應的二進制位向右移動 n 位,右邊舍去,左邊補 0 。
例如 :2 >> 1 = 1 ; 00000010 >> 1 = 00000001
右移一位相當于除以 2
上述位預算符---------原文鏈接:https://blog.csdn.net/qq_52354698/article/details/119301131
?與操作會清零,如何修改4-19位,4-19位清零,其他位不變,
0xff0000f =?111111111111000000000000000011111111
當進行位與操作時,因為4-19位都是0,按照其運算規則,得到值始終是0
清楚之后,這時候需要去修改我們的4-19位分別寫成0011 0011 0011 0011,
這時候可以采用或操作。
0011等于十六進制的3
或操作置位, =0x00033330;
四、通過寄存器地址進行點燈操作?
注:?
清零是與操作
置1是或操作
管腳高電平點亮
低電平熄滅
?點亮led燈和我們的端口輸出數據寄存器有關:
寄存器地址等于基地址+偏移地址
現在我們要讓他輸出一個高電平
就要往這個寄存器里面的1-4位寫高電平
要讓燈熄滅的話對應寫0就可以了
在進入循環語句之前應該讓我們的led燈都熄滅,在循環中點亮熄滅
?DOR寄存器地址:
?=0x4001080c
首先對寄存器清零,清零就是與操作
1<<1 = 10
1<<2 = 100
1<<3 = 1000
1<<4 = 10000
|或完是11110
取反后是00001
通過循環做一個延時
?
五、GPIO庫函數?
?
在stm32固件庫函數手冊的第10節對GPIO的庫函數進行了描述
GPIO寄存器結構,GPIO_TypeDef和AFIO_TypeDef在文件stm32f10x_map.h中
其中AFIO有兩個功能:
1、引腳復用重映射
2、中斷引腳選擇
GPIO函數庫
其中標黃的是常用的幾個庫函數
函數GPIO_DeInit和函數GPIO_DeInit
配置GPIO端口為默認值。
函數GPIO_Init對GPIO進行初始化,主要包括配置GPIOx的那個引腳,配置成什么模式,速度是多少,這些都是通過一個結構體進行配置的。
GPIO_ReadInputDataBit:讀取PA15的輸入值(GPIOA_PIN_15)
函數GPIO_ReadInputData:讀取GPIOA的輸入值,多位
函數GPIO_ReadOutputDataBit:讀取PA15的輸出值
函數GPIO_ReadOutputData:讀取GPIOA的輸出值,多位
?一個字節=8位(bit)所以末尾bit就是讀一位的值
函數 GPIO_SetBits:設置PA15的值,就是置1
函數 GPIO_ResetBits:清除PA15的輸入值,就是置0
函數 GPIO_WriteBit:設置PA15的值,可以是0也可以是1
函數GPIO_Write:設置PA的值,可以是一個十六進制的值,一下設置多位
函數GPIO_EXTILineConfig:中斷時使用,選擇一個GPIO引腳作為中斷線路。