完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
正题引入:
按键中断控制LED蜂鸣器,首先确定按键属于输入信号,需要向开发板输入电平来对LED灯和蜂鸣器进行控制,那么我们需要做的分为以下几步: 首先查看开发板原理图,确定你所需要控制的KEY和LED以及BEEP位于哪个引脚 从下图可以得到KEY的引脚分别为PE2-PE3,LED引脚为PC0-PC7,BEEP引脚为PB5 从下图看出KEY对应为高电平时可以触发中断,LED需要低电平才可以被点亮,BEEP由于这里是无源蜂鸣器则需要不停使其引脚高低电平转换才可以响。 查看好所需要配置的GPIO引脚后,再确定引脚所需要的工作模式。这里的LED灯显而易见,肯定是需要开发板给予高低电平才可以使其工作,并且我们这里给其配置为带数字推挽输出。KEY则一般是设置为上拉输入,BEEP的工作原理模式配置与LED类似。 下面分别是GPIOx_CRH和GPIOx_CRL的寄存器原理图 以配置PC0为例:这里是需要给LED配置带数字推挽输出,那么则需要将GPIOx_CRL的MODE0[1:0]=01即输出模式,最大速率为10MHz CNF0[1:0]=00 即推挽输出模式 配置KEY1:需要给PE1设置为上拉输入模式 配置BEEP:需要给PB5设置为推挽输出模式 接下来就是需要对上面两步进行程序化,也就是化成程序,比如这个地方需要程序化: LED_Init() // 初始化函数 KEY_Init() // 初始化函数 BEEP_Init() // 初始化函数 初始化首先需要开启相应引脚时钟:这里LED对应的是PC引脚,那么需要使能PC的时钟以及PE和PB的时钟 LED_Control(para1,para2)//LED控制函数 BEEP_Ring() // BEEP控制函数 EXTI2_IRQHandler() // 按键的中断服务函数(关键) 最后就是应用层main.c的编写,根据需求去完成。 这里分别以HAL库函数版和寄存器版进行举例 HAL库函数版: KEY.c如下(.h文件由自己发挥): void KEY_Init(void) // 初始化 { GPIO_InitTypeDef GPIO_InitStructure ={0}; __HAL_RCC_GPIOE_CLK_ENABLE(); // 开启时钟 /*Configure GPIO pins : PE2 PE3 PE4 */ GPIO_InitStructure.Pin = KEY1_Pin; GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStructure.Pull = GPIO_PULLUP; // 上拉输入 HAL_GPIO_Init(KEY_GPIO_Port, &GPIO_InitStructure); HAL_GPIO_WritePin(KEY_GPIO_Port, KEY1_Pin, GPIO_PIN_SET); HAL_NVIC_SetPriority(EXTI2_IRQn, 1, 0); HAL_NVIC_EnableIRQ(EXTI2_IRQn); } LED.c如下(.h文件由自己发挥): void LED_Init(void) // LED初始化 { GPIO_InitTypeDef GPIO_InitStructure ={0}; __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStructure.Pin = LED1_Pin ; // LED1_Pin 相当于 PC0 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 设置为推挽输出 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; // 低速 HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStructure); HAL_GPIO_WritePin(LED_GPIO_Port, LED1_Pin, GPIO_PIN_SET); // 默认输出低电平 } void Led_Ctrl(int No, LED_Staus staus) { switch(No) { case 1: { if(staus == LED_ON) // 开灯 { HAL_GPIO_WritePin(GPIOB, LED_Pin, GPIO_PIN_RESET); } else // 关灯 { HAL_GPIO_WritePin(GPIOB, LED_Pin, GPIO_PIN_SET); } break; } default: break; } } BEEP.c如下(.h文件由自己发挥): void Beep_Init(void) { GPIO_InitTypeDef GPIO_InitStructure ={0}; __HAL_RCC_GPIOB_CLK_ENABLE(); // 使能时钟 GPIO_InitStructure.Pin = BEEP_Pin ; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BEEP_GPIO_Port, &GPIO_InitStructure); HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET); } void Beep_Ring(void) { uint16_t i; while(i《=3000) { HAL_GPIO_TogglePin(BEEP_GPIO_Port,BEEP_Pin); delaynms(30); i++; } } void delaynms(uint16_t i) { uint16_t j; while(i--) { for(j = 0; j 《 125; j++) // 1ms { } } } EXTI2_IRQHandler() 如下: void EXTI2_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { LOS_TaskDelay(20); // 消除抖动 switch(GPIO_Pin) { case GPIO_PIN_2: { Led_Ctrl(1,LED_ON); Beep_Ring(); break; } default: break; } } 寄存器版: LED.c如下(.h文件由自己发挥): void LED_Init(void) // LED初始化 { RCC-》APB2ENR |= (1 《《 4); // 需要左移几位具体需要看前面,寄存器原理图引脚所对应为第几位 // 这里PC对应第四位,所以这里左移4 GPIOC-》CRL &= ~ (0xF 《《 0); // 置为前先清零,养成好习惯,需要左移几位同样是看引脚对应为第几位 GPIOC-》CRL |= 1 《《 0; // 设置为推挽输出模式 GPIOC-》BSRR = 1 《《 0; // 默认输出高电平 } void Led_Ctrl(int No, LED_Staus staus) { switch(No) { case 1: { if(staus == LED_ON) // 开灯 { GPIOC-》BRR = 1 《《 0; // 开灯 } else // 关灯 { GPIOC-》BSRR = 1 《《 0; // 关灯 } break; } default: break; } } BEEP.c如下(.h文件由自己发挥): void BEEP_Init(void) // LED初始化 { RCC-》APB2ENR |= (1 《《 2); // 需要左移几位具体需要看前面,寄存器原理图引脚所对应为第几位 GPIOB-》CRL &= ~ (0xF 《《 0); // 置为前先清零,养成好习惯,需要左移几位同样是看引脚对应为第几位 GPIOB-》CRL |= 1 《《 20; // 设置为推挽输出模式 } void Beep_Ring(void) { uint16_t i; while(i《=3000) { GPIOB-》BRR = 1 《《 5; delaynms(30); GPIOB-》BSRR = 1 《《 5; i++; } } void delaynms(uint16_t i) { uint16_t j; while(i--) { for(j = 0; j 《 125; j++) // 1ms { } } } KEY.c如下(.h文件由自己发挥): void KEY_Init(void) // LED初始化 { RCC-》APB2ENR |= (1 《《 0); // AFIO口的时钟源 RCC-》APB2ENR |= (1 《《 6); // 需要左移几位具体需要看前面,寄存器原理图引脚所对应为第几位 GPIOE-》CRL &= ~ (0xF 《《 8); // 置为前先清零,养成好习惯,需要左移几位同样是看引脚对应为第几位 GPIOE-》CRL |= 8 《《 8; // 设置为上拉输入模式 GPIOE-》ODR |= 1 《《 2; // 默认输出高电平 AFIO-》EXTICR1 &= ~(0xF 《《 8); AFIO-》EXTICR1 |= 4 《《 8; // 将PE2口用作外部中断EXTI2输入 EXTI-》IMR |= 1 《《 2; // 打开中断 EXTI-》FTSR |= 1 《《 2; // 外部中断为下降沿触发 NVIC_EnableIRQ(EXTI2_IRQn); // 使能中断 NVIC_SetPriority(EXTI2_IRQn,1); // 设置中断优先级 } void EXTI2_IRQHandler() // 中断服务函数 { Led_Ctrl(1,LED_ON); BEEP_Ring(); EXTI-》PR = 1 《《 2; // 清除中断标志位 } 一起加油吧,有问题都可以在评论区留言呀,会及时回复的! |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1606 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1538 浏览 1 评论
969 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
681 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1584 浏览 2 评论
1861浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
642浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
514浏览 3评论
528浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
501浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-19 23:13 , Processed in 0.595358 second(s), Total 47, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号