|
电子琴仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源码:
- /*
- 名称:简易电子琴设计
- 说明:本程序运行时,按下矩阵键盘中的按键,数码管会显示当前的按键值,蜂鸣器会播放对应的音符
- */
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define KeyIO P1 //矩阵键盘的控制IO
- sbit BEEP = P3^4; //蜂鸣器对应的控制IO
- sbit L1=P1^0;
- sbit L2=P1^1 ;
- sbit L3=P1^2 ;
- sbit L4=P1^3 ;
- uchar code string[] = {0x01,0x03,
- 0x07,0x0f,0x1f,0x3f,0x7f,0xff};
- uchar code dis[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- //各音符对应的延时
- uint code Table_Tone[] = {
- 63628,63835,64021,64103,
- 64260,64400,64524,64580};
- uchar KeyNo; //按键序号
- /** 延时子函数 **/
- void DelayMS(uchar time)
- {
- uchar i;
- while(time--)
- {
- for(i=0; i<120; i++);
- }
- }
- /** 矩阵键盘的扫描子函数 **/
- void Key_Scan(void)
- {
- uchar temp,i;
- uchar Num;
- P1=0xfe;
- for(i=0;i<=3;i++)
- {
- if(L1==0)Num=dis[i*4+0];
- if(L2==0)Num=dis[i*4+1];
- if(L3==0)Num=dis[i*4+2];
- if(L4==0)Num=dis[i*4+3];
- DelayMS(5);
- temp=P1;
- temp=temp|0x0f;
- temp=temp<<1;
- temp=temp|0x0f;
- P1=temp;
- }
- // uchar Temp, Num;
- //
- // P1 = 0x0f; //高四位置 0 ,放入四列
- //
- // DelayMS(2);
- // //按键按下后 00001111 将变成 0000XXXX,X 中 1 个为 0,3个仍为 1
- // Temp = KeyIO ^ 0x0f; //异或操作会把 3 个 1 变成 0,唯一的 0 变成 1
- //
- // switch(Temp)
- // {
- // case 1 : Num = 0; break;
- // case 2 : Num = 1; break;
- // case 4 : Num = 2; break;
- // case 8 : Num = 3; break;
- // default : return;
- // }
- //
- // KeyIO = 0xf0; //低四位置 0 ,放入四列
- //
- // DelayMS(2);
- // //按键按下后 11110000 将变成 XXXX0000,X 中 1 个为 0,3个仍为 1
- // Temp = (KeyIO >> 4) ^ 0x0f; //将高四位移至低四位,并将其中唯一的 0 变为 1,其余为 0
- //
- // switch (Temp)
- // {
- // case 1 : Num += 0; break;
- // case 2 : Num += 4; break;
- // case 4 : Num += 8; break;
- // case 8 : Num += 12; break;
- // default : return;
- // }
- // KeyNo = Num;
- }
- void led_shi()
- {
- uchar n;
- for(n=0;n<40;n++)
- {
- P0=string[KeyNo];
- P2=0x00;
- }
- }
- /** 定时器 0 中断服务程序,不同频率的声音由该中断产生 **/
- void Play_Tone() interrupt 1
- {
- TH0 = Table_Tone[KeyNo] / 256;
- TL0 = Table_Tone[KeyNo] % 256;
- BEEP = ~BEEP;
- }
- /** 主函数 **/
- void main(void)
- {
- TMOD = 0x01;
- IE = 0x82;
- while(1)
- {
- KeyIO = 0xf0; //发送扫描码
- if (KeyIO != 0xf0) //如果有按键按下
- {
- Key_Scan(); //矩阵键盘的扫描
- led_shi();
- TR0 = 1; //启动定时器,并发出对应的声音
- }
- else
- {
- TR0 = 0; //停止播放声音
- }
- DelayMS(2);
- }
- }
复制代码
|
-
-
110.zip
132.07 KB, 下载次数: 102, 下载积分: 黑币 -5
|