day02-流水燈控制、蜂鳴器、按鍵及外部中斷


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
}
View Code

驅動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    
}
View Code

  檢測按鍵按下:

/*
按鍵動作捕獲
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;
}
View Code
// 讀取按鍵按下值
#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)
View Code

主函數中循環查詢是否有按鍵按下:后面可以使用按鍵中斷方式控制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);            
        }
    }
View Code

擴展:

  可以將其他引腳配置與上面引腳配置類似,使用杜邦線連接控制相同的動作;這里配置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 }
View Code

  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);

}
View Code

  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 }
View Code

  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 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM