本例程基於先前的庫函數版demo工程模板,主要內容為:bsp_led.h、bsp_led.c、bsp_key.h、bsp_key.c、main.c
1、bsp_led.h
1 #ifndef __BSP_LED_H //條件編譯,如果沒有定義這個宏,向下執行;如果已經定義則不向下執行,結束條件編譯。 2 #define __BSP_LED_H //沒有定義,則定義該宏。 當下次該頭文件被編譯時,該宏已經編譯,即直接結束條件編譯。 3 4 #include "stm32f10x.h" //下面用到外設的寄存器映射 5 //綠色led宏定義一下,便於移植 6 #define LED_G_GPIO_PIN GPIO_Pin_0 7 #define LED_G_GPIO_PORT GPIOB 8 #define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB 9 10 11 #define ON 1 12 #define OFF 0 13 14 // \ 續行符,后面不能有任何東西 15 16 #define LED_G(a) if(a) \ 17 GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); \ //復位,PB0的ODR寄存器對應位置0 18 else GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); //PB0的ODR寄存器對應位置1 19 20 // ^ 異或 21 22 #define LED_G_TOGGLE {LED_G_GPIO_PORT->ODR ^= LED_G_GPIO_PIN;} //端口設置寄存器BSRR對應位為1,ODR寄存器對應位反復與BSRR取異或,實現0變1,1變0 23 24 void LED_GPIO_Config(void); //在頭文件中定義bsp_led.c中的函數,目的是便於其他c文件調用。 25 26 #endif /* __BSP_LED_H */ //結束條件編譯
2、bsp_led.c
1 #include "bsp_led.h" 2 3 void LED_GPIO_Config(void) 4 { 5 GPIO_InitTypeDef GPIO_InitStruct;//定義GPIO結構體 6 7 RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);//使能APB2總線時鍾 8 9 GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;//0號引腳 10 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出 11 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//輸出頻率50MHz 12 13 GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);//GPIO初始化函數,入口參數1為GPIOB,入口參數2為GPIO結構體首地址,因此&取地址 14 }
3、bsp_key.h
1 #ifndef __BSP_KEY_H 2 #define __BSP_KEY_H 3 4 #include "stm32f10x.h" 5 6 #define KEY_ON 1 7 #define KEY_OFF 0 8 9 #define KEY1_GPIO_PIN GPIO_Pin_0 10 #define KEY1_GPIO_PORT GPIOA 11 #define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA 12 13 void KEY_GPIO_Config(void); 14 uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin); 15 16 #endif /* __BSP_KEY_H */ 17 18 //該頭文件與bsp_led.h結構完全一致,不做說明。
4、bsp_key.c
1 #include "bsp_key.h" 2 3 4 void KEY_GPIO_Config(void) 5 { 6 GPIO_InitTypeDef GPIO_InitStruct; 7 8 RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE); 9 10 GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN; 11 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; 12 13 GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct); 14 } 15 //以上重復部分不做說明。 16 uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
//此為自定義按鍵掃描函數,入口參數定義來自於標准函數GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)入口參數,讀取的是IDR寄存器對應位 17 { 18 if( GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON ) //key1按下,PA0輸入高電平,GPIO_ReadInputDataBit()讀1 19 { 20 // 松手檢測 21 while( GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON ); //key1按下后未斷開,執行該死循環,執行語句為空; 22 return KEY_ON; //按鍵斷開后,返回1 23 } 24 else return KEY_OFF; //沒有檢測到key1按下返回0 25 }
5、main.c
1 #include "stm32f10x.h" // 相當於51單片機中的 #include <reg51.h> 2 #include "bsp_key.h" 3 #include "bsp_led.h" 4 void Delay( uint32_t count )//軟件延時,未用 5 { 6 for(; count!=0; count--); 7 } 8 9 int main(void) 10 { 11 // 來到這里的時候,系統時鍾已經被配置成72M 12 LED_GPIO_Config(); 13 KEY_GPIO_Config(); 14 15 while(1) 16 { 17 if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) ==KEY_ON ) 18 LED_G_TOGGLE; 19 20 // 每按下key1一次,執行一次LED反轉 21 } 22 }
7