STM32F40实现 按键密码锁、按键控制LED 、串口选择菜单 、串口控制LED开关 、串口控制蜂鸣器开关及响度 、串口控制蜂鸣器播放音乐 、按键控制LED的亮度
本人第一次发文,很多都不懂,尤其害怕版权问题,如果有人质疑我有盗权行为,请联系我,因为项目也遇到很多问题,然后就解决嘛,可印象中只有播放音乐代码有借鉴,所以如果有质疑盗了权的,请务必联系我。板子是使用粤嵌科技的STM32F407ZE。
文章讲下述内容
1 项目文件结构
2 功能
3 源码:
4 从功能解析代码
5 使用说明
6. 可能遇到的问题
7. 播放音乐参考代码:
1 项目文件结构
- main.c -----------------------------------------------------------------程序入口
- led.c--------------------------------------------------------------------LED初始化
- key.c--------------------------------------------------------------------按键初始化及* 密码锁的实现
- delay.c-----------------------------------------------------------------系统定时器实现延时
- EXTI.c------------------------------------------------------------------外部中断(按键)
- usart.c-----------------------------------------------------------------串口初始化
- TIM.c------------------------------------------------------------------蜂鸣器的OUT初始化,TIM13初始化蜂鸣器的AF初始化,TIM14初始化LED的AF初始化
- menu.c----------------------------------------------------------------菜单功能实现
2 功能
- 按键密码锁
- 按键控制LED开关
- 串口选择菜单
- 串口控制LED开关
- 串口控制蜂鸣器开关及响度
- 串口控制蜂鸣器播放音乐
- 按键控制LED的亮度
3 源码:https://pan.baidu.com/s/16D9zn4O17SZgqm66o6gJiQ
- 链接:https://pan.baidu.com/s/10JugqdTt6H3URKoygvSXFw
提取码:rwqf
4 从功能解析代码
main.c
#include "stm32f4xx.h" // Device header
#include "delay.h"
#include "led.h"
#include "TIM.h"
#include "key.h"
#include "EXTI.h"
#include "usart.h"
#include "menu.h"int main()
{LED_init();BEEP_init();//TIM_init();KEY_init();password();//beep_pwm_init(((10000/100)-1),(8400-1));EXTI_init();usart1_init(115200);printf("登陆成功\n");menu_start();while(1){}}
1. 按键密码锁
程序开始执行LED的初始化、蜂鸣器的初始化和按键的初始化,此时蜂鸣器的初始化是调用了TIM.c文件中的BEEP_init()函数进行的OUT模式初始化,之后执行key.c中的password()函数,此时用户可以通过按键按指定的密码进行输入。
signed char key_det(void)
{if(key0 == 0) //按键0表示数字1{ //检测到按键按下delay_ms(50); //避过抖动期-按下抖动while(key0 == 0); //判断等待按键松开delay_ms(50); //避过抖动期-松开抖动while(key0 == 0); //判断确认按键松开return 1;}if(key1 == 0)//按键1表示数字2{ //检测到按键按下delay_ms(50); //避过抖动期-按下抖动while(key1 == 0); //判断等待按键松开delay_ms(50); //避过抖动期-松开抖动while(key1 == 0); //判断确认按键松开return 2;}if(key2 == 0) //按键2表示数字3{ //检测到按键按下delay_ms(50); //避过抖动期-按下抖动while(key2 == 0); //判断等待按键松开delay_ms(50); //避过抖动期-松开抖动while(key2 == 0); //判断确认按键松开return 3;}if(key3 == 0) //按键3表示数字4{ //检测到按键按下delay_ms(50); //避过抖动期-按下抖动while(key3 == 0); //判断等待按键松开delay_ms(50); //避过抖动期-松开抖动while(key3 == 0); //判断确认按键松开return 4;}return -1;
}void password(void)
{signed char n;signed char i[4]={0,0,0,0};while(1){for(n=0;n<4;n++){//等待输入密码,输入4位密码while((i[n] = key_det())== -1);//输入完毕延时500ms并响一声BEEP(1),delay_ms(200),BEEP(0);} //判断密码是否正确 密码1122if(i[0]==1 && i[1]==1 && i[2]==2 && i[3]==2) {BEEP(1),delay_ms(200),BEEP(0);delay_ms(200);BEEP(1),delay_ms(200),BEEP(0);delay_ms(200);BEEP(1),delay_ms(200),BEEP(0);delay_ms(200);break;}else{BEEP(1),delay_ms(1000),BEEP(0);}} }
2. 按键控制LED开关
在密码输入正确后蜂鸣器会响三声,之后进行外部中断(EXTI)初始化,此时可以在没进入“按键控制LED的亮度”功能前,通过按键key0、key1、key2、key3都可以分别控制LED0、LED1、LED2、LED3的开关
//EXTI_Line0的中断服务函数
void EXTI0_IRQHandler(void)
{//获取中断的状态,检查是否有中断请求if(EXTI_GetITStatus(EXTI_Line0) == SET ){i+=25;printf("%d\n",i);if(EXTI_FLAG == 0){ GPIO_ToggleBits(GPIOF,GPIO_Pin_9);}else if(EXTI_FLAG == 1){if(i<100){TIM_SetCompare1(TIM14,i);}else{i=0;}}}//清空外部中断控制线的挂起位,告诉CPU已完成中断请求,可以接收新的中断EXTI_ClearITPendingBit(EXTI_Line0);
}//EXTI_Line2的中断服务函数
void EXTI2_IRQHandler(void)
{//获取中断的状态,检查是否有中断请求if(EXTI_GetITStatus(EXTI_Line2) == SET ){printf("%d\n",i);i-=25;if(EXTI_FLAG == 0){GPIO_ToggleBits(GPIOF,GPIO_Pin_10);}else if(EXTI_FLAG == 1){if(i>-1){TIM_SetCompare1(TIM14,i);}else{i=100;}}}//清空外部中断控制线的挂起位,告诉CPU已完成中断请求,可以接收新的中断EXTI_ClearITPendingBit(EXTI_Line2);
}//EXTI_Line3的中断服务函数
void EXTI3_IRQHandler(void)
{//获取中断的状态,检查是否有中断请求if(EXTI_GetITStatus(EXTI_Line3) == SET ){GPIO_ToggleBits(GPIOE,GPIO_Pin_13);}//清空外部中断控制线的挂起位,告诉CPU已完成中断请求,可以接收新的中断EXTI_ClearITPendingBit(EXTI_Line3);
}//EXTI_Line4的中断服务函数
void EXTI4_IRQHandler(void)
{//获取中断的状态,检查是否有中断请求if(EXTI_GetITStatus(EXTI_Line4) == SET ){GPIO_ToggleBits(GPIOE,GPIO_Pin_14);}//清空外部中断控制线的挂起位,告诉CPU已完成中断请求,可以接收新的中断EXTI_ClearITPendingBit(EXTI_Line4);
}
3. 串口选择菜单
上述执行后,开始串口初始化,同时打印“登陆成功”,并打印开始菜单( menu_start()函数 )。
void menu_start(void){printf("※※※※※※※※※※※※※※※※※※※※\r\n");printf("※ _功能菜单_ ※\r\n");printf("※ ※\r\n");printf("※ _1、LED的开关_ ※\r\n");printf("※ _2、蜂鸣器开关,响度_ ※\r\n");printf("※ _3、音乐_ ※\r\n");printf("※ _4、灯控_ ※\r\n");printf("※※※※※※※※※※※※※※※※※※※※\r\n");
}
此时通过串口助手发送相应的序号,进入相应的子菜单,在发送相应的序号,执行相应的功能。
static int flag = 0;
int EXTI_FLAG = 0;
//static int TIM_FLAG=0;
//uint32_t pwm_cmp=0;
void USART1_IRQHandler(void)
{uint8_t d;//检查是否有中断触发if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){//接收数据d = USART_ReceiveData(USART1);//发送数据//USART_SendData(USART1,d);if(flag==0 && d=='1'){flag++;menu_1();}else if(flag==0 && d=='2'){flag+=2;menu_2();}else if(flag==0 && d=='3'){flag+=3;menu_3(); }else if(flag == 0 && d=='4'){flag+=4;menu_4();}}
子功能菜单
void menu_1(void){printf("※※※※※※※※※※※※※※※※※※※※\r\n");printf("※ _LED的开关 ※\r\n");printf("※ ※\r\n");printf("※ _a、控制灯1_ ※\r\n");printf("※ _b、控制灯2_ ※\r\n");printf("※ _c、控制灯3_ ※\r\n");printf("※ _d、控制灯4_ ※\r\n");printf("※ _e、返回上级菜单_ ※\r\n");printf("※※※※※※※※※※※※※※※※※※※※\r\n");
}void menu_2(void){printf("※※※※※※※※※※※※※※※※※※※※\r\n");printf("※ _蜂鸣器的开关,响度_ ※\r\n");printf("※ ※\r\n");printf("※ _a、蜂鸣器开_ ※\r\n");printf("※ _b、蜂鸣器关_ ※\r\n"); printf("※ _c、响度1 _ ※\r\n");printf("※ _d、响度2 _ ※\r\n");printf("※ _e、响度3 _ ※\r\n");printf("※ _f、返回上级菜单_ ※\r\n");printf("※※※※※※※※※※※※※※※※※※※※\r\n");
}void menu_3(void){printf("※※※※※※※※※※※※※※※※※※※※\r\n");printf("※ _播放音乐_ ※\r\n");printf("※ ※\r\n");printf("※ _a、开始播放_ ※\r\n");printf("※ _b、返回上级菜单_ ※\r\n");printf("※※※※※※※※※※※※※※※※※※※※\r\n");
}void menu_4(void){printf("※※※※※※※※※※※※※※※※※※※※\r\n");printf("※ _呼吸灯_ ※\r\n");printf("※ ※\r\n");printf("※ _a、灯控1_ ※\r\n");printf("※ _b、灯控2_ ※\r\n");printf("※ _c、灯控3_ ※\r\n");printf("※ _d、灯控4_ ※\r\n");printf("※ _e、返回上级菜单_ ※\r\n");;printf("※※※※※※※※※※※※※※※※※※※※\r\n");
}
菜单通过一个‘flag’表示来识别进入第几个菜单后会打印相应的功能菜单。之后再使用串口接收中断‘d’来执行功能,(执行第‘flag’菜单的‘d’功能)
//功能一菜单if(flag == 1){//LED_init();switch(d){case 'a': GPIO_ToggleBits(GPIOF,GPIO_Pin_9); break;case 'b': GPIO_ToggleBits(GPIOF,GPIO_Pin_10);break;case 'c': GPIO_ToggleBits(GPIOE,GPIO_Pin_13);break;case 'd': GPIO_ToggleBits(GPIOE,GPIO_Pin_14);break;case 'e': flag--;menu_start();break;}}//功能二菜单else if(flag == 2){//if(d != '6' && TIM_FLAG==1){//TIM_FLAG=0;beep_pwm_init((uint32_t)((10000/100)-1),(8400-1));//printf("已初始化\n");//}switch(d){case 'a': TIM_SetCompare1(TIM13,10);break; case 'b': TIM_SetCompare1(TIM13,0);break;case 'c': TIM_SetCompare1(TIM13,30);break;case 'd': TIM_SetCompare1(TIM13,60);break;case 'e': TIM_SetCompare1(TIM13,90);break;//case '6': TIM_FLAG+=1;beep_pwm_init((int)14399,10);musicPlay();break;case 'f': flag-=2;menu_start();break;}}功能三菜单else if(flag == 3){switch(d){case 'a'://TIM_FLAG+=1;beep_pwm_init((int)14399,10);musicPlay();break;case 'b': flag-=3;menu_start();break;}}功能四菜单else if(flag == 4){switch(d){case 'a': EXTI_FLAG=1;led_pwm_init(&gpio_9);break;case 'b': EXTI_FLAG=1;led_pwm_init(&gpio_10);break;case 'c': EXTI_FLAG=1;led_pwm_init(&gpio_13);break;case 'd': EXTI_FLAG=1;led_pwm_init(&gpio_14);break;case 'e': EXTI_FLAG=0;flag-=4;LED_init();menu_start();break;}} //清空标志位,告诉CPU,我已经完成中断处理,可以接收新的中断请求USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
4. 串口控制LED开关
从第3点可以看出,在进入菜单一,flag置1,发送‘a’,此时LED0开(‘开’引脚PF9置0;默认是高电平1),在发送‘a’LED0关。GPIO_ToggleBits(GPIOx,GPIO_Pin_x);函数是引脚电平取反函数。
5. 串口控制蜂鸣器开关及响度
选择菜单2,flag置2,进行TIM13初始化(pwm1)和蜂鸣器AF模式初始化,在判断接收到的数据‘d’,设置TIM13_CCR1比较值。
//二级菜单else if(flag == 2){//if(d != '6' && TIM_FLAG==1){//TIM_FLAG=0;beep_pwm_init((uint32_t)((10000/100)-1),(8400-1));//printf("已初始化\n");//}switch(d){case 'a': TIM_SetCompare1(TIM13,10);break; case 'b': TIM_SetCompare1(TIM13,0);break;case 'c': TIM_SetCompare1(TIM13,30);break;case 'd': TIM_SetCompare1(TIM13,60);break;case 'e': TIM_SetCompare1(TIM13,90);break;//case '6': TIM_FLAG+=1;beep_pwm_init((int)14399,10);musicPlay();break;case 'f': flag-=2;menu_start();break;}}
6. 串口控制蜂鸣器播放音乐
选择菜单3,flag置3,打印子功能菜单,选择播放音乐,进行TIM13的计数值14399和预分频值10的再次初始化。
else if(flag == 3){switch(d){case 'a'://TIM_FLAG+=1;beep_pwm_init((int)14399,10);musicPlay();break;case 'b': flag-=3;menu_start();break;}}
串口发送 ‘a’ 执行musicPlay()函数,此次用到music.h、pwm.h文件
music.h-----------------------------------------------------音名的宏定义、音符结构
//music.h//文件:music.h
#ifndef __MUSIC_H__
#define __MUSIC_H__
#include "sys.h"
// 定义低音音名(数值单位:Hz)
#define L1 262 // c
#define L2 294 // d
#define L3 330 // e
#define L4 349 // f
#define L5 392 // g
#define L6 440 // a1
#define L7 494 // b1 // 定义中音音名
#define M1 523 // c1
#define M2 587 // d1
#define M3 659 // e1
#define M4 698 // f1
#define M5 831 // g1
#define M6 932 // a2
#define M7 988 // b2 // 定义高音音名
#define H1 1047 // c2
#define H2 1175 // d2
#define H3 1319 // e2
#define H4 1397 // f2
#define H5 1568 // g2
#define H6 1760 // a3
#define H7 1976 // b3
// 定义时值单位,决定演奏速度(数值单位:ms)
#define T 3600
#define TT 2000 //定义音符结构
typedef struct {
short mName; // 音名:取值L1~L7、M1~M7、H1~H7分别表示低音、中音、高音的1234567,取值0表示休止符
short mTime; // 时值:取值T、T/2、T/4、T/8、T/16、T/32分别表示全音符、 二分音符、四分音符、八分音符 ,取值0表示演奏结束
}tNote;#endif
pwm.h------------------------------------------------------用音符结构定义歌曲
//#include "pwM.h"#include "Music.h"
#ifndef __PWM_H__
#define __PWM_H__
const tNote MyScore[] =
{
{L3, TT/4},
{M3, TT/4+TT/8},
{M2, TT/16},
{M1, TT/8},
{L7, TT/8},
{L6, TT/4},
{L6, TT/8}, //
{M1, TT/8},
{L7, TT/8},
{L6, TT/8},
{L5, TT/8},
{L6, TT/8},
{L3, TT/8},
{L2, TT/8},
{L3, TT*2}, //{0, 0} // 结束
}; #endif
播放音乐相关代码
/*******************************播放音乐************************************/
// 蜂鸣器停止发声
void buzzerQuiet(void)
{ TIM_SetCompare1(TIM13,0);//BEEP_init();
}//蜂鸣器发出指定频率的声音
//usFreq是发声频率,取值 (系统时钟/65536)+1 ~ 20000,单位:Hz
void buzzerSound(unsigned short usFreq)
{ // GPIO_InitTypeDef GPIO_InitStructure; unsigned long ulVal; if((usFreq<=8000000/65536UL)||(usFreq>20000)) { buzzerQuiet();// 蜂鸣器静音 } else{ GPIO_PinAFConfig(GPIOF,GPIO_PinSource8,GPIO_AF_TIM13);// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOF9// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //上拉 ulVal=8000000/usFreq; TIM13->ARR =ulVal; //设置自动重装载寄存器周期的值(音调) TIM_SetCompare1(TIM13,ulVal/3);//音量 TIM_Cmd(TIM13, ENABLE); //启动TIM3 }
}void musicPlay(void){ uint8_t i=0; while(1) { if (MyScore[i].mTime == 0){break;}buzzerSound(MyScore[i].mName);delay_ms(MyScore[i].mTime); i++; buzzerQuiet(); // 蜂鸣器静音 delay_ms(100);// 10 ms}
}
pwm.h歌曲定义当mTime为零时表示歌曲结束,会跳出musicPlay()中的循环,否则会将mName即频率值传参给buzzerSound()函数来实现播放这个频率值的声音,用i实现向下播放,每放完一个频率值的静音10ms。
7. 按键控制LED的亮度
选择菜单4,flag置为4,选择功能时会将EXTI_FLAG标识置为1,同时执行LED的AF模式初始化,用结构体传参来实现哪一颗LED的AF初始化,
typedef struct{char init_flag;uint16_t gpio_pin_x;uint8_t gpio_pinsource_x;}GPIO_EXTI;
结构体这中的init_flag标识GPIO的哪个端口,gpio_pin_x是哪个引脚,gpio_pinsource_x是哪个引脚连接到定时器TIM14上
定义
GPIO_EXTI gpio_9 = {'F', GPIO_Pin_9, GPIO_PinSource9};
GPIO_EXTI gpio_10 = {'F', GPIO_Pin_10, GPIO_PinSource10};
GPIO_EXTI gpio_13 = {'E', GPIO_Pin_13, GPIO_PinSource13};
GPIO_EXTI gpio_14 = {'E', GPIO_Pin_14, GPIO_PinSource14};
功能调用,结构体传址传参
else if(flag == 4){switch(d){case 'a': EXTI_FLAG=1;led_pwm_init(&gpio_9);break;case 'b': EXTI_FLAG=1;led_pwm_init(&gpio_10);break;case 'c': EXTI_FLAG=1;led_pwm_init(&gpio_13);break;case 'd': EXTI_FLAG=1;led_pwm_init(&gpio_14);break;case 'e': EXTI_FLAG=0;flag-=4;LED_init();menu_start();break;}}
led_pwm_init(GPIO_EXTI *p)函数
void led_pwm_init(GPIO_EXTI *p)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;/* 使能端口F的时钟,说白就是对端口F供电 */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE , ENABLE);/* 使能定时器14的时钟,说白就是对定时器14供电 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);/* Time base configuration,定时器基本的配置,用于配置PWM输出的频率 */TIM_TimeBaseStructure.TIM_Period = (10000/100)-1; //计数值是输出频率,当前为100Hz//这个值不能超过65535(0xFFFF)TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; //预分频值,第一次降低频率,这个值不能超过65535(0xFFFF)//TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分频,第二次降低频率,这里用不到TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数,计数到某个值之后就触发中断TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure);if(p->init_flag == 'F'){/* 配置PF9引脚为多功能模式 */GPIO_InitStructure.GPIO_Pin = p->gpio_pin_x; //第9根引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //多功能模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //[可选]推挽输出,增大输出电流GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //GPIO工作最大速度为100MHz,就是GPIO的反应速度,速度越高,反应越快,但是功耗就更高GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不需要使能上下拉电阻GPIO_Init(GPIOF, &GPIO_InitStructure); //将PF9引脚连接到定时器14GPIO_PinAFConfig(GPIOF, p->gpio_pinsource_x, GPIO_AF_TIM14); }else if(p->init_flag == 'E'){/* 配置PF9引脚为多功能模式 */GPIO_InitStructure.GPIO_Pin = p->gpio_pin_x; //第9根引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //多功能模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //[可选]推挽输出,增大输出电流GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //GPIO工作最大速度为100MHz,就是GPIO的反应速度,速度越高,反应越快,但是功耗就更高GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不需要使能上下拉电阻GPIO_Init(GPIOE, &GPIO_InitStructure); //将PF9引脚连接到定时器14GPIO_PinAFConfig(GPIOE, p->gpio_pinsource_x, GPIO_AF_TIM14);}/* PWM1 Mode configuration: Channel1,配置定时器14通道1工作在PWM1模式 */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //工作在模式1,只要计数值小于比较值,就输出高电平//计数值≥比较值,就输出低电平TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //允许脉冲输出,其实它就是一个输出开关TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性(有效的状态)为高电平//初始化定时器14通道1TIM_OC1Init(TIM14, &TIM_OCInitStructure);//初始化定时器1通道3//TIM_OC3Init(TIM1, &TIM_OCInitStructure); //定时器14自动重载功能,意思说不断输出PWM脉冲TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);TIM_ARRPreloadConfig(TIM14, ENABLE);/* TIM14 enable counter,使能定时器14工作 */TIM_Cmd(TIM14, ENABLE); TIM_CtrlPWMOutputs(TIM1,ENABLE); }
EXTI_FLAG=1的作用是用于外部中断的触发功能。置1是为了让按键KEY0、KEY1不再是控制OUT模式LED的开关,而是控制LED的亮度。KEY0是使LED变暗,KEY1是使LED变亮(循环);
//EXTI_Line0的中断服务函数
void EXTI0_IRQHandler(void)
{//获取中断的状态,检查是否有中断请求if(EXTI_GetITStatus(EXTI_Line0) == SET ){i+=25;printf("%d\n",i);if(EXTI_FLAG == 0){ GPIO_ToggleBits(GPIOF,GPIO_Pin_9);}else if(EXTI_FLAG == 1){if(i<100){TIM_SetCompare1(TIM14,i);}else{i=0;}}}//清空外部中断控制线的挂起位,告诉CPU已完成中断请求,可以接收新的中断EXTI_ClearITPendingBit(EXTI_Line0);
}//EXTI_Line2的中断服务函数
void EXTI2_IRQHandler(void)
{//获取中断的状态,检查是否有中断请求if(EXTI_GetITStatus(EXTI_Line2) == SET ){printf("%d\n",i);i-=25;if(EXTI_FLAG == 0){GPIO_ToggleBits(GPIOF,GPIO_Pin_10);}else if(EXTI_FLAG == 1){if(i>-1){TIM_SetCompare1(TIM14,i);}else{i=100;}}}//清空外部中断控制线的挂起位,告诉CPU已完成中断请求,可以接收新的中断EXTI_ClearITPendingBit(EXTI_Line2);
}
5 使用说明
将程序成功烧写进开发板,连接串口助手在开发板上输入密码1122,进入主功能菜单,同时开发板0、1、2、3按键分别可控制LED1、LED2、LED3、LED4的开关直至没有进入灯控功能前都有效,出来功能4也有效。
※※※※※※※※※※※※※※※※※※※※
※ 功能菜单 ※
※ ※
※ 1、LED的开关 ※
※ 2、蜂鸣器开关,响度 ※
※ 3、音乐 ※
※ 4、灯控 ※
※※※※※※※※※※※※※※※※※※※※
1、LED的开关
在输入界面发送“1”进入功能LED的开关
※※※※※※※※※※※※※※※※※※※※
※ LED的开关 ※
※ ※
※ a、控制灯1 ※
※ b、控制灯2 ※
※ c、控制灯3 ※
※ d、控制灯4 ※
※ e、返回上级菜单 ※
※※※※※※※※※※※※※※※※※※※※
发送“a”LED1亮,再次发送“a”LED1灭
发送“b”LED2亮,再次发送“b”LED2灭
发送“c”LED3亮,再次发送“c”LED3灭
发送“d”LED4亮,再次发送“d”LED4灭
发送“e”退出当前功能界面返回主功能菜单
*注:发送指令为“abcd”,同时控制4个LED的亮灭
灯亮时发送指令灯灭,灯灭时发送指令灯亮
2、蜂鸣器的开关、响度
在输入界面发送“2”进入功能蜂鸣器的开关、响度
※※※※※※※※※※※※※※※※※※※※
※ 蜂鸣器的开关,响度 ※
※ ※
※ a、蜂鸣器开 ※
※ b、蜂鸣器关 ※
※ c、响度1 ※
※ d、响度2 ※
※ e、响度3 ※
※ f、返回上级菜单 ※
※※※※※※※※※※※※※※※※※※※※
发送“a”蜂鸣器开,发送“b”蜂鸣器关
“c、d、e”控制蜂鸣器的响度,响度从下递增
发送“f”退出当前功能界面返回主功能菜单
3、音乐
在输入界面发送“3”进入功能音乐
※※※※※※※※※※※※※※※※※※※※
※ 播放音乐 ※
※ ※
※ a、开始播放 ※
※ b、返回上级菜单 ※
※※※※※※※※※※※※※※※※※※※※
发送“a”开始播放音乐
发送“b” 退出当前功能界面返回主功能菜单
4、灯控
在输入界面发送“4”进入功能灯控
※※※※※※※※※※※※※※※※※※※※
※ 呼吸灯 ※
※ ※
※ a、灯控1 ※
※ b、灯控2 ※
※ c、灯控3 ※
※ d、灯控4 ※
※ e、返回上级菜单 ※
※※※※※※※※※※※※※※※※※※※※
发送“a”可控制LED1,
发送“b” 可控制LED2,
发送“c” 可控制LED3,
发送“d” 可控制LED4,
开发板按键“1”增加灯的亮度, “0”减少灯的亮度(开发板按键“1”或“0”可单键循环调节LED灯的亮度)
发送“e”退出当前功能界面返回主功能菜单
*注:在1、2、3、4功能中开发板的按键0、1、2、3皆能控制LED1、LED2、LED3、LED4等的开关及亮度
6. 可能遇到的问题
- 没有打印消息-------------选上”Use MicroLIB”
- 打印信息乱码-------------把有打印消息的.c文件用记事本打开然后另存为,编码格式选成“ANSI编码”,或者是外部晶振频率不对,修改方法如下
我用的板子是8MHz,就修改stm32f4xx.h以下内容,行127将外部晶振频率值修改为8MHz。
#if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */#endif /* HSE_VALUE */
7. 播放音乐参考代码:
http://blog.sina.com.cn/s/blog_e24e6e650102wxv6.html
感谢Ta的贡献。
STM32F40实现 按键密码锁、按键控制LED 、串口选择菜单 、串口控制LED开关 、串口控制蜂鸣器开关及响度 、串口控制蜂鸣器播放音乐 、按键控制LED的亮度相关推荐
- 【Arduino】一个按键开关控制RGB音乐彩灯(蜂鸣器播放音乐+按键控制播放暂停+RGB彩灯随音乐节奏跳动)
一.项目说明 这里我们需要使用到RGB LED.蜂鸣器.按键开关这个元件.为什么要叫RGB呢?是因为这个LED是由红(Red).绿(Green)和蓝(Blue)三种颜色组成.我们可以通过调整三个LED ...
- Arduino按键控制MP3模块随机播放音乐(YX5300 MP3音乐模块)
设计者:STCode (公众号同名) 1)功能描述 这个设计主要是通过按键来控制播放音乐,主要涉及到的内容有按键和YX5300 MP3音乐模块的使用,通过按压按键来达到随机播放音乐曲目的目的. 2)使 ...
- 1.可选择8种节日彩灯模式; 2.可调节彩灯流动方向; 3.可调节彩灯流动速度; 4.独立按键启动/停止蜂鸣器播放音乐; 5.通过电位器控制音量;...
这是一个关于节日彩灯的设备的描述,具有以下功能: 可以选择8种不同的节日彩灯模式: 可以调整彩灯流动的方向: 可以调整彩灯流动的速度: 有一个独立按键,可以启动或停止蜂鸣器播放音乐: 可以通过电位器来 ...
- Flash:关键帧中调用自建的音乐类,进行播放、关闭、循环音乐+按键播放或者关闭外部音乐+循环播放背景音乐+播放按钮音乐+停止+加载外部音乐文件+AS2播放背景音乐
目录 一.关键帧里面:调用自建的音乐类, 循环播放外部音乐.进行播放.关闭.循环音乐 1.代码:自建音乐类 2.关键帧中创建.播放.暂停背景音乐+按钮音乐 3.文件布置 二.关键帧中:按键播放或者关闭 ...
- 【51MCU】51单片机定时器中断写MIDI音乐(按键可切换音乐)
Author: Manba Cople 专业:IOT 说明:记录和输出学习内容 文章目录 前言 定时器 音乐播放 音乐库 总结和展望 前言 程序思路:该程序是利用51单片机的定时器中断,另外根据音符的 ...
- UART0串口编程(五):串口编程(UART0)之UC/OS(一)UC/OS下的串口发送任务编程
UART0串口编程(五) 串口编程(UART0)之UC/OS(一) 一.在UC/OS中设计串口程序所要考虑的问题 1. 串口通信数据以帧为单位进行处理,如果需要接收大量数据,则帧缓冲区规模必然 ...
- linux pwm控制蜂鸣器 滴滴_兴安盟KOBISHI电磁蜂鸣器BZ-21BLAC24V保证
兴安盟KOBISHI电磁蜂鸣器BZ-21BLAC24V保证日本KOBISHI蜂鸣器.jjb器 .蜂鸣器BZ-35VR DC24V.济南千斗工业出售,货期短.价格低.保证 这里只对必须用1/2duty的 ...
- android 如何去控制第三方音乐播放app之控制QQ音乐
最近在做一个需求,要在桌面去控制qq音乐的播放(即,可以播放暂停,上一曲,下一曲显示歌名和歌手名).接下来一一说下完成这个需求的心路历程. 1.在网上查腾讯有没有针对qq音乐提供SDK接口,结果发现, ...
- BLE-HID 音乐/相机控制
以SDK下自带的 HID 鼠标示例为例说明: 音乐控制: 代码中 main中调用了services_init初始化几个服务. 其中调用hids_init 来初始化hid服务 函数中首先定义了 s ...
最新文章
- springboot国际化i18n
- 使用xib封装一个view的步骤
- 视觉SLAM回环检测、词袋模型和视觉位置识别--论文记录和实验简析
- Qt之Q_GLOBAL_STATIC创建全局静态对象
- 【已解决】tomcat报严重: Socket accept failed
- BLE CC2541 串口BootLoader 即 SBL BootLoader 资料 收集
- 常见中文NER数据集大盘点
- php 调用带返回多个结果集的方法,PHP中有多个结果集?
- 计算机四级网络工程师考点速查,计算机四级《网络工程师》考点习题
- 1600802047 android 第三次作业(音乐播放器)
- LSOF 安装与使用
- jQuery 文档操作方法 (四)
- sqlserver 提示“用户sa 登录失败 18456”问题解决过程
- oracle ovm配置使用
- 极速狂飙 无线网BT下载使用技巧全攻略
- Laravel Collect集合用pluck取多维数组中某个字段值
- linux 添加开机启动项的三种方法。
- SpringMVC条件查询+分页时下一页丢失查询条件
- 阿里云支持备案云产品列表(不只是云服务器)
- 2023年上海国际车展展中新车报告
热门文章
- Swagger3实现API文档管理:让前后端合作更加顺畅
- c++课设学生成绩与学籍管理系统
- android开发之popupwindow半透明
- 计算机开启telnet服务,telnet服务-开启telnet服务对电脑有何危害
- 极米刷鸿蒙系统,极米科技再创经典,极米RS Pro 2让用户尊享旗舰级体验
- java23种设计模式(追妹妹版)
- python 批量读取电脑文件夹内视频,获取视频分辨率,过滤删除分辨率较小的文件
- miniui的ajax组件,标签:miniui控件
- 风口浪尖上的王者“农药”该何去何从?
- ELK 搭建成功过程