一、 单片机开发系统应用初步
——基本I/O口赋值
1. 内容提要:
a. KEIL C软件对程序进行编译调试及烧录软件的使用方法。
b. 单片机基本I/O口的驱动方式、特点等。
c. 汇编语句的基本用法;对基本I/O口的赋值方法;程序的具体流程等。
2.实验目的及要求:
a. 课前预习好编程的基本知识。程序的基本概念、*.asm、*.c、*.hex、*.uv2所表示的文件类型等。
b. 熟练掌握不同数据类型之间的相互转换,不同类型的数据在程序中的表示方法等。
c. 课前弄清楚单片机I/O口的基本驱动方式,理解何谓上拉及下拉方式,单片机驱动电流、灌入电流等概念。
d. 复习数码管的相关知识,弄清数码管需显示某个字符应如何对其进行控制等。
3.实验源程序及流程图:
ORG 0000H
AJMP MAIN
MAIN: MOV P0,#0FH
JMP MAIN
END
4.实验步骤:
a. 通过读程序,弄懂程序对哪个口进行赋初值,通过发光管亮或灭的情况反映出单片机输出数据的情况(注意区分数据的高低位)。
b. 通过KEIL C软件对以上程序进行编译,正确后生成*.HEX机器语言文件,随即打开烧录软件,将生成的*.HEX文件烧录到单片机芯片中,完成后点击运行按钮便可脱机运行编写好的程序。
c. 观察发光管亮灭情况,最终得出硬件的实际连接情况。
d. 修改程序中的输出数据,重复以上编译烧录步骤,再次观察LED发光情况是
否与数据对应。例:
ORG 0000H
AJMP MAIN
MAIN: MOV P0,#65H
JMP MAIN
END
e. 修改单片机输出数据的I/O口(如改为P2口输出),观察其余口是否能正确输出数据。例:
ORG 0000H
AJMP MAIN
MAIN: MOV P2,#0FH
JMP MAIN
END
5.发挥部分:
将I/O口通过8芯排线接至独立两位数码管处,通过I/O口赋值能使数码管显示出本人学号最后一位(注意数据高位统一用来控制数码管的a笔段,低位控制h笔段)。
6. 电路原理图:
提示:
1. 由于单片机芯片烧录时需用到P1口,故在烧录过程中P1.5、P1.6、P1.7口不应有导线连接,否则易引起实验台初始化失败等错误(烧录完成后可以进行连接)。
7.C语言编程:
#include <AT89X51.H>
void main(void)
{
while(1)
{
P0=0x0f;
}
}
二、基本控制语句应用
——简单广告牌霓虹灯设计
1. 内容提要:
a. 汇编语言控制语句应用。
b. 程序的循环、子程序调用、程序跳转等。
c. 单片机基本I/O口的驱动方式、特点等。
2.实验目的及要求:
a. 理解左移RL、右移RR概念。
b. 延时程序DELAY的具体执行过程、延时量控制等。
c. 掌握通过设置程序的跳转来实现程序循环的方法。
3.实验源程序及流程图:
ORG 0000H
AJMP MAIN
MAIN: MOV P0,#00H
MOV A,#01H
LOOP: MOV P0,A
RL A
JMP LOOP
END
何功能。
b. 运行程序,观察结果是否与程序一致,分析出现问题的原因所在。
c. 试着向源程序中加入延时语句,观察现象是否有所改变。
ORG 0000H
AJMP MAIN
MAIN: MOV P0,#00H
MOV A,#01H
LOOP: MOV P0,A
RL A
ACALL DELAY
JMP LOOP
;*****延时子程序******;
DELAY:MOV R2,#10H
LOOP1:MOV R1,#0FFH
LOOP2:DJNZ R1,LOOP2
DJNZ R2,LOOP1
RET
END
d. 适当修改延时量,使LED闪烁更为明显,易于肉眼观察。
e. 适当修改程序,使程序最终实现一只LED作流水状移动。
5.发挥部分:
能自左向右——自右向左——自左向右反复循环来控制一只发光管如反弹状移动。
6. 电路原理图:
7. C语言编程:
#include <AT89X51.H>
unsigned char i,c,d,temp=0xfe;
void delay(void)
{
unsigned char a,b;
for(a=0;a<255;a++)
{
for(b=0;b<200;b++);
}
}
void main(void)
{
while(1)
{
for(i=0;i<8;i++)
{
c=temp<<i;
d=temp>>(8-i);
P0=c|d;
delay();
}
}
}
三、单片机I/O口输入
——独立按键识别
1. 内容提要:
a. 独立式按键的连接。
b. 汇编语句对按键的是否按下的具体判断、按键按下后所执行的跳转等。
c. 按键抖动对单片机所造成的影响以及如何消除抖动对单片机在执行程序上的影响。
2.实验目的及要求:
a. 掌握JB、CPL语句的具体使用方法。
b. 延时程序的具体执行过程、延时量控制等。
c. 掌握通过设置程序的跳转来执行相应语句的方法。
d. 体会按键抖动对单片机系统所造成的影响,以及如何通过软件延时去抖动方法来消除按键抖动。
3.实验源程序及流程图:
ORG 0000H
AJMP MAIN
;*****主程序*****;
MAIN: MOV P0,#0FFH
MOV A,#0FFH
WAIT: MOV P0,A
JB P3.0,WAIT
CPL A
JMP WAIT
END
4.实验步骤:
a. 运行以上程序,同时反复按下连接至P3.0口的独立式轻触开关(平时按键抬起时为高电平,按下按键时为低电平),观察LED发光情况。
5.发挥部分:
由于按键抖动,使LED的亮灭情况无法通过按键准确控制,试着通过前面一节的实验,在程序适当的位置加入延时程序,实现软件去抖动。
6. 电路原理图:(K2应接在P3.0)
7. C语言编程:
#include <AT89X51.H>
sbit key=P3^0;
unsigned char a=0;
void main(void)
{
while(1)
{P0=a;
if(key==0)
{
a=~a;
}
}
}
四、外部中断应用
——按键计数器
1. 内容提要:
a. 单片机中断系统基本功能、中断控制字定义以及外中断触发方式等。
b. 中断服务程序入口地址、中断断点及中断返回。
c. 按键抖动对中断所造成的影响。
2.实验目的及要求:
a. 理解中断服务程序的入口地址及熟记各中断服务程序入口地址。
b. 掌握中断控制字TCON、IE、IP的具体含义及正确定义等。
c. 掌握中断服务程序的具体执行过程。
d. 体会按键抖动对单片机系统所造成的影响及如何消除按键抖动。
3.实验源程序及流程图:
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP DEAL
MAIN:SETB EA
SETB EX0
SETB IT0
MOV A,#00H
MOV P0,#0FFH
WAIT:SJMP WAIT
DEAL:INC A
CPL A
MOV P0,A
CPL A
RETI
END
4.实验步骤:
a. 阅读并理解程序,理解程序第三行的“ORG 0003H”及“MAIN”程序中初始化部分的具体含义。
b. 运行程序,通过反复按下P3.2独立式按键(INT0),观察LED显示结果。
5.发挥部分:
通过以上实验结果得出:由于按键抖动,导致P3.2/INT0口频繁出现高低变化的电平,致使单片机多次执行中断服务程序。能否在程序的适当部分加入延时程序并更改触发方式,成功解决按键抖动问题?
6. 电路原理图:
7. C语言编程: a
#include <AT89X51.H>
unsigned char a=0;
void int0(void) interrupt 0 using 0
{
a++;a=~a;P0=a;a=~a;
}
void main(void)
{
EA=1;EX0=1;IT0=1;
while(1);
}
五、数码管显示基础
——数显按键计数器
1. 内容提要:
a. 数码管内部结构、引脚定义及驱动。
b. 数码管段代码表具体含义。
c. 变址寻址在单片机查表中的意义所在。
2.实验目的及要求:
a. 掌握数码管与单片机的连接方法。
b. 掌握段代码表的推算及变址寻址的具体含义。
c. 掌握判断语句的具体用法。
3.实验源程序及流程图:
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP DEAL
ORG 0030H
MAIN: SETB EA
SETB EX0
SETB IT0
MOV P0,#00H
MOV R0,#00H
MOV DPTR,#TAB
DISPLAY:MOV A,R0
MOVC A,@A+DPTR
MOV P0,A
JMP DISPLAY
DEAL: INC R0
RETI
TAB: DB 0FCH,60H,0DAH,0F2H,66H
DB 0B6H,0BEH,0E0H,0FEH,0F6H
DB 0EEH,3EH,9CH,7AH,9EH,8EH,00H
END
4.实验步骤:
a. 阅读并理解程序,重点掌握数码管“TAB”段代码表以及段代码表查表过程。
b. 根据程序定义,将P0口通过8芯排线连接至静态二位数码管的其中一位(注意将拨码开关拨至断开状态,以免PO口与74LS164输出发生冲突),注意数据高位控制a笔段;P3.2/INT0端仍接独立式按键。
c. 运行以上程序,通过按下按键观察数码管显示情况。
d. 解决按键抖动问题,同时分析数码管显示完“F”字符后为何会出现乱码。
5.发挥部分:
使程序实现16进制计数,即按下按键时能从0~9~A~F~0循环显示。
6. 电路原理图:
7. C语言编程:
#include <AT89X51.H>
unsigned char a=0;
//*************数码管代码表(共阳且高位接a笔段)*************//
unsigned char Tab[]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,
0x01,0x09,0x11,0xC1,0x63,0x85,0x61,0x71,0xFF};
void int0(void) interrupt 0 using 0
{
a++;P0=Tab[a];
}
void main(void)
{
EA=1;EX0=1;IT0=1;
while(1);
}
六、矩阵式键盘应用
——矩阵键盘识别
1. 内容提要:
a. 矩阵式键盘优点、具体结构、连接方式等。
b. 单片机C语言基础编程应用。
2.实验目的及要求:
a. 掌握矩阵式键盘的内部构架以及键盘与单片机之间的连接方式。
b. 掌握矩阵键盘扫描识别的编程方法。
c. 掌握C语言常用语句如if、for、switch、while的具体用法等。
3.实验源程序及流程图:
#include <AT89X51.H>
unsigned char key;
//按键延时程序
void ys()
{unsigned char aaa,bbb;
for(aaa=200;aaa>0;aaa--)
for(bbb=0;bbb<200;bbb++);
}
void main(void)
{key=0;
while(1)
{
P3=0x7f;
if(P3!=0x7f)
{
ys();
if(P3!=0x7f)
{
switch(P3)
{case 0x77:key=7;break;
case 0x7b:key=4;break;
case 0x7d:key=1;break;
case 0x7e:key=0;break;
}
P0=~key;
}
}
P3=0xbf;
if(P3!=0xbf)
{
ys();
if(P3!=0xbf)
{
switch(P3)
{case 0xb7:key=8;break;
case 0xbb:key=5;break;
case 0xbd:key=2;break;
case 0xbe:key=13;break;
}
P0=~key;
}
}
P3=0xdf;
if(P3!=0xdf)
{
ys();
if(P3!=0xdf)
{
switch(P3)
{case 0xd7:key=9;break;
case 0xdb:key=6;break;
case 0xdd:key=3;break;
case 0xde:key=14;break;
}
P0=~key;
}
}
P3=0xef;
if(P3!=0xef)
{
ys();
if(P3!=0xef)
{
switch(P3)
{case 0xe7:key=10;break;
case 0xeb:key=11;break;
case 0xed:key=12;break;
case 0xee:key=15;break;
}
P0=~key;
}
}
}
}
4.实验步骤:
a. 理解矩阵键盘的结构及硬件连接。
b. 运行程序,按下4×4键盘上的按键,观察P0口的LED显示情况。
5.发挥部分:
发挥部分:通过加入数码管段代码表,使键值能通过数码管显示出来,依次对应0~9~A~F。C语言中数码管段代码表可参考如下(共阴数码管,高位接a笔段):
unsigned char Tab[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,
0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00};
如要将key值通过查表赋予P0,可直接定义为:P0=Tab[key]。
6. 电路原理图(实际电路板中的键盘行与列接P3口):
发挥部分原理图(实际电路板中的键盘行与列接P3口):
七、单片机定时/计数器
——秒脉冲定时器
1. 内容提要:
a. 定时/计数器控制字定义。
b. 中断服务程序入口地址、中断断点及中断返回。
c. 单片机定时时长计算方法、间接定时获取长时间定时方法。
2.实验目的及要求:
a. 理解中断服务程序的入口地址及熟记各中断服务程序入口地址。
b. 掌握定时/计数控制字TMOD、TCON的具体含义及正确定义等。
c. 掌握不同工作方式下定时时间初值的具体算法。
3.实验源程序及流程图:
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP INTT0
MAIN: MOV TMOD,#01H
MOV TL0,#0B0H
MOV TH0,#3CH
SETB EA
SETB ET0
SETB TR0
SJMP $
INTT0: MOV TL0,#0B0H
MOV TH0,#3CH
CPL P1.0
RETI
END
4.实验步骤:
a. 运行以上程序,观察P1.0口的LED闪烁情况。
5.发挥部分:
精确定义一秒钟时间,并结合前面学过的知识,能通过数码管显示出秒钟的个位信息(注意秒钟个位为十进制)(结合实验五电路图连接)。
6. 电路原理图:
八、单片机显示初步
——数码管动态扫描
1. 内容提要:
a. 人眼有视觉暂留效应。
b. 数码管动态扫描的硬件连接特点。
c. 单片机C语言的具体应用。
2.实验目的及要求:
a. 通过实验体会人眼的视觉暂留效应,通过实践得出八位数码管动态扫描的时间间隔大于多少会产生闪烁问题。
b. 掌握定时/计数控制字TMOD、TCON的具体含义;不同工作方式下定时时间初值的具体算法等。
c. 掌握数码管动态扫描的硬件连接。
3.实验源程序:
#include <AT89X51.H> //******头文件*******//
unsigned char mg=9,ms=8,fg=7,bitdisplay=0; //***定义变量***//
//****************数码管段代码表****************//
unsigned char Tab[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,
0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00};
//*********定时中断服务程序**********//
void timer0 (void) interrupt 1 using 0
{
TH0=0; TL0=0xb0;
switch(bitdisplay)
{
case 0:P0=Tab[mg];P2=0x7F;break;
case 1:P0=Tab[ms];P2=0xBF;break;
case 2:P0=Tab[fg];P2=0xDF;break;
}
bitdisplay++;
if(bitdisplay==3){bitdisplay=0;}
}
//*********主程序**********//
void main(void)
{
TMOD=0x01;TH0=0;TL0=0xb0;
EA=1; ET0=1; TR0=1;
while(1);
}
4.实验步骤:
a. 掌握数码管动态扫描的硬件连接方法。弄清程序对动态扫描部分的定义,软件与硬件需相吻合,否则出现乱码或高低位对调。
b. 运行以上程序,观察数码管显示情况,正常情况下应能以较慢速度(闪烁态)显示“789”。
5.发挥部分:
在以上程序基础上,编写一程序,能正确稳定地显示出本人学号(8位数字,且显示时无闪烁问题)。
6. 电路原理图:(仅画出三位数码管)
九、单片机串行口应用
——数码管并行静态显示
1. 内容提要:
a. 串行口基本定义;RXD、TXD信号实现串行数据发送。
b. 串行口控制寄存器SCON具体定义;中断请求的标志位等。
c. 74LS164芯片串行数据转换为并行数据的硬件连接。
2.实验目的及要求:
a. 掌握单片机串行口收发数据的全过程。
b. 掌握串行口控制寄存器SCON的具体定义;数据发送过程中中断请求标志位的相应变化;欲发送的数据必须先送入缓冲区等。
c. 掌握74LS164芯片的工作原理、连接方法等。
3.实验源程序:
#include <AT89X51.H>
//*************数码管代码表(共阳且高位接a笔段)*************//
unsigned char Tab[]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,
0x01,0x09,0x11,0xC1,0x63,0x85,0x61,0x71,0xFF};
unsigned char mg=5,ms=0,bittime=20;
//显示程序//
void display(void)
{
TI=0; SBUF=Tab[ms]; while(!TI);
TI=0; SBUF=Tab[mg]; while(!TI);
}
//定时中断服务程序
void timer0 (void) interrupt 1 using 0
{
TH0=0; TL0=0xb0; bittime--;
while(bittime==0)
{
bittime=20;display(); //每经一秒调用一次显示程序
}
}
//主程序
void main(void)
{
TMOD=0x01;SCON=0X00;
TH0=0;TL0=0xb0;
EA=1; ET0=1; TR0=1;
while(1);
}
4.实验步骤:
a. 读懂并理解程序,掌握串行口控制字的定义及子程序调用等相关知识。
b. 掌握串行数据转换为并行数据的连接方法及74LS164串并转换芯片的具体用法。根据程序定义将单片机串行信号(P3.0/RXD、P3.1/TXD)通过两单芯导线对应连接至74LS164的RXD、TXD端(电路板内部已连接);74LS164芯片输出的并行信号(Q1~Q8)通过拨码开关接至静态数码管笔段中(a~h,其中拨码开关的第8位对应a笔段)。
c. 运行以上程序,观察两数码管显示情况,正常情况下应能显示“05”。
5.发挥部分:
通过加入若干语句,对mg及ms变量进行控制,实现每当一秒钟到来时mg自动加1;当mg=10(即经历10秒钟)时mg自动清零,同时ms自动加1;当ms=6(即经历60秒)时ms自动清零,最终实现标准时间的秒信息显示(mg及ms变量通过串行口送出,经转换至数码管显示)。
6. 电路原理图:
十、单片机系统设计(一)
——动态扫描数字钟
1. 内容提要:
a. 单片机软件系统设计。
b. 单片机硬件接口系统设计。
c. 单片机C语言的综合应用。
2.实验目的及要求:
a. 能够系统性地总结掌握的知识,将单元模块知识有机的结合在一起。
b. 能够充分协调好硬件与软件之间的相互结合,合理设计硬件电路。
c. 掌握单片机C语言判断语句、分支语句以及子程序调用等编程知识。
3.实验源程序:
#include <AT89X51.H> //******头文件*******//
unsigned char mg=0,ms=0,fg=0,bittime=0,bitdisplay=0; //*定义变量*//
//***************数码管段代码表(共阴且高位对应a段)****************//
unsigned char Tab[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,
0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00};
//*********定时中断服务程序**********//
void timer0 (void) interrupt 1 using 0
{
TH0=0; TL0=0xb0;
switch(bitdisplay)
{
case 0:P0=Tab[mg];P2=0x7F;break;
case 1:P0=Tab[ms];P2=0xBF;break;
case 2:P0=Tab[fg];P2=0xDF;break;
}
bitdisplay++;bittime++;
if(bitdisplay==3){bitdisplay=0;}
}
//*********主程序**********//
void main(void)
{
TMOD=0x01; TH0=0;TL0=0xb0;
EA=1; ET0=1; TR0=1;
while(1)
{
if(bittime==20){bittime=0;mg++;}
}
}
4.实验步骤:
a. 根据程序定义将P0口通过8芯排线接至数码管动态扫描笔段控制端;P2口接至位地址端(电路内部已连接,无需连线)。
b. 运行以上程序,观察数码管显示情况,应能以闪烁状显示“000”、“001”,直至秒个位出现乱码(由于秒个位mg一直在不断地累加,超过16后在段代码表中无代码与之对应,故出现乱码)。
c. 针对以上情况,请修改程序,最终实现正确稳定地显示小时(两位数)、分钟(两位数)、秒钟(两位数),同时数码管应无闪烁问题。
5. 电路原理图:(仅画出三位数码管)
十一、单片机系统设计(二)
——16路数显竞赛抢答器
1. 内容提要:
a. 单片机软件系统设计。
b. 单片机硬件接口系统设计。
c. 单片机C语言的综合应用。
2.实验目的及要求:
a. 能够系统性地总结掌握的知识,将单元模块知识有机的结合在一起。
b. 能够充分协调好硬件与软件之间的相互结合,合理设计硬件电路。
c. 掌握单片机C语言判断语句、分支语句以及子程序调用等编程知识。
3.实验源程序:
#include <AT89X51.H>
unsigned char key;
void main(void)
{key=0;
while(1)
{
P3=0x7f;
if(P3!=0x7f)
{
switch(P3)
{case 0x77:key=7;break;
case 0x7b:key=4;break;
case 0x7d:key=1;break;
case 0x7e:key=0;break;
}
P0=~key;
}
P3=0xbf;
if(P3!=0xbf)
{
switch(P3)
{case 0xb7:key=8;break;
case 0xbb:key=5;break;
case 0xbd:key=2;break;
case 0xbe:key=13;break;
}
P0=~key;
}
P3=0xdf;
if(P3!=0xdf)
{
switch(P3)
{case 0xd7:key=9;break;
case 0xdb:key=6;break;
case 0xdd:key=3;break;
case 0xde:key=14;break;
}
P0=~key;
}
P3=0xef;
if(P3!=0xef)
{
switch(P3)
{case 0xe7:key=10;break;
case 0xeb:key=11;break;
case 0xed:key=12;break;
case 0xee:key=15;break;
}
P0=~key;
}
}
}
4.实验步骤:
a. 弄清4×4矩阵键盘的电路连接。
b. 设计程序,使之能够同时为16支参赛队提供抢答功能,抢答成功后应能通过数码管显示出参赛队号数,同时点亮发光二极管示意抢答成功。
c. 加入独立开关,可启动10秒倒计时功能,通过数码管显示出倒计时时间(倒计时状态下抢答功能不起作用,反之亦然)。
5. 电路原理图:
十二、单片机系统设计(三)
——数字频率计
1. 内容提要:
a. 单片机软件系统设计。
b. 单片机硬件接口系统设计。
c. 单片机C语言的综合应用。
2.实验目的及要求:
a. 能够系统性地总结掌握的知识,将单元模块知识有机的结合在一起。
b. 能够充分协调好硬件与软件之间的相互结合,合理设计硬件电路。
c. 掌握单片机C语言判断语句、分支语句、子程序调用、定时/计数器应用等编程知识。
3.实验源程序:
#include <AT89X51.H>
unsigned char a=0,b=0,c=0,bitdisplay=0,bittime=0;
unsigned long digit=0;
unsigned char Tab[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,
0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00};
void timer0 (void) interrupt 1 using 0
{
TH0=0;TL0=0xb0;bittime++;
switch(bitdisplay)
{
case 0:P0=Tab[a];P2=0x7F;break;
case 1:P0=Tab[b];P2=0xBF;break;
case 2:P0=Tab[c];P2=0xDF;break;
}
bitdisplay++;
if(bitdisplay==3){bitdisplay=0;}
}
void main(void)
{
TMOD=0x51;TH0=0;TL0=0xb0;
IP=0x02; //定时器0优先级高
EA=1;TR0=1;TR1=1;ET0=1;ET1=1;TH1=0;TL1=0;
while(1)
{
if(bittime==20)
{
digit=TH1*256+TL1;
c=digit/100;
b=digit%100/10;
a=digit%10;
TH1=0;TL1=0;bittime=0;
}
}
}
4.实验步骤:
a. 读懂程序,根据程序定义将频率产生器的跳线接通,从而将方波引至单片机计数器T1输入端P3.5/T1。
b. 运行以上程序,正常情况下数码管应有三位数显示,此显示值便是当前输入方波频率的低三位,其中百位为乱码(已超出段代码表范围)。
c. 依据以上情况,编写一完整程序,能够正确显示出5位数的频率值(需解决数码管闪烁问题)。
十三、单片机系统设计(四)
——16音电子琴
1. 内容提要:
a. 单片机软件系统设计。
b. 单片机键盘硬件接口系统设计。
c. 单片机C语言的综合应用。
2.实验目的及要求:
a. 能够系统性地总结掌握的知识,将单元模块知识有机的结合在一起。
b. 能够充分协调好硬件与软件之间的相互结合,合理设计硬件电路。
c. 掌握单片机C语言判断语句、分支语句、子程序调用、定时/计数器应用等编程知识。
d. 理解单片机发声原理以及如何改变音调。
3.实验源程序:
#include <AT89X51.H>
unsigned char key,KTH0,KTL0;
sbit sp=P1^0;
unsigned int code tab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};
void t0(void) interrupt 1 using 0
{
TH0=KTH0;
TL0=KTL0;
P1_0=~P1_0;
}
//按键延时程序
void ys()
{unsigned char aaa,bbb;
for(aaa=200;aaa>0;aaa--)
for(bbb=0;bbb<20;bbb++);
}
void main(void)
{key=0;TMOD=0X01;EA=1;ET0=1;
while(1)
{
P3=0x7f;
if(P3!=0x7f)
{
ys();
while(P3!=0x7f)
{
switch(P3)
{case 0x77:key=7;break;
case 0x7b:key=4;break;
case 0x7d:key=1;break;
case 0x7e:key=0;break;
}
P0=~key;
KTH0=tab[key]/256;
KTL0=tab[key]%256;
TR0=1;
}
}
P3=0xbf;
if(P3!=0xbf)
{
ys();
if(P3!=0xbf)
{
switch(P3)
{case 0xb7:key=8;break;
case 0xbb:key=5;break;
case 0xbd:key=2;break;
case 0xbe:key=13;break;
}
P0=~key;
KTH0=tab[key]/256;
KTL0=tab[key]%256;
TR0=1;
}
}
P3=0xdf;
if(P3!=0xdf)
{
ys();
if(P3!=0xdf)
{
switch(P3)
{case 0xd7:key=9;break;
case 0xdb:key=6;break;
case 0xdd:key=3;break;
case 0xde:key=14;break;
}
P0=~key;
KTH0=tab[key]/256;
KTL0=tab[key]%256;
TR0=1;
}
}
P3=0xef;
if(P3!=0xef)
{
ys();
if(P3!=0xef)
{
switch(P3)
{case 0xe7:key=10;break;
case 0xeb:key=11;break;
case 0xed:key=12;break;
case 0xee:key=15;break;
}
P0=~key;
KTH0=tab[key]/256;
KTL0=tab[key]%256;
TR0=1;
}
}
}
}
4.实验步骤:
a. 读懂程序,根据程序定义将功放接入跳线接通,从而将单片机P1.0口输出的方波引入功放。接着找来一只阻抗为8Ω,功率在0.5W左右的小喇叭,接上双孔插头后插入功放输出插口便可。
b. 运行以上程序,正常情况下按下4×4键盘的按键应听到喇叭发出不同的声调。
c. 依据以上情况,编写一音乐自动播放程序,即能够通过单片机自动播放一首完整的曲子,如常见的贺卡上存储的《生日快乐》、《祝你平安》等(即根据曲子节奏变换定时时间)。
5. 电路原理图(实际电路板中的键盘行与列接P3口,P1.0接入功放):
联系我们
Contact us