之前沒接觸過單片機,初次學習感到很迷茫,從初識stm'32到建工程模板再到第一個(流水燈實驗),用了兩天半的時間。因為C語言基礎不是很好,有很多語句都看不懂,費了很大的勁才把led燈點亮。因為模電和數電都還沒學,電路圖也很難弄懂。
下面是原理圖:

點亮led的方法

知道了原理之后,根據方法分析,可制定相應的開發步驟如下:
1)為控制LED燈,知道要使用 GPIO 外設。
2)了解GPIO外設有什么功能,要如何使用。
3)獲知GPIO的地址映射,知道它所掛載的總線APB2。
4)了解ST官方庫對寄存器的封裝。
5)了解時鍾樹,查看 GPIOx(x= A…F)的時鍾來源,即PCLK2。
6)在stm32f10x_conf.h文件中包含用到的頭文件stm32f10x_gpio.h 、
stm32f10x_rcc.h。
7)在工程模板的基礎上添加bsp_xxx.c、bsp_xxx.h用戶文件。
8)編寫驅動初始化函數 XXX_GPIO_Confi g() (XXX = LED / KEY …。
9)開啟外設GPIOx x= A…F )時鍾,分析由SystemInit()函數配置的默認的
Sysclk=72MHz 的時鍾頻率是否符合工程要求。
10)根據控制要求,定義並填充初始化結構體GPIO_InitStructure向相應的結構體成
員寫入適當的參數。
2)了解GPIO外設有什么功能,要如何使用。
3)獲知GPIO的地址映射,知道它所掛載的總線APB2。
4)了解ST官方庫對寄存器的封裝。
5)了解時鍾樹,查看 GPIOx(x= A…F)的時鍾來源,即PCLK2。
6)在stm32f10x_conf.h文件中包含用到的頭文件stm32f10x_gpio.h 、
stm32f10x_rcc.h。
7)在工程模板的基礎上添加bsp_xxx.c、bsp_xxx.h用戶文件。
8)編寫驅動初始化函數 XXX_GPIO_Confi g() (XXX = LED / KEY …。
9)開啟外設GPIOx x= A…F )時鍾,分析由SystemInit()函數配置的默認的
Sysclk=72MHz 的時鍾頻率是否符合工程要求。
10)根據控制要求,定義並填充初始化結構體GPIO_InitStructure向相應的結構體成
員寫入適當的參數。
11)調用初始化函數GPIO_Init()初始化 GPIOx(x= A…F)。
12)編寫相應的XXX_led.h XXX = LED)頭文件。
13)針對不同的應用要求,編寫 main 應用程序。
14)調試程序、完成
13)針對不同的應用要求,編寫 main 應用程序。
14)調試程序、完成
該步驟也適用任何工程。分析完之后,再寫三個文件"bsp_led.c","bsp_led.h"和主函數"main.c"
下面是頭文件bsp_led.h的程序代碼
[html] view plain copy
- #include "stm32f10x.h"//這個是STM32的地址映射,包含了STM32的所有寄存器的地址
- #define ON 0
- #define OFF 1
- // 定義帶參宏,可以像內聯函數一樣使用
- #define LED1(a) if (a) \
- GPIO_SetBits(GPIOB,GPIO_Pin_0);\
- else \
- GPIO_ResetBits(GPIOB,GPIO_Pin_0)
- #define LED2(a) if (a) \
- GPIO_SetBits(GPIOC,GPIO_Pin_4);\
- else \
- GPIO_ResetBits(GPIOC,GPIO_Pin_4)
- #define LED3(a) if (a) \
- GPIO_SetBits(GPIOC,GPIO_Pin_3);\
- else \
- GPIO_ResetBits(GPIOC,GPIO_Pin_3)
- void LED_GPIO_Config(void);//初始化LED端口
- #endif
頭文件的內容不多,但也把它獨立成一個頭文件,方便以后擴展或移植使用。在寫頭文件的時候加上類似以下這樣的條件編譯 :
#ifndef __LED_H
#define __LED_H
……
#endif
這個是非常重要的。
下面試bsp_led.c文件
[html] view plain copy
- #include "bsp_led.h"//調用頭文件
- void LED_GPIO_Config(void)//初始化LED的IO
- {
- GPIO_InitTypeDef GPIO_InitStructure;//定義一個GPIO_InitTypeDef類型的結構體
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);//開啟LED的外設時鍾
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//選擇要要控制的GPIOB引腳
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//設置引腳模式為通用推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//設置引腳速率為50MHZ
- GPIO_Init(GPIOB,&GPIO_InitStructure);//調用庫函數,初始化GPIOB0
- lt;span style="color:#ff0000;">
- /*選擇要控制的引腳*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_Init(GPIOC, &GPIO_InitStructure); </span>
- GPIO_SetBits(GPIOB, GPIO_Pin_0);//關閉所有的led燈
- GPIO_SetBits(GPIOC, GPIO_Pin_4|GPIO_Pin_3);//關閉所有的led燈
- }
紅色部分是非常重要的,一開始我忘記編寫了,燒錄成功后只有一個;LED燈閃亮。
下面是主函數main.c的代碼
[html] view plain copy
- #include "stm32f10x.h"
- #include "bsp_led.h"//兩個頭文件都必須包含,不要漏掉
- void Delay(__IO uint32_t nCount);//簡單的延時函數的聲明,在這里延時函數被調用
- int main(void)
- {
- LED_GPIO_Config();//LED端口的初始化
- while(1)
- {
- LED1(ON);
- Delay(0x0FFFFF);//延時的時間我用十六進制來表示的,也可以用十進制
- LED1(OFF);
- LED2(ON);
- Delay(0x0FFFFF);
- LED2(OFF);
- LED3(ON);
- Delay(0x0FFFFF);
- LED3(OFF);
- }
- }
- void Delay(__IO uint32_t nCount)//簡單的延時函數
- {
- for(; nCount !=0; nCount--);
- }
下面來分析一下主函數
首先調用了在bsp_led.c文件編寫的LED_GPIO_Config()函數,完成了對控制LED 的 GPIO 的初始化。緊接着就在 while死循環里不斷執行在bsp_led.h文件中編寫的帶參宏代碼,並加上延時函數,使各盞LED輪流亮滅。當然,在LED控制的部分,如果不習慣帶參宏的方式,讀者也可以直接使用GPIO_SetBits() 和GPIO_ResetBits() 函數實現對LED的控制。
第一個工程就這樣學完了,當然還存在許多疑問,我相信會慢慢解決的。應該抽時間學一下C語言和模電數電的知識,學習是無止境的,加油吧!!!
創客學院全新視頻盡在:www.makeru.com.cn
嵌入式學習交流群:561213221