笔记 15-3 : 彭老师课本第 7 章, 中断,键盘 key 编程与轮询 :具体的代码实现

(114)配置该按键的初始化

++ 以及

++ 中断逻辑

++ 接着看下与讯为板的差异 :

(115)接着学习按键的轮询逻辑

(116)老师布置了作业,可以把蜂鸣声改为音乐,《大海》,代码如下 :

c 复制代码
#include "exynos_4412.h"

void  delay_ms(unsigned int num)
{
    int i,j;
    for(i=num; i>0;i--)
	for(j=1000;j>0;j--)
		;
}
void pwm_init(void)
{
	GPD0.CON = GPD0.CON & (~(0xf))| 0x2;
	GPD0.PUD = GPD0.PUD & (~(0xf)) | 0x3;
	PWM.TCFG0 = PWM.TCFG0 & (~(0xff))|0xff;
	PWM.TCFG1 = PWM.TCFG1 & (~(0xf)) | 0x2;
	PWM.TCMPB0 = 50;
	PWM.TCNTB0 = 100;
	PWM.TCON = PWM.TCON & (~(0xff)) | (1 << 0) | (1 << 1) ;
}
void beep_on(void)
{
	PWM.TCON = PWM.TCON & (~(0xff)) | (1 << 0) | (1 << 3) ;
}
void beep_off(void)
{
	PWM.TCON = PWM.TCON & (~(1 << 0)) ;
}
#define SYS_SET_FREQUENCE 25000
void beep_set_frequence( unsigned int fre )
{
	//若蜂鸣器的发声频率为0则返回
	if( 0==fre )
		return ;

	PWM.TCMPB0 =  SYS_SET_FREQUENCE/(fre+fre);   //根据设定频率重新设定计数器比较的值
	PWM.TCNTB0 =  SYS_SET_FREQUENCE/fre;			//根据频率重新调整计数值

}
const unsigned char dahai[] =
{
	0x13,  0x15 , 0x16, 0x16, 0x16, 0x16, 0x21, 0x16, 0x15, 0x15, 0x16, 0x15,  //哀愁
	0x13,  0x12 , 0x11, 0x11, 0x11, 0x11, 0x12, 0x13,
	0x13,  0x12 , 0x11, 0x11, 0x11, 0x11, 0x21, 0x16, 0x15, 0x15, 0x16, 0x15,
	0x13,  0x15,  0x16, 0x21, 0x21, 0x16, 0x15, 0x15,//飘远
};

/*
 * 大海的简谱, 控制每一个音的时间 1为长时间 4为短时间
 */
const unsigned char time[] =
{
	4,		4,   4,     2,    4 ,   2,    4,     4,    4,    2,    4,    2 ,//哀愁
	4,      4,   4,     2,    4,    2,    2,     1,
	4,      4,   4,     2,    4,    2,    4,     4,     4,   2,    4,    2,
	4,      4,   2,      4,   2,     4,   4,     1  //飘远

};
const unsigned int yinyue[3][7]
={
	262,  294,  330,  370,  415,  266,  294,  //低音
	523,  578,  659,  698,  784,  880,  988,  //中音
	1046, 1174, 1318, 1396, 1567, 1700, 1975  //高音
};

void led_init(void)
{
	GPK1.CON = (GPK1.CON & (~(0xf << 4))) | (0x1 << 4);
	GPX3.CON = (GPX3.CON & (~(0xf << 4))) | (0x1 << 4);
}
void led_on()
{
	GPK1.DAT = GPK1.DAT | (0x1 << 1);
	GPX3.DAT = GPX3.DAT | (0x1 << 1);
}
void led_off()
{
	GPK1.DAT = GPK1.DAT & (~(0x01 << 1));
	GPX3.DAT = GPX3.DAT & (~(0x01 << 1));
}
/*
 *  裸机代码,不同于LINUX 应用层, 一定加循环控制
 */
int main (void)
{
	unsigned int loop = 0;   //循环控制变量
	unsigned int a = 0;      //计算高中低音使用的变量
	unsigned int b = 0;		 //计算do re mi ....使用的变量
	unsigned int delay = 0;  //计算每一个音延时使用的变量

	led_init();
	pwm_init();
	GPX1.CON = GPX1.CON &(~(0xf<<4))|0x0<<4; //按键初始化
	while(1)
	{
	    if(!(GPX1.DAT & (0x1<<1)))  // 返回为真,按键按下
	    {
	    	delay_ms(10);
	        if(!(GPX1.DAT & (0x1<<1))) //二次检测,去抖
	        {
				led_on();
	            delay_ms(500);
				led_off();

				for (loop = 0;   // 在播放每个音节的时候,也检查按键是否被压下即可
					loop < sizeof(dahai) / (sizeof(unsigned char)) && !(GPX1.DAT & (0x1 << 1)); 
					loop++)
				{
					//查大海的简谱表
					a = dahai[loop] >> 4;       		    //计算出高低音
					b = (dahai[loop] & 0x0f) - 1;  	    //计算出DO RE MI FA SO LA XI
					delay = 0x1500 / time[loop];
					beep_set_frequence(yinyue[a][b]); //重新设定频率
					beep_on();			//发出一个音
					delay_ms(delay);

					beep_off();         //关闭蜂鸣器, 每个音播放完成后有间隔感
					//	delay_ms(0x10);   //关闭蜂鸣器
					delay_ms(100);
				}

	        }
	    }
	}
   return 0;
}

(117)

谢谢