本人第一次发文,很多都不懂,尤其害怕版权问题,如果有人质疑我有盗权行为,请联系我,因为项目也遇到很多问题,然后就解决嘛,可印象中只有播放音乐代码有借鉴,所以如果有质疑盗了权的,请务必联系我。板子是使用粤嵌科技的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 功能

  1. 按键密码锁
  2. 按键控制LED开关
  3. 串口选择菜单
  4. 串口控制LED开关
  5. 串口控制蜂鸣器开关及响度
  6. 串口控制蜂鸣器播放音乐
  7. 按键控制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的亮度相关推荐

  1. 【Arduino】一个按键开关控制RGB音乐彩灯(蜂鸣器播放音乐+按键控制播放暂停+RGB彩灯随音乐节奏跳动)

    一.项目说明 这里我们需要使用到RGB LED.蜂鸣器.按键开关这个元件.为什么要叫RGB呢?是因为这个LED是由红(Red).绿(Green)和蓝(Blue)三种颜色组成.我们可以通过调整三个LED ...

  2. Arduino按键控制MP3模块随机播放音乐(YX5300 MP3音乐模块)

    设计者:STCode (公众号同名) 1)功能描述 这个设计主要是通过按键来控制播放音乐,主要涉及到的内容有按键和YX5300 MP3音乐模块的使用,通过按压按键来达到随机播放音乐曲目的目的. 2)使 ...

  3. 1.可选择8种节日彩灯模式; 2.可调节彩灯流动方向; 3.可调节彩灯流动速度; 4.独立按键启动/停止蜂鸣器播放音乐; 5.通过电位器控制音量;...

    这是一个关于节日彩灯的设备的描述,具有以下功能: 可以选择8种不同的节日彩灯模式: 可以调整彩灯流动的方向: 可以调整彩灯流动的速度: 有一个独立按键,可以启动或停止蜂鸣器播放音乐: 可以通过电位器来 ...

  4. Flash:关键帧中调用自建的音乐类,进行播放、关闭、循环音乐+按键播放或者关闭外部音乐+循环播放背景音乐+播放按钮音乐+停止+加载外部音乐文件+AS2播放背景音乐

    目录 一.关键帧里面:调用自建的音乐类, 循环播放外部音乐.进行播放.关闭.循环音乐 1.代码:自建音乐类 2.关键帧中创建.播放.暂停背景音乐+按钮音乐 3.文件布置 二.关键帧中:按键播放或者关闭 ...

  5. 【51MCU】51单片机定时器中断写MIDI音乐(按键可切换音乐)

    Author: Manba Cople 专业:IOT 说明:记录和输出学习内容 文章目录 前言 定时器 音乐播放 音乐库 总结和展望 前言 程序思路:该程序是利用51单片机的定时器中断,另外根据音符的 ...

  6. UART0串口编程(五):串口编程(UART0)之UC/OS(一)UC/OS下的串口发送任务编程

    UART0串口编程(五) 串口编程(UART0)之UC/OS(一) 一.在UC/OS中设计串口程序所要考虑的问题 1.     串口通信数据以帧为单位进行处理,如果需要接收大量数据,则帧缓冲区规模必然 ...

  7. linux pwm控制蜂鸣器 滴滴_兴安盟KOBISHI电磁蜂鸣器BZ-21BLAC24V保证

    兴安盟KOBISHI电磁蜂鸣器BZ-21BLAC24V保证日本KOBISHI蜂鸣器.jjb器 .蜂鸣器BZ-35VR DC24V.济南千斗工业出售,货期短.价格低.保证 这里只对必须用1/2duty的 ...

  8. android 如何去控制第三方音乐播放app之控制QQ音乐

    最近在做一个需求,要在桌面去控制qq音乐的播放(即,可以播放暂停,上一曲,下一曲显示歌名和歌手名).接下来一一说下完成这个需求的心路历程. 1.在网上查腾讯有没有针对qq音乐提供SDK接口,结果发现, ...

  9. BLE-HID 音乐/相机控制

    以SDK下自带的 HID 鼠标示例为例说明: 音乐控制: 代码中 main中调用了services_init初始化几个服务. 其中调用hids_init 来初始化hid服务 函数中首先定义了    s ...

最新文章

  1. springboot国际化i18n
  2. 使用xib封装一个view的步骤
  3. 视觉SLAM回环检测、词袋模型和视觉位置识别--论文记录和实验简析
  4. Qt之Q_GLOBAL_STATIC创建全局静态对象
  5. 【已解决】tomcat报严重: Socket accept failed
  6. BLE CC2541 串口BootLoader 即 SBL BootLoader 资料 收集
  7. 常见中文NER数据集大盘点
  8. php 调用带返回多个结果集的方法,PHP中有多个结果集?
  9. 计算机四级网络工程师考点速查,计算机四级《网络工程师》考点习题
  10. 1600802047 android 第三次作业(音乐播放器)
  11. LSOF 安装与使用
  12. jQuery 文档操作方法 (四)
  13. sqlserver 提示“用户sa 登录失败 18456”问题解决过程
  14. oracle ovm配置使用
  15. 极速狂飙 无线网BT下载使用技巧全攻略
  16. Laravel Collect集合用pluck取多维数组中某个字段值
  17. linux 添加开机启动项的三种方法。
  18. SpringMVC条件查询+分页时下一页丢失查询条件
  19. 阿里云支持备案云产品列表(不只是云服务器)
  20. 2023年上海国际车展展中新车报告

热门文章

  1. Swagger3实现API文档管理:让前后端合作更加顺畅
  2. c++课设学生成绩与学籍管理系统
  3. android开发之popupwindow半透明
  4. 计算机开启telnet服务,telnet服务-开启telnet服务对电脑有何危害
  5. 极米刷鸿蒙系统,极米科技再创经典,极米RS Pro 2让用户尊享旗舰级体验
  6. java23种设计模式(追妹妹版)
  7. python 批量读取电脑文件夹内视频,获取视频分辨率,过滤删除分辨率较小的文件
  8. miniui的ajax组件,标签:miniui控件
  9. 风口浪尖上的王者“农药”该何去何从?
  10. ELK 搭建成功过程