1、led點燈:
int main(void) { delay_init(168); //³õʼ»¯ÑÓʱº¯Êý LED_Init(); //³õʼ»¯LED¶Ë¿Ú /**這里的PF.1是板子上的任意管腳,將原來的PF.9不配置,使用杜邦線連接PF.1和PF.9進行驅動led **/ while(1) { GPIO_ResetBits(GPIOF,GPIO_Pin_1); //GPIOF.1 =0,LED0 GPIO_SetBits(GPIOF,GPIO_Pin_10); //GPIOF.10 =1,LED1 delay_ms(500); //延時 GPIO_SetBits(GPIOF,GPIO_Pin_1); //LED0 GPIO_ResetBits(GPIOF,GPIO_Pin_10); //LED1 delay_ms(500); } } // led 管腳初始化 void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);// //GPIOF9,F10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_10;//LED0ºÍLED1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// GPIO_Init(GPIOF, &GPIO_InitStructure);//GPIO GPIO_SetBits(GPIOF,GPIO_Pin_1 | GPIO_Pin_10);//GPIOF1,F10 }
驅動led需要配置外設的時鍾,具體選擇外設的哪一個管腳,選擇管腳為輸出模式,輸出模式中管腳驅動能力,管腳最大輸出速度,管腳配置上下拉輸出;
具體的每種模式詳細查看庫函數可選項;
2、蜂鳴器驅動:
蜂鳴器有有源和無源蜂鳴器,有源蜂鳴器只需要高低電平開關便可以蜂鳴器出聲。無源蜂鳴器需要管腳產生2~5KHz的方波才可以驅動蜂鳴器;
板子上用的是有源蜂鳴器。而蜂鳴器與led驅動方式類似,這里使用上面實驗中的PF1管腳驅動蜂鳴器,使用杜邦線連接對應的管腳就可以;
由於蜂鳴器驅動需要至少30mA的電流,而stm32F4單個管腳最大的輸出電流有25mA,但是整個芯片最大輸出電流也就140mA,因此這里使用三極管驅動蜂鳴器;
3、獲取按鍵輸入:

硬件連接如圖所示:注意配置按鍵管腳上下拉,PE2.3,4在按鍵按下檢測低電平,因此需要配置上拉電阻,確保常態下為高電平;WK_UP檢測高電平,因此需要配置下拉電阻,確保常態下為低電平,檢測高電平;
可以在上面試驗基礎上修改,KeyInit如下:
/* key0--->PE4 key1--->PE3 key2--->PE2 WK_UP-->PA0 */ void KeyInit(void) { // ÅäÖÃPA0, PE2.3.4ΪÊäÈëģʽ GPIO_InitTypeDef GPIO_InitStructure; // ³õʼ»¯ÍâÉèʱÖÓ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOA, ENABLE);//ʹÄÜGPIOFʱÖÓ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//LED0ºÍLED1¶ÔÓ¦IO¿Ú GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//ÆÕͨÊäÈëģʽ // GPIO_InitStructureA.GPIO_OType = GPIO_OType_PP;//ÍÆÍìÊä³ö GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;// ÓÉÓڸð´¼üÐèÒª¼ì²â¸ßµçƽ£¬Òò´Ë¹Ü½Å³õʼµçƽӦ¸ÃΪµÍµçƽ GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 |GPIO_Pin_3| GPIO_Pin_4; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// ÓÉÓڸð´¼üÐèÒª¼ì²âµÍµçƽ£¬Òò´Ë¹Ü½Å³õʼµçƽӦ¸ÃΪ¸ßµçƽ GPIO_Init(GPIOE, &GPIO_InitStructure);//³õʼ»¯GPIO }
檢測按鍵按下:
/* 按鍵動作捕獲 key0.1.2 -->0 WK_UP--->1 */ u8 KeyScan() { if(KEY0 == 0|| KEY1==0|| KEY2==0) { delay_ms(30); if(KEY0==0) return 1; else if(KEY1 == 0) return 2; else if(KEY2 == 0) return 3; } delay_ms(50); return 0; }
// 讀取按鍵按下值 #define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) #define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) #define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) #define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) #define LED0 PFout(9) #define LED1 PFout(10)
主函數中循環查詢是否有按鍵按下:后面可以使用按鍵中斷方式控制LED
int main(void) { u8 key; delay_init(168); // 延時函數初始化 LED_Init(); // led初始化 KeyInit(); // 按鍵配置初始化 while(1) { key = KeyScan(); if(key ){ switch(key){ case 1: LED0 = !LED0; break; case 2: LED1 = !LED1; break; case 3: LED0 = !LED0; LED1 = !LED1; break; } } else{ delay_ms(100); } }
擴展:
可以將其他引腳配置與上面引腳配置類似,使用杜邦線連接控制相同的動作;這里配置PE1,可以實現PE2對應的管腳控制動作;
4、使用中斷方式處理按鍵動作
外部中斷線有如下,這里先主要使用EXTI線0-15;

其中中斷線0-15映射關系:

5、外部中斷線的配置步驟:
1、使能中斷源(GPIO)的時鍾,外設中斷映射器(RCC_APB2Periph_SYSCFG)的時鍾;RCC_AHB1PeriphClockCmd()、RCC_APB2PeriphClockCmd()
2、初始化外設GPIO為輸入模式,以及對應的上拉或者下拉電阻;GPIO_Init()
3、初始化外部中斷線控制器,將GPIO與中斷線聯系起來;SYSCFG_EXTILineConfig()
4、對外部中斷線初始化,配置觸發方式;EXTI_Init()
5、配置外部中斷線的中斷處理函數;NVIC_Init()
6、編寫中斷處理函數,在中斷函數中,處理完任務后清除中斷標志位;EXTI_ClearITPendingBit(EXTI_Line2);
6、使用按鍵控制器LED的狀態
1、對按鍵、LED管腳初始化
1 // 按鍵管腳定義 2 #define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) 3 #define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) 4 #define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_1) 5 #define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) 6 7 #define LED0 PFout(9) 8 #define LED1 PFout(10) 9 10 //LED 初始化 11 void LED_Init(void) 12 { 13 GPIO_InitTypeDef GPIO_InitStructure; 14 15 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);// 16 17 //GPIOF9,F10 18 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0 LED1 19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;// 20 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// 21 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz 22 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// 23 GPIO_Init(GPIOF, &GPIO_InitStructure);// GPIO 24 25 GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//GPIOF1 26 } 27 28 29 /* 30 key0--->PE4 31 key1--->PE3 32 key2--->PE2 33 WK_UP-->PA0 34 */ 35 void KeyInit(void) 36 { 37 // PA0, PE2.3.4 38 GPIO_InitTypeDef GPIO_InitStructure; 39 40 // 41 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOA, ENABLE);// 42 43 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//LED0 44 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 45 // GPIO_InitStructureA.GPIO_OType = GPIO_OType_PP;// 46 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz 47 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;// 48 GPIO_Init(GPIOA, &GPIO_InitStructure);// GPIO 49 50 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3| GPIO_Pin_4; 51 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 52 GPIO_Init(GPIOE, &GPIO_InitStructure);// GPIO 53 }
2、外部中斷線初始化
// ÍⲿÖжÏÏß³õʼ»¯ // KEY0,1,2¼ì²âϽµÑØ void Exti_Init(void) { EXTI_InitTypeDef EXTI_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; KeyInit(); // 外設GPIO時鍾、輸入模式初始化 // 對外設中短線控制器時鍾初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // 將中斷線與對應的GPIO聯系起來 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2); SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3); SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4); // 外部中斷線初始化 設置觸發方式,中斷處理函數關聯 EXTI_InitStruct.EXTI_Line = EXTI_Line2|EXTI_Line3|EXTI_Line4; EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStruct); // NVIC_InitStruct.NVIC_IRQChannel = EXTI2_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; NVIC_Init(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = EXTI3_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; NVIC_Init(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStruct); }
3、中斷處理函數
1 // KEY2--->PE2--->EXTI2 2 void EXTI2_IRQHandler(void) 3 { 4 delay_ms(10); 5 LED1 = !LED1; 6 LED0 = !LED0; 7 EXTI_ClearITPendingBit(EXTI_Line2); 8 } 9 // KEY1-->PE3--->EXTI3 10 void EXTI3_IRQHandler(void) 11 { 12 delay_ms(10); 13 14 LED1 = !LED1; 15 16 EXTI_ClearITPendingBit(EXTI_Line3); 17 } 18 19 // KEY0--->PE4--->EXTI4 20 void EXTI4_IRQHandler(void) 21 { 22 delay_ms(10); 23 24 LED0 = !LED0; 25 EXTI_ClearITPendingBit(EXTI_Line4); 26 27 }
4、主函數:相關初始化,主函數可以大多做其他任務
1 int main(void) 2 { 3 u8 key; 4 delay_init(168); 5 LED_Init(); 6 //KeyInit(); 7 Exti_Init(); 8 // 使用中斷方式按鍵動作 9 LED0 = 0; // 10 while(1) 11 { 12 delay_ms(1000); // 處理其他任務 13 } 14 15 16 /* // 使用查詢方式處理按鍵動作 17 while(1) 18 { 19 key = KeyScan(); 20 if(key ){ 21 switch(key){ 22 case 1: 23 LED0 = !LED0; 24 break; 25 case 2: 26 LED1 = !LED1; 27 break; 28 case 3: 29 LED0 = !LED0; 30 LED1 = !LED1; 31 break; 32 } 33 } 34 else{ 35 delay_ms(100); 36 } 37 } 38 39 */ 40 41 }
