STM32入門(一)
學習單片機主要學習單片機的外設部分,主要有GPIO,UART,其他外設在應用中學習,


一、GPIO
GPIO 是通用輸入輸出埠的簡稱,簡單來說就是 STM32 可控制的引腳,STM32 芯片
的 GPIO 引腳與外部設備連接起來,從而實作與外部通訊、控制以及資料采集的功能,
STM32芯片的 GPIO 被分成很多組,每組有 16 個引腳,如型號為 STM32F103VET6型號的
芯片有 GPIOA、GPIOB、GPIOC 至 GPIOE 共 5 組 GPIO,芯片一共 100 個引腳,其中
GPIO就占了一大部分,所有的 GPIO引腳都有基本的輸入輸出功能,
GPIO 有很多個暫存器,每一個都有特定的功能,每個暫存器為 32bit,占四個位元組,
在該外設的基地址上按照順序排列,暫存器的位置都以相對該外設基地址的偏移地址來描
述,這里我們以 GPIOB 埠為例,來說明 GPIO 都有哪些暫存器

/*本檔案用于添加暫存器地址及結構體定義*/
/*片上外設基地址 */
#define PERIPH_BASE ((unsigned int)0x40000000)
/*APB2 總線基地址 */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
/* AHB總線基地址 */
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
/*GPIOC外設基地址*/
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
/* GPIOC暫存器地址,強制轉換成指標 */
#define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18)
/*RCC外設基地址*/
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
/*RCC的AHB1時鐘使能暫存器地址,強制轉換成指標*/
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)
首先定義了 “片上外設”基地址 PERIPH_BASE,接著在 PERIPH_BASE 上加入各個總線的地址偏移,得到 APB1、APB2 總線的地APB1PERIPH_BASEAPB2PERIPH_BASE,在其之上加入外設地址的偏移,得到 GPIOA-G 的外設地址,最后在外設地址上加入各暫存器的地址偏移,得到特定暫存器的地址,一旦有了具體地址,就可以用指標讀寫
二、使用暫存器點亮LED燈
1.啟動檔案
名為“startup_stm32f10x_hd.s”的檔案,它里邊使用匯編語言寫好了基本程式,當STM32 芯片上電啟動的時候,首先會執行這里的匯編程式,從而建立起 C 語言的運行環境,所以我們把這個檔案稱為啟動檔案,該檔案使用的匯編指令是 Cortex-M3 內核支持的指令
2.stm32f10x.h檔案
看完啟動檔案,那我們立即寫 SystemInit 和 main 函式吧?別著急,定義好了SystemInit 函式和 main 我們又能寫什么內容?連接 LED 燈的 GPIO 引腳,是要通過讀寫暫存器來控制的,就這樣空著手,如何控制暫存器,我們知道暫存器映射就是給一個已經分配好地址的特殊的記憶體空間取的一個別名,這個特殊的記憶體空間就是暫存器,它可以通過指標來操作,
/*本檔案用于添加暫存器地址及結構體定義*/
/*片上外設基地址 */
#define PERIPH_BASE ((unsigned int)0x40000000)
/*APB2 總線基地址 */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
/* AHB總線基地址 */
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
/*GPIOC外設基地址*/
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
/* GPIOC暫存器地址,強制轉換成指標 */
#define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18)
/*RCC外設基地址*/
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
/*RCC的AHB1時鐘使能暫存器地址,強制轉換成指標*/
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)
3.main檔案
從分析啟動檔案時我們知道,Reset_Handler 呼叫了該函式用來初始化 SMT32 系統時鐘,為了簡單起見,我們在 main 檔案里面定義一個SystemInit 空函式,什么也不做,為的是騙過編譯器,把這個錯誤去掉,關于配置系統時鐘我們在后面再寫,當我們不配置系統時鐘時,STM32 會把 HSI 當作系統時鐘,HSI=8M,由芯片內部的振蕩器提供,
/*
*工程模板(暫存器版本)
*/
#include "stm32f10x.h"
/**
* 主函式
*/
int main(void)
{
// 開啟GPIOC 埠時鐘
RCC_APB2ENR |= (1<<4);
//清空控制PC2的埠位
GPIOC_CRL &= ~( 0x0F<< (4*2));
// 配置PC2為通用推挽輸出,速度為10M
GPIOC_CRL |= (1<<4*2);
// PC2 輸出 低電平
GPIOC_ODR &= ~(1<<2);
while(1);
}
// 函式為空,目的是為了騙過編譯器不報錯
void SystemInit(void)
{
}
/*********************************************END OF FILE**********************/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/253544.html
標籤:其他
上一篇:Hfut | 集電競賽指南
