热门搜索 :
考研考公
您的当前位置:首页正文

西安思源学院

来源:伴沃教育
西安思源学院 精品课程 单片机原理与应用

子项目四:电子琴

目标:

通过完成音频的输出和电子琴的综合设计, 使学生进一步掌握keilC编译器的使用和proteus仿真软件进行仿真的基本过程。进一步了解单片机C51程序设计基础,了解单片机内部结构、存储器地址分配、并行I/O口的结构与工作原理、循环程序的设计。

任务:

由易到难设计滴、滴报警声的输出,叮咚门铃和电子琴掌握音符的输出控制。 一、原理 1、滴、滴报警声

用 AT89S51 单片机产生“嘀、嘀、…”报警声从 P1.0 端口输出,产生频率为 1KHz, 根据上面图可知:1KHZ方波从 P1.0 输出 0.2 秒,接着 0.2 秒从 P1.0输出电平信号,如此循环下去,就形成我们所需的报警声了。

2、叮咚门铃

当按下开关 SP1,AT89S51 单片机产生“叮咚”声从 P1.0 端口输出,经过放大之后送入喇叭。

3、电子琴

由 4X4 组成 16 个按钮矩阵,设计成 16 个音,可随意弹奏想要表达的音乐。

二、原理图绘制 1、滴、滴报警声

西安思源学院 精品课程 单片机原理与应用

2、叮咚门铃

3、电子琴

西安思源学院 精品课程 单片机原理与应用

三、程序设计 

(1)滴、滴报警声 

1、生活中我们常常到各种各样的报警声,例如“嘀、嘀、…”就是常见的一种声音报警声,但对于这种报警声,嘀 0.2 秒钟,然后断 0.2 秒钟,如此循环下去,假设嘀声的频率为 1KHz,则报警声时序图如下图所示: 

 

上述波形信号如何用单片机来产生呢? 

由于要产生上面的信号,我们把上面的信号分成两部分,一部分为 1KHZ 方波,占用时间为 0.2 秒;另一部分为电平,也是占用0.2秒;因此,我们利用单片机的定时/计数器 T0 作为定时,可以定时 0.2 秒;同时,也要用单片机产生 1KHZ的方波,对于 1KHZ 的方波信号周期为 1ms,高电平占用 0.5ms,低电平占用 0.5ms,因此也采用定时器 T0 来完成 0.5ms 的定时;最后,可以选定定时/计数器 T0 的定时时间为 0.5ms, 而要定时 0.2 秒则是 0.5ms 的 400 倍, 也就是说以 0.5ms 定时 400次就达到 0.2秒的定时时间了。 2、程序框图 主程序框图 

 

中断服务程序框图 

 

西安思源学院 精品课程 单片机原理与应用

3、汇编源程序  

T02SA EQU 30H  T02SB EQU 31H  FLAG BIT 00H  ORG 00H  LJMP START  ORG 0BH  LJMP INT_T0  

START: MOV T02SA,#00H  MOV T02SB,#00H  CLR FLAG  

MOV TMOD,#01H  

MOV TH0,#(65536-500) / 256  MOV TL0,#(65536-500) MOD 256  SETB TR0  SETB ET0  SETB EA  SJMP ¥  INT_T0:  

MOV TH0,#(65536-500) / 256  MOV TL0,#(65536-500) MOD 256  INC T02SA  MOV A,T02SA  

CJNE A,#100,NEXT  INC T02SB  MOV A,T02SB  

CJNE A,#04H,NEXT  MOV T02SA,#00H  MOV T02SB,#00H  CPL FLAG  

NEXT: JB FLAG,DONE  CPL P1.0  DONE: RETI  END 

4、 C 语言源程序  

 #include <AT89X51.H>  unsigned int t02s;  unsigned char t05ms;  bit flag;  

void main(void)  {  

TMOD=0x01;  

TH0=(65536-500)/256;  TL0=(65536-500)%256;  

西安思源学院 精品课程 单片机原理与应用

TR0=1;  ET0=1;  EA=1;  while(1);  }  

void t0(void) interrupt 1 using 0  {  

TH0=(65536-500)/256;  TL0=(65536-500)%256;  t02s++;  

if(t02s==400) {  

t02s=0;  flag= ̄flag;  }  

if(flag==0)  {  

P1_0= ̄P1_0;  }  }  

(2)叮咚门铃 

1、我们用单片机实定时/计数器 T0 来产生 700HZ和 500HZ的频率, 根据定时/计数器T0,我们取定时 250us,因此,700HZ的频率要经过3 次 250us 的定时,而 500HZ的频率要经过 4 次 250us 的定时。在设计过程,只有当按下 SP1 之后,才启动 T0 开始工作,当 T0 工作完毕,回到最初状态。“叮”和“咚”声音各占用 0.5 秒,因此定时/计数器 T0 要完成 0.5 秒的定时,对于以 250us 为基准定时2000 次才可以。 2、程序框图 主程序框图 

 

西安思源学院 精品课程 单片机原理与应用

T0中断服务程序框图 

 

 

3、汇编源程序  T5HZ EQU 30H  T7HZ EQU 31H  T05SA EQU 32H  T05SB EQU 33H  FLAG BIT 00H  STOP BIT 01H  SP1 BIT P3.7  ORG 00H  LJMP START  ORG 0BH  LJMP INT_T0  

START: MOV TMOD,#02H  MOV TH0,#06H  MOV TL0,#06H  SETB ET0  SETB EA  

NSP: JB SP1,NSP  LCALL DELY10MS  JB SP1,NSP  

西安思源学院 精品课程 单片机原理与应用

SETB TR0  

MOV T5HZ,#00H  MOV T7HZ,#00H  MOV T05SA,#00H  MOV T05SB,#00H  CLR FLAG  CLR STOP  JNB STOP,¥  LJMP NSP  

DELY10MS: MOV R6,#20  D1: MOV R7,#248  DJNZ R7,¥  DJNZ R6,D1  RET  

INT_T0: INC T05SA  MOV A,T05SA  

CJNE A,#100,NEXT  MOV T05SA,#00H  INC T05SB MOV A,T05SB  CJNE A,#20,NEXT  MOV T05SB,#00H  JB FLAG,STP  CPL FLAG  LJMP NEXT  

STP: SETB STOP  CLR TR0  LJMP DONE  

NEXT: JB FLAG,S5HZ  INC T7HZ  MOV A,T7HZ  

CJNE A,#03H,DONE  MOV T7HZ,#00H  CPL P1.0  LJMP DONE  

S5HZ: INC T5HZ  MOV A,T5HZ  

CJNE A,#04H,DONE  MOV T5HZ,#00H  CPL P1.0  LJMP DONE  DONE: RETI  END 

4、 C 语言源程序 

西安思源学院 精品课程 单片机原理与应用

#include unsigned char t5hz; unsigned char t7hz; unsigned int tcnt; bit stop; bit flag;

void main(void) {

unsigned char i,j; TMOD=0x02; TH0=0x06; TL0=0x06; ET0=1; EA=1; while(1) {

if(P3_7==0) {

for(i=10;i>0;i--) for(j=248;j>0;j--); if(P3_7==0) {

t5hz=0; t7hz=0; tcnt=0; flag=0; stop=0; TR0=1;

while(stop==0); } } } }

void t0(void) interrupt 1 using 0 {

tcnt++;

if(tcnt==2000) {

tcnt=0; if(flag==0) {

flag=~flag; } else

西安思源学院 精品课程 单片机原理与应用

{

stop=1; TR0=0; } }

if(flag==0) {

t7hz++; if(t7hz==3) {

t7hz=0;

P1_0=~P1_0; } } else {

t5hz++; if(t5hz==4) {

t5hz=0;

P1_0=~P1_0; } } }

(1)电子琴

1、4×4 矩阵键盘识别处理  

每个按键有它的行值和列值 ,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和 CPU 通信。每个按键的状态同样需变成数字量“0”和“1” ,开关的一端(列线)通过电阻接 VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。 

2、音乐产生的方法;  

一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器 T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。现在以单片机 12MHZ 晶振为例,列出高中低音符与单片机计数 T0 相关的计数值如下表所示 

音 符 低1 DO #1 DO#

频 率(Hz)

262

277

音 符 #4 FA# 中5 SO

频 率(Hz)

740

784

西安思源学院 精品课程 单片机原理与应用

低2 RE #2 RE# 低3 MI 低4 FA #4 FA# 低5 SO #5 SO# 低6 LA #6 低7 SI 中1 DO #1 DO# 中2 RE #2 RE# 中3 MI 中4 FA

294 311 330 349 370 392 415 440 466 494 523 554 587 622 659 698

#5 SO# 中6 LA #6 中7 SI 高1 DO #1 DO# 高2 RE #2 RE# 高3 MI 高4 FA #4 FA# 高5 SO #5 SO# 高6 LA #6 高7 SI

831 880 932 988 1046 1109 1175 1245 1318 1397 1480 1568 1661 1760 1865 1967

 

2、程序框图 主程序框图 

 

西安思源学院 精品课程 单片机原理与应用

按键程序设计框图 

 

中断服务程序框图 

 

3、汇编源程序  

KEYBUF      EQU 30H  

西安思源学院 精品课程 单片机原理与应用

STH0        EQU 31H  STL0        EQU 32H  TEMP        EQU 33H  ORG 00H  LJMP START  ORG 0BH  LJMP INT_T0  

START:      MOV TMOD,#01H  SETB ET0  SETB EA  WAIT:  

MOV P3,#0FFH  CLR P3.4  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY1  

LCALL DELY10MS  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY1  MOV A,P3  ANL A,#0FH  

CJNE A,#0EH,NK1  MOV KEYBUF,#0  LJMP DK1  

NK1:        CJNE A,#0DH,NK2 MOV KEYBUF,#1  LJMP DK1  

NK2:        CJNE A,#0BH,NK3  MOV KEYBUF,#2  LJMP DK1  

NK3:        CJNE A,#07H,NK4  MOV KEYBUF,#3  LJMP DK1  

NK4:        NOP  DK1:  

MOV A,KEYBUF  MOV DPTR,#TABLE  MOVC A,@A+DPTR  MOV P0,A  MOV A,KEYBUF  MOV B,#2  

西安思源学院 精品课程 单片机原理与应用

MUL AB  MOV TEMP,A  

MOV DPTR,#TABLE1  MOVC A,@A+DPTR  MOV STH0,A  MOV TH0,A  INC TEMP  MOV A,TEMP  MOVC A,@A+DPTR  MOV STL0,A  MOV TL0,A  SETB TR0  

DK1A:       MOV A,P3  ANL A,#0FH  XRL A,#0FH  JNZ DK1A  CLR TR0  NOKEY1:  

MOV P3,#0FFH  CLR P3.5  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY2  

LCALL DELY10MS  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY2  MOV A,P3 ANL A,#0FH  

CJNE A,#0EH,NK5  MOV KEYBUF,#4  LJMP DK2  

NK5:        CJNE A,#0DH,NK6  MOV KEYBUF,#5  LJMP DK2  

NK6:        CJNE A,#0BH,NK7  MOV KEYBUF,#6  LJMP DK2  

NK7:        CJNE A,#07H,NK8  MOV KEYBUF,#7  LJMP DK2  

NK8:        NOP  

西安思源学院 精品课程 单片机原理与应用

DK2:  

MOV A,KEYBUF  MOV DPTR,#TABLE  MOVC A,@A+DPTR  MOV P0,A  MOV A,KEYBUF  MOV B,#2  MUL AB  MOV TEMP,A  

MOV DPTR,#TABLE1  MOVC A,@A+DPTR  MOV STH0,A  MOV TH0,A  INC TEMP  MOV A,TEMP  MOVC A,@A+DPTR  MOV STL0,A  MOV TL0,A  SETB TR0  

DK2A:       MOV A,P3  ANL A,#0FH  XRL A,#0FH  JNZ DK2A  CLR TR0  NOKEY2:  

MOV P3,#0FFH  CLR P3.6  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY3 

LCALL DELY10MS  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY3  MOV A,P3  ANL A,#0FH  

CJNE A,#0EH,NK9  MOV KEYBUF,#8  LJMP DK3  

NK9:        CJNE A,#0DH,NK10  MOV KEYBUF,#9  LJMP DK3  

西安思源学院 精品课程 单片机原理与应用

NK10:       CJNE A,#0BH,NK11  MOV KEYBUF,#10  LJMP DK3  

NK11: CJNE A,#07H,NK12  MOV KEYBUF,#11  LJMP DK3  

NK12:       NOP  DK3:  

MOV A,KEYBUF  MOV DPTR,#TABLE  MOVC A,@A+DPTR  MOV P0,A  MOV A,KEYBUF  MOV B,#2  MUL AB  MOV TEMP,A  

MOV DPTR,#TABLE1  MOVC A,@A+DPTR  MOV STH0,A  MOV TH0,A  INC TEMP  MOV A,TEMP  MOVC A,@A+DPTR  MOV STL0,A  MOV TL0,A  SETBTR0  

DK3A:       MOV A,P3  ANL A,#0FH  XRL A,#0FH  JNZ DK3A  CLR TR0  NOKEY3:  MOV P3,#0FFH CLR P3.7  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY4  

LCALL DELY10MS  MOV A,P3  ANL A,#0FH  XRL A,#0FH  JZ NOKEY4  MOV A,P3  

西安思源学院 精品课程 单片机原理与应用

ANL A,#0FH  

CJNE A,#0EH,NK13  MOV KEYBUF,#12  LJMP DK4  

NK13:       CJNE A,#0DH,NK14  MOV KEYBUF,#13  LJMP DK4  

NK14:       CJNE A,#0BH,NK15  MOV KEYBUF,#14  LJMP DK4  

NK15:       CJNE A,#07H,NK16  MOV KEYBUF,#15  LJMP DK4  

NK16:       NOP  DK4:  

MOV A,KEYBUF  MOV DPTR,#TABLE  MOVC A,@A+DPTR  MOV P0,A  MOV A,KEYBUF  MOV B,#2  MUL AB  MOV TEMP,A  

MOV DPTR,#TABLE1  MOVC A,@A+DPTR  MOV STH0,A  MOV TH0,A  INC TEMP  MOV A,TEMP  MOVC A,@A+DPTR  MOV STL0,A  MOV TL0,A  SETB TR0  

DK4A:       MOV A,P3  ANL A,#0FH XRL A,#0FH  JNZ DK4A  CLR TR0  NOKEY4:  LJMP WAIT  DELY10MS:  MOV R6,#10  

D1:         MOV R7,#248  DJNZ R7,¥  

西安思源学院 精品课程 单片机原理与应用

DJNZ R6,D1  RET  INT_T0:  

MOV TH0,STH0  MOV TL0,STL0  CPL P1.0  RETI  

TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H  DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H  TABLE1:     DW 64021,64103,64260,64400  DW 64524,64580,64684,64777  DW 64820,64898,64968,65030  DW 65058,65110,65157,65178  END 

4、 C 语言源程序  

 #include

unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; unsigned char temp; unsigned char key; unsigned char i,j; unsigned char STH0; unsigned char STL0;

unsigned int code tab[]={64021,64103,64260,64400, 64524,64580,64684,64777, 64820,64898,64968,65030, 65058,65110,65157,65178}; void main(void) {

TMOD=0x01; ET0=1; EA=1; while(1) {

P3=0xff; P3_4=0; temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

for(i=50;i>0;i--) for(j=200;j>0;j--);

西安思源学院 精品课程 单片机原理与应用

temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; switch(temp) {

case 0x0e: key=0; break; case 0x0d: key=1; break; case 0x0b: key=2; break; case 0x07: key=3; break; }

temp=P3; P1_0=~P1_0; P0=table[key];

STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;

temp=temp & 0x0f; while(temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; }

TR0=0; } }

P3=0xff; P3_5=0; temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

for(i=50;i>0;i--) for(j=200;j>0;j--);

西安思源学院 精品课程 单片机原理与应用

temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; switch(temp) {

case 0x0e: key=4; break; case 0x0d: key=5; break; case 0x0b: key=6; break; case 0x07: key=7; break; }

temp=P3; P1_0=~P1_0; P0=table[key];

STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;

temp=temp & 0x0f; while(temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; }

TR0=0; } }

P3=0xff; P3_6=0; temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

for(i=50;i>0;i--) for(j=200;j>0;j--);

西安思源学院 精品课程 单片机原理与应用

temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; switch(temp) {

case 0x0e: key=8; break; case 0x0d: key=9; break; case 0x0b: key=10; break; case 0x07: key=11; break; }

temp=P3; P1_0=~P1_0; P0=table[key];

STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;

temp=temp & 0x0f; while(temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; }

TR0=0; } }

P3=0xff; P3_7=0; temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

for(i=50;i>0;i--) for(j=200;j>0;j--);

西安思源学院 精品课程 单片机原理与应用

temp=P3;

temp=temp & 0x0f; if (temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; switch(temp) {

case 0x0e: key=12; break; case 0x0d: key=13; break; case 0x0b: key=14; break; case 0x07: key=15; break; }

temp=P3; P1_0=~P1_0; P0=table[key];

STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;

temp=temp & 0x0f; while(temp!=0x0f) {

temp=P3;

temp=temp & 0x0f; }

TR0=0; } } } }

void t0(void) interrupt 1 using 0 {

TH0=STH0; TL0=STL0; P1_0=~P1_0; }

西安思源学院 精品课程 单片机原理与应用

 

四、仿真 

利用KeilC进行编译程序,生成hex文件 添加仿真文件 单击

开始仿真。 

 

因篇幅问题不能全部显示,请点此查看更多更全内容

Top