文章目錄
- 一、題目簡述
- 二、簡述:初始化GPIO,點亮LED燈
- 三、工程檔案模板的建立
- 四、使用暫存器點亮LED燈——代碼部分
- 1、硬體連接設計
- 2、打開之前建立的工程模板
- 3、代碼撰寫
- 4、硬體連接
- 燒錄:STM32F103C8T6與PC端連接
- 五、使用暫存器點亮LED燈——電路部分
- 1、面包板介紹
- 2、電路連接
- 六、總結
關于STM32F103系列芯片的地址映射和暫存器映射原理,GPIO埠的初始化設定步驟,請參考我的前一篇博客,
【嵌入式07】暫存器映射原理詳解,GPIO埠的初始化設定步驟
一、題目簡述
以 STM32最小系統核心板STM32F103C8T6+面板板+3只紅綠藍LED 搭建電路,使用GPIOB、GPIOC、GPIOD這3個埠控制LED燈,輪流閃爍,間隔時長1秒,
1)寫出程式設計思路,包括GPIOx埠的各暫存器地址和詳細引數;
2)分別用匯編語言,C語言編程實作,
二、簡述:初始化GPIO,點亮LED燈
外設的功能都是完全不同的,但初始化都是大同小異的,
點燈是所有學單片機的人都應該學會的第一項技能,這樣子才算入門,
51單片機的點燈是,通過控制暫存器將片外引腳(我們稱之為IO口)拉低拉高,輸出高低電平,以控制LED亮滅,
其程序:單片機給指令->控制暫存器->給IO口電平->控制LED亮滅
stm32的點燈則是,通過使能外設GPIO時鐘,發出指令給外設GPIO,外設GPIO收到指令后,著手配置自己的暫存器,然后給IO口模式,讓其實作各種功能,
其程序:CPU給指令->GPIO收到指令->配置內部暫存器->配置IO口模式(注意是模式)->控制LED亮滅
三、工程檔案模板的建立
建立模板要用到的SYSTEM檔案及啟動檔案,包括點燈時需要的C8T6資料手冊,以及燒錄用到的FlyMcu,網盤自取,
鏈接:https://pan.baidu.com/s/1jxbVCa_filfR9ZRlmP6SMw
提取碼:k4lv
新建工程Light2檔案,工程名為light,因為之后實驗采用C8T6板,因此這里選擇STM32F103C8
之后彈出的添加庫檔案視窗Manage Run-Time Environment,在這個界面,我們可以添加自己需要的組件,從而方便構建開發環境,不過這里我們不做介紹,選擇Cancel即可,
到這里,我們還只是建了一個框架,還需要添加啟動代碼,以及.c 檔案等,
先介紹一下啟動代碼:啟動代碼是一段和硬體相關的匯編代碼,
主要作用如下:
1、堆疊(SP)的初始化;
2、初始化程式計數器(PC);
3、設定向量表例外事件的入口地址;
4、呼叫 main 函式,
ST 公司提供了 3 個啟動檔案給我們,分別用于不同容量的 STM32 芯片,這三個檔案是:
startup_stm32f10x_ld.s,startup_stm32f10x_md.s,startup_stm32f10x_hd.s
其中,ld.s 適用于小容量 產品;md.s 適用于中等容量產品;hd 適用于大容量產品;
這里的容量是指 FLASH 的大小.判斷方法如下:
小容量:FLASH≤32K
中容量:64K≤FLASH≤128K
大容量:256K≤FLASH
這里,我查看了一下C8T6的資料手冊,
其Flash容量為128K,屬于中容量,因此我在這里采用startup_stm32f10x_md.s作為啟動檔案,
啟動檔案借用了正點原子版本,上面網盤鏈接可下載,
或者可以到這個網址去下載:http://www.openedv.com/posts/list/313.htm,
將啟動檔案拷貝到Light2工程檔案夾下,

我們找到 Target1→Source Group1→雙擊→設定打開檔案型別為 Asm Source file→選擇 startup_stm32f10x_hd.s→點擊 Add,如下圖所示

這里看到的 2 個檔案夾:Listings 和 Objects,是 KEIL 自行創建的,用于保存編譯程序中生成的一些檔案,
添加完之后,得到如下界面

先關閉 KEIL 軟體
為了不讓之后生成的檔案顯得混亂,在Light2檔案夾下新建一個OBJ檔案,用于存放生成的中間檔案,
USER 檔案夾專門用來存放啟動檔案(startup_stm32f10x_md.s)、工程檔案(test.uvprojx)等不可缺少的檔案,而 OBJ 則用來存放這些編譯程序中產生的中間檔案(包括.hex 檔案也將存放在這個檔案夾里面),然后把 Listings 和Objects 檔案夾里面的東西全部移到 OBJ 檔案夾下,
這一步我自己做的有點凌亂,最后的檔案夾結果如圖所示,檔案夾跟下面差不多一般就沒有問題,



由于上面我們還沒有任何代碼在工程里面,這里我們把系統代碼 copy 過來(即 SYSTEM檔案夾,該檔案夾由 ALIENTEK 提供,這些代碼在任何 STM32F10x 的芯片上都是通用的,可以用于快速構建自己的工程,
同樣在本節開頭網盤鏈接內,
注意一定要拷貝暫存器版本

在 USER 檔案夾下面找到 test.uvprojx,打開它,然后在 Target 目錄樹上點擊右鍵→Manage Project Items,彈出對話框,

在上面對話框的中間欄,點新建(用紅圈標出)按鈕(也可以通過雙擊下面的空白處實作),新建 USER 和 SYSTEM 兩個組,然后點擊 Add Files 按鈕,把 SYSTEM 檔案夾三個子檔案夾里面的:sys.c、usart.c、delay.c 加入到 SYSTEM 組中,注意:此時 USER 組下還是沒有任何檔案,我們只添加SYSTEM的三個,

點擊 OK,退出該界面回傳 IDE,
此時界面如圖所示

接著,我們新建一個 test.c 檔案,并保存在 USER 檔案夾下,然后雙擊 USER 組,會彈出加載檔案的對話框,此時我們在 USER 目錄下選擇 test.c 檔案,加入到 USER 組下,

如果我們此時編譯的話,生成的中間檔案,還是會存放在 Listings 和 Objects 檔案夾下,所以,我們先設定輸出路徑,再編譯,
點擊魔法棒,彈出 Options for Target’Target 1’對話框,選擇 Output 選項卡→選中 Create Hex File(用于生成 Hex 檔案,后面會用到)→點擊 Select Folder for Objects→找到 OBJ 檔案夾→點擊 OK

接著,再設定 Listings 檔案路徑,在圖 3.2.16 的基礎上,打開 Listing 選項卡→點擊 Select
Folder for Listings→找到 OBJ 檔案夾→點擊 OK

加入sys、delay、usart的include路徑:

注意!我們必須根據所用 STM32F1 型號的容量,來輸入相關宏定義,對于STM32F103 系列芯片,設定原則如下:
16KB≤FLASH≤32KB 選擇:STM32F10X_LD 64KB≤FLASH≤128KB 選擇:STM32F10X_MD
256KB≤FLASH≤512KB 選擇:STM32F10X_HD
我們要將三個路徑都加入

至此,一個完整的 STM32F1 開發工程模板下建立好了,接下來我們就可以進行代碼下載和仿真除錯了,
四、使用暫存器點亮LED燈——代碼部分
1、硬體連接設計
根據題目要求,使用GPIOB,GPIOC,GPIOD埠來控制LED燈,在查詢C8T6資料手冊后,我選用了PB5,PC4,PD8管腳分別連接紅綠藍三種顏色的燈(由于我只有紅綠黃三個小燈,在之后實際硬體中,會用黃燈代替藍燈)

圖中從 3 個 LED 燈的陽極各經過 1 個限流電阻連接到 3.3V 電源,陰極連接STM32 的 3 個 GPIO 引腳中,所以我們只要控制這三個引腳輸出高低電平,即可控制其所連接 LED 燈的亮滅,
目標是把 GPIO 的引腳設定成推挽輸出模式并且默認下拉,輸出低電平,這樣就能讓 LED 燈亮起來了,
但是之后連電路的時候發現并沒有PD管腳,于是自己改成了PA1,PB0,PB5,只是在推挽輸出、以及宣告時代碼有所不同,其他變化不大,

2、打開之前建立的工程模板
具體步驟請往上翻
3、代碼撰寫
在Light2檔案夾下新建一個HARDWARE檔案夾,用來存盤以后與硬體相關的代碼,

然后我們打開 USER 檔案夾下的 test.uvprojx 工程,新建兩個檔案,然后保存在HARDWARE→LED 檔案夾下面,保存為 led.c,led.h
我們將檔案添加到工程中,步驟如下圖

在魔法棒這里將HARDWARE路徑加進去,否則之后會報錯,

下面來撰寫led.c檔案,要用到GPIOB、GPIOC、GPIOD則,對應時鐘設定:

在設定完時鐘之后就是配置完時鐘之后,LED_Init 配置了 PB5 PC4 PD8 的模式為推挽輸出,
并且默認輸出 1,這樣就完成了對這三個 IO 口的初始化,
代碼如下:
led.c
#include "led.h"
//初始化 PB1 PC4 PD8為輸出口.并使能這三個口的時鐘
//LED IO 初始化
void LED_Init(void)
{
RCC->APB2ENR|=1<<2; //使能 PORTA 時鐘
RCC->APB2ENR|=1<<3; //使能 PORTB 時鐘
// RCC->APB2ENR|=1<<4; //使能 PORTC 時鐘
// RCC->APB2ENR|=1<<5; //使能 PORTD 時鐘
GPIOB->CRL&=0XFF0FFFFF;
GPIOB->CRL|=0X00300000;//PB.5 推挽輸出
GPIOB->ODR|=1<<5; //PB.5 輸出高
GPIOB->CRL&=0XFFFFFFF0;
GPIOB->CRL|=0X00000003;//PB.0 推挽輸出
GPIOB->ODR|=1<<0; //PB.0 輸出高
GPIOA->CRL&=0XFFFFFF0F;
GPIOA->CRL|=0X00000030;//PA.1 推挽輸出
GPIOA->ODR|=1<<1; //PA.1 輸出高
}
這段代碼里面最關鍵就是 3 個推挽輸出代碼的撰寫
led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//LED 埠定義
#define LED0 PBout(5) // DS0
#define LED1 PBout(0) // DS1
#define LED2 PAout(1) // DS2
void LED_Init(void); //初始化
#endif
這段代碼里面最關鍵就是 3 個宏定義:
#define LED0 PBout(5) // DS0
#define LED1 PBout(0) // DS1
#define LED2 PAout(1) // DS2
在USER檔案夾的test.c中撰寫main函式
test.c
#include "sys.h"
#include "delay.h"
#include "led.h"
int main(void)
{
Stm32_Clock_Init(9); //系統時鐘設定
delay_init(72); //延時初始化
LED_Init(); //初始化與 LED 連接的硬體介面
while(1)
{
LED0=0;
LED1=1;
LED2=1;
delay_ms(1000);
LED0=1;
LED1=0;
LED2=1;
delay_ms(1000);
LED0=1;
LED1=1;
LED2=0;
delay_ms(1000);
}
}
代碼包含了#include "led.h"這句,使得 LED0、LED1、LED2、LED_Init 等能在 main 函式里被呼叫,
接下來,main 函式先呼叫 Stm32_Clock_Init 函式,配置系統時鐘為 9 倍頻,也就是 8*9=72M(外部晶振是 8Mhz),然后呼叫 delay_init 函式,初始化延時函式,接著就是呼叫 LED_Init 來初始化 三個管腳 為輸出,最后在死回圈里面實作 LED0 LED1 LED2 交替閃爍,間隔為 1s,
我們編譯看看是否報錯,

沒有報錯!
那么就可以進行下載了,
4、硬體連接
燒錄:STM32F103C8T6與PC端連接
打開C8T6資料手冊,查找TXD和RXD管腳位置
PA9——TX
PA10——RX


務必將boot0設為1,boot1設為0,利用跳線帽實作


借助FLYMCU下載軟體,即可將light.hex載入,軟體資料同樣可在網盤下載,
這里我利用FlyMcu進行,

五、使用暫存器點亮LED燈——電路部分
1、面包板介紹
面包板是由于板子上有很多小插孔,專為電子電路的無焊接實驗設計制造的,由于各種電子元器件可根據需要隨意插入或拔出,免去了焊接,節省了電路的組裝時間,而且元件可以重復使用,所以非常適合電子電路的組裝、除錯和訓練,


常見的最小單元面包板分上、中、下三部分, 上面和下面部分一般是由一行或兩行的插孔構成的窄條,中間部分是由中間一條隔離凹 槽和上下各 5 行的插孔構成的寬條,

窄條上下兩行之間電氣不連通,
面包板背面示意圖,看到背面示意圖的情況,應當就很容易理解面包板之后應當如何接線了,

每 5 個插孔為一組,通常的面包板上有 10 組或 11 組,
對于 10 組的結構,左邊 5 組內部電氣連通,右邊 5 組內部電氣連通,但左右兩邊之間不連通,這種結構通常稱為 5-5 結構,
還有一種 3-4-3 結構即左邊 3 組內部電氣連通,中間 4 組內部電氣連通,右邊 3 組內部電氣連通,但左邊 3 組、中間 4 組以及右邊 3 組之間是不連通的,
對于 11 組的結構,左邊 4 組內部電氣連通,中間 3 組內部電氣連通,右邊 4 組內部電氣連通,但左邊 4 組、中間 3 組以及右邊 4 組之間是不連通的,這種結構稱為 4-3-4 結構,
中間部分寬條是由中間一條隔離凹槽和上下各 5 行的插孔構成,在同一列中的 5 個 插孔是互相連通的,列和列之間以及凹槽上下部分則是不連通的,

2、電路連接
讓 STM32 一按復位鍵就開始跑代碼,則需要配置 BOOT0 為 0,BOOT1 隨便設定都可以,

在將C8T6連接到電路板之前,一定要先將BOOT0置位0,否則電路無效!!!
面包板連線,按照這個圖連接,只不過我在實際電路時手頭沒有電阻,于是就沒有連接電阻,

實際圖連接

點燈實況

成功!
六、總結
面包板是個很方便的東西,比焊接快多了,以后可以多多利用,
參考
[1] https://blog.csdn.net/asdfg1075511750/article/details/79663568
[2] https://blog.csdn.net/countofdane/article/details/82561478
[3] https://blog.csdn.net/weixin_44784157/article/details/107448624
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/321749.html
標籤:其他
上一篇:具有kml命名空間的根節點<kml>未在basexxquery中決議
下一篇:在一列中固定字母
