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 }