附1:源程序代码
#include
#define keyport P1 //手动按键连接的I/O口 #define uchar unsigned char #define uint unsigned int uchar high,low; //定时器预装值的高8位和低8位 sbit speak=P3^0; //蜂鸣器输出 sbit gao=P3^5; //高音切换键 sbit di=P3^6; //低音切换键 sbit zdbf=P3^7; //自动播放切换键 uchar yinjie=1; uchar time; uchar n=0;
uchar code fre[][2]= { 0xf3,0xf8, 0x5b,0xf9, 0x15,0xfa, 0x67,0xfa, 0x04,0xfb, 0xae,0xfb, 0x0c,0xfc, 0x90,0xfc, 0xac,0xfc, 0x09,0xfd, 0x52,0xfd, 0x82,0xfd, 0xd6,0xfd, 0x06,0xfe, 0x22,0xfe, 0x56,0xfe, 0x85,0xfe, 0x9a,0xfe, 0xc1,0xfe, 0xec,0xfe, 0x03,0xff, }; void delay(uint );
void ITimer0(void);//定时器初始化 void key(void); void dtxs(int,int); void song()
36
//低音 //中音 //高音 {
TH0=high; TL0=low; TR0=1;
delay(time*240); }
void yinyue()//自动播放子程序 {
uchar code hls[]={ 5,2,2, 3,2,1, 5,2,1, 1,3,4, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 1,2,1, 2,2,1 ,3,2,2 ,2,2,1,
1,2,1 ,2,2,6, 5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1, 1,2,6, 6,2,2, 1,3,2, 1,3,4, 7,2,2, 6,2,1, 7,2,1, 1,3,4 ,6,2,1,
7,2,1, 1,3,1 ,6,2,1, 6,2,1 ,5,2,1 ,3,2,1, 1,2,1, 2,2,6, 5,2,2, 3,2,1, 1,2,1, 1,3,3, 7,2,1, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1, 1,2,6
}; uchar m; n=0;
while(n<174) { m=hls[n]+7*(hls[n+1]-1)-1; high=fre[m][1]; low=fre[m][0]; time=hls[n+2]; n=n+3; song(); } } void main (void) { uchar num; ITimer0(); speak=0; while(1) { key(); switch(keyport) //扫描手动按键并发声和显示 { case 0xfe:num=1;break; case 0xfd:num=2;break; case 0xfb:num= 3;break; case 0xf7:num= 4;break;
37
case 0xef:num= 5;break; case 0xdf:num= 6;break; case 0xbf:num= 7;break; case 0x7f:num= 8;break; default:num= 0;break; } if(num==0) { TR0=0; speak=0; } else { high=fre[7*yinjie+num-1][1]; low=fre[7*yinjie+num-1][0]; TR0=1; } dtxs(yinjie,num); } }
void ITimer0(void) //定时器初始化 {
TMOD |= 0x01; //使用模式1,16位定时器,使用\符号可以在使用多个定时器时不受影响
EA=1; //总中断打开 ET0=1; //定时器中断打开 TR0=1; //定时器开关打开 }
void Timer0_isr(void) interrupt 1 //定时器0中断服务程序 {
TH0=high; TL0=low; speak=!speak; if(zdbf==0) { delay(100); if(zdbf==0) { delay(100); if(n<174)n=500; //n赋值大于174,跳出while,停止音乐 else n=0; }
38
}/**/ }
void key() //控制切换键扫描程序 { if(zdbf==0)
{delay(100); if(zdbf==0) yinyue(); } if(gao==0) { delay(100); if(gao==0) { delay(100); if(yinjie==2) yinjie=1; else yinjie=2; } }
if(di==0) { delay(100); if(di==0) { delay(100); if(yinjie==0) yinjie=1; else yinjie=0; } } }
void delay(unsigned int x) //延时子程序 { int a,b;
for(a=x;a>0;a--) for(b=110;b>0;b--); }
void dtxs(k,l) //显示子程序 {
char seg[14]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e}; P2=0x01;//选择第一个数码管
39
P0=seg[k+10];//显示工作方式 delay(4);
P2=0x02;//选择第二个数码管 P0=seg[l];//显示按键号 delay(4); }
40
附2:系统原理图
41