博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32F40实现 按键密码锁、按键控制LED 、串口选择菜单 、串口控制LED开关 、串口控制蜂鸣器开关及响度 、串口控制蜂鸣器播放音乐 、按键控制LED的亮度
阅读量:4299 次
发布时间:2019-05-27

本文共 18698 字,大约阅读时间需要 62 分钟。

本人第一次发文,很多都不懂,尤其害怕版权问题,如果有人质疑我有盗权行为,请联系我,因为项目也遇到很多问题,然后就解决嘛,可印象中只有播放音乐代码有借鉴,所以如果有质疑盗了权的,请务必联系我。板子是使用粤嵌科技的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);		}					//判断密码是否正确 密码1122		if(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引脚连接到定时器14		GPIO_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引脚连接到定时器14		GPIO_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通道1	TIM_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的贡献。

转载地址:http://aupws.baihongyu.com/

你可能感兴趣的文章
MySQL 查看执行计划
查看>>
OpenGL ES 3.0(四)图元、VBO、VAO
查看>>
OpenGL ES 3.0(五)纹理
查看>>
OpenGL ES 3.0(八)实现带水印的相机预览功能
查看>>
OpenGL ES 3.0(九)实现美颜相机功能
查看>>
FFmpeg 的介绍与使用
查看>>
Android 虚拟机简单介绍——ART、Dalvik、启动流程分析
查看>>
原理性地理解 Java 泛型中的 extends、super 及 Kotlin 的协变、逆变
查看>>
FFmpeg 是如何实现多态的?
查看>>
FFmpeg 源码分析 - avcodec_send_packet 和 avcodec_receive_frame
查看>>
FFmpeg 新旧版本编码 API 的区别
查看>>
RecyclerView 源码深入解析——绘制流程、缓存机制、动画等
查看>>
Android 面试题整理总结(一)Java 基础
查看>>
Android 面试题整理总结(二)Java 集合
查看>>
学习笔记_vnpy实战培训day02
查看>>
学习笔记_vnpy实战培训day03
查看>>
VNPY- VnTrader基本使用
查看>>
VNPY - CTA策略模块策略开发
查看>>
VNPY - 事件引擎
查看>>
MongoDB基本语法和操作入门
查看>>