鴿了這么久終于又想起了CSDN的密碼
今天大家一起來學習stm32,對于32如何建工程,網路上已經有很多例子,包括檔案也有很多,如果需要的話可以在文末找到群號,我會在群檔案里面分享,這里就不再浪費口舌,
32對于51單片機來說,無論是I/O口還是暫存器都有特別大的變化,舉個很簡單的例子:51單片機的I/O一般是不需要配置的,而32的I/O口需要使能,需要選擇模式,(模擬輸入、浮空輸入、上、下拉輸入、開漏輸出、推挽輸出、復用開漏/推挽輸出共計八個模式),所以,想要學好32就必須了解32的庫函式定義,
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
這就是一段GPIO初始化的結構體,結構體里面仍然是結構體,比如mode這個
typedef enum
{ GPIO_Mode_AIN = 0x0,
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28,
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_OD = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
真正初始化的函式是
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
相信大家看到這里已經懵逼了,這到底該**怎么才能初始化啊,一個I/O口怎么這么麻煩!
不要炸雞,聽我給大家講解
首先看到前兩個函式框,大家估計已經明白了,32的庫函式幾乎有一半都是結構體,所以大家C語言功底一定要扎實,咱們寫單片機的不像搞程式的那個復雜深入,但是基本功一定不要落下,
大家看到入口引數其實就倆GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct
我們先看看GPIO_TypeDef* GPIOx,從名字上就能看出這是找I/O口的,就和51單片機是一樣的,比如51叫P1那么32就叫GPIOA,第二個是初始化I/O口的,我們右鍵進入定義看看
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
這里也就是剛剛那一段,我們可以看到這個結構體里面有三個東西
uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode;
看后面的注釋可以知道uint16_t GPIO_Pin;是定義引腳的,也就是51中的P1^1一樣
GPIOSpeed_TypeDef GPIO_Speed;這是定義I/O口頻率的,我們右鍵進去看看
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
這里我們有三個選擇10 2 50,根據需要自行決定
我們看下一個
GPIOMode_TypeDef GPIO_Mode;這是對IO口模式的選擇,繼續右鍵
typedef enum
{ GPIO_Mode_AIN = 0x0,
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28,
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_OD = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
可以看到這里也就是我最開始說的八種模式
好了了解這些之后我們就開始第一步,初始化一個I/O口吧,那么因為我的LED在B5和E5,那我就以這兩個I/O口為例子,
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE埠時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 埠配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據設定引數初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 輸出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 埠配置, 推挽輸出
GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽輸出 ,IO口速度為50MHz
GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 輸出高
}
我知道大家又懵了,我來依次為大家解答
Q:第一行干什么的?
A:第一行相當于是定義一個GPIO_InitStructure結構體來初始化I/O口
Q:RCC_APB2PeriphClockCmd是什么東西?
A:這是使能B E這兩個I/O口的函式,因為GPIOB和BPIOE在APB2總線上(可以在中文參考手冊查到其他GPIO的總線,群里有),所以我們需要用這個函式,大家記住即可,
接下來的三行就是一個規范的結構體使用方法,根據定義中的資料,依次錄入,那么因為我們是要點燈,所以我們用推挽輸出,接著GPIO_Init來根據引數初始化GPIOB,
GPIO_SetBits是輸出高電平的函式,使用方法看我例程也就明白了
這里補充一下:低電平是GPIO_ResetBits
Q:為什么GPIOE你只設定了Pin腳的引數,其他引數都不設定呢?
A:因為其他的和GPIOB一樣,都是推挽輸出和50MHz所以不需要另外設定,
LED_Init寫完了之后我們就可以寫主函式了
int main(void)
{
delay_init();
LED_Init();
while(1)
{
LED0 = 0;
LED1 = 1;
delay_ms(300);
LED0 = 1;
LED1 = 0;
delay_ms(300);
}
}
學過51的同學應該都能看懂吧?
不過還是得說明一下
delay_init();這個函式在delay.h里面已經定義過了,不需要自己寫,(群里有工程檔案)
LED0 和LED1需要我們自己在led.h頭檔案中宏定義
#define LED0 PBout(5)
#define LED1 PEout(5)
趕快將代碼編譯到stm32開發板上試試吧!
下一篇我將會更新STC51的PWM,然后更新STC12的PWM,為更新STM32的PWM做好準備
交流群號:1033131250
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/271454.html
標籤:其他
