爱玩科技网
您的当前位置:首页单片机实验报告

单片机实验报告

来源:爱玩科技网


1

实验一 00-99计数器

1.实验目的:

1>整个系统有较强的抗干扰能力. 2>计数范围:00~99. 3>将计数值准确显示出来.

2. 实验要求:

利用keil软件和proteus软件提供的显示电路,动态显示一行数据.

3. 实验电路(proteus提供):

2

4. 实验器材:

(1)具备keil软件和proteus软件的电脑一台 5. 实验原理说明:

利用ATS51单片机来制作一个手动计数器,在ATS51单片机的P3.7管脚接一个轻触开关,作为手动计数的按钮,用单片机的P2.0-P2.7接一个共阴数码管,作为00-99计数的个位数显示,用单片机的P0.0-P0.7接一个共阴数码管,作为00-99计数的十位数显示;

硬件电路图如图1-1所示:

3

图 1-1 硬件电路图

系统板上硬件连线

1)把“单片机系统”区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:P0.0/AD0对应着a,P0.1/AD1对应着b,„„,P0.7/AD7对应着h。

2)把“单片机系统”区域中的P2.0/A8-P2.7/A15端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个数码管的a-h端口上;

3)把“单片机系统”区域中的P3.7/RD端口用导线连接到“式键盘”区域中的SP1端口上; 6.程序流程图:

4

7.程序清单:

(1) 汇编源程序 Count EQU 30H SP1 BIT P3.7 ORG 0

START: MOV Count,#00H NEXT: MOV A,Count MOV B,#10 DIV AB

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

MOVC A,@A+DPTR MOV P2,A

WT: JNB SP1,WT WAIT: JB SP1,WAIT LCALL DELY10MS JB SP1,WAIT INC Count MOV A,Count

CJNE A,#100,NEXT LJMP START

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

TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END

(2) C语言源程序

#include

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char Count;

void delay10ms(void) {

unsigned char i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); }

5

void main(void) {

Count=0;

P0=table[Count/10]; P2=table[Count%10]; while(1) {

if(P3_7==0) {

delay10ms(); if(P3_7==0) {

Count++;

if(Count==100) {

Count=0; }

P0=table[Count/10]; P2=table[Count%10]; while(P3_7==0); } } } }

6

8.实验总结 (对实验的结果及优缺点及可能改进的方法,根据实验写) 实验结果:走时,默认为计数状态,显示两位数,时间会按实际时间以秒为最小单位变化,从00—99的计数,按复位键,重00开始,重新计数。

基于单片机构成的产品自动计数器研究的主要内容包括:如果构成检测电路、MCS-51单片机用何种方式对外部计数脉冲进行计数显示控制、LED显示驱动模块的选择、MCS-51单片机的扩展。在这个设计中主要需要解决的问题便是如何提高MCS-51单片机的抗干扰能力以及稳定性。

在本任务中用2位数码管显示当前数值的十,个,由于数码管个数多,如采用静态显示方式,则占用单片机的I/O口线太多,如果用定时器/计数器的串行移位寄存器工作方式及外接串入并出移位寄存器74LS1的方式,则电路复杂。所以,在数码管个数较多时,常采用动态显示方式。

2位数码管的相同段并联在一起,由一个6位I/O(P1口)输出字形码控制显示某一字形,每个数码管的公共端由另外一个I/O口(P0口)输出的字位码控制,即数码管显示的字形是由单片机I/O口输出的字形码确定,而哪个数码管点亮是由单片机I/O口输出的字位码确定的。在本任务中,为了简便,字形码和字位码都没由加驱动电路,在实际应用中应加驱动电路。数码管有共阴极和共阳极两种。对于共阳数码管,字形驱动输出0有效,字位驱动输出1有效;而对于共阴数码管则相反,即:字形驱动输出1有效,字位驱动输出0有效。

7

实验二 流水灯实验

1.实验目的:

用电子电路去设计流水灯,我们主要可以用装套控制器和状态译码器来实现灯光的流水效果,但是现在我们可以用单片机ATC51来实现,因为其相对于电子电路有明显的优越性,控制硬件电路比较简单,软件方面程序也不复杂,因此制作的远离简单,但功能作用并不低于电子电路设计的,由于它的小巧方便、通俗易懂,所以我们往往采用单片机来做流水灯。 2.实验器材:

(1)具备keil软件和proteus软件的电脑一台

3. 实验电路:

(1)硬件框图

复位电路 STC C51 键盘 (2)总设计图

震荡电路流水灯电路

8

4.实验说明

如图所示,S1为复位开关,S2、S3、S4分别为切换不同流水效果的开关,P2口控制LED灯D1~D7的显示,P0口作为LED的输出控制。当按下S2后能实现D1和D7同时亮其他不亮,然后D2和D6亮,依此类推。当按下复位S1,然后按下S2实现LED灯从D7到D1循环亮,按下S1然后按下S3实现LED从D1到D7的循环亮。

5.实验框图:

开始 9

检查是否有键按下 读取键值 根据键盘指令执行流水灯显示效果 执行结束

6.程序清单: #include // 头文件

sbit k1=P0^0; //定义按键k1 sbit k2=P0^1; //定义按键k2 sbit k3=P0^2; //定义按键k3

code unsigned char num[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,//左移

0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,//右移 0x7e,0xbd,0xdb,0xe7,0xe7,0xdb,0xbd,0x7e};//两

边到中间

unsigned char k; //数组的移动指针

void delay10ms(void) //延时10ms {

unsigned char i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); }

void delay02s(void)//延时0.2s {

unsigned char i; for(i=20;i>0;i--) {delay10ms();

10

} }

void KEY(void) //按键扫描程序 {

if(k1==0) {

delay10ms(); if(k1==0) {

k=0; } }

if(k2==0) {

delay10ms(); if(k2==0) {

k=8; } }

if(k3==0) {

delay10ms(); if(k3==0) {

k=16; } } }

void main(void) //主程序 {

unsigned char i; while(1)//死循环 {

if(P0!=0xff)//判断是否有按键按下 {

KEY();//执行按键扫描程序

for(i=0;i<8;i++)//循环8次的出8个亮的状态 {

P2=num[i+k];//根据按下的键得到亮的状态 delay02s();//延时0.2s }

P2=0xff;//全灭 }

11

} } 7.实验总结 实验结果:仿真结果如下:当S2关闭

当S3关闭

12

选用ATC51的引脚功能

XTAL1:单芯片系统时钟的反向放大器输入端。

XTAL2:系统时钟的反向放大器输出端,一般在设计上只要在XTAL1和XTAL2上接上一只石英震荡晶体系统就可以工作了,此外可以在两引脚与地之间加入20PF的小电容,可以使系统更稳定,避免噪音干扰而死机。

RESET:重置引脚,高电平动作,当要对晶体重置时,只要对此引脚电平提升至高电平并保持两个及其周期以上的时间便能完成系统重置的各项动作,使得内部特殊功能寄存器内容均被设成已知状态。

P0:端口0是一个8位宽的开路汲汲双向输出入端口,共有8个位,P0.0表示0,P0.1表示1,以此类推。 P2:端口2是具有内部提升电路的双向I/O端口,每一个引脚可以推动4个LS的TTL负载,若将端口2的输出设为高电平时,此端口便能当成输入端口来使用。

13

实验三 音乐盒 1.实验目的 设计一个基于MCS-51系列单片机的音乐盒,利用试验板上的开关,按开关切换演奏出不同的乐曲。蜂鸣器发出某个音调,与之相对应的LED亮起。使用两个按键,一个用来切换歌曲,另一个切换八路LED的变化花样。

2.实验要求 1)电路有两种工作模式:演奏音乐模式和花样灯模式。 演奏音乐模式:演奏完整的一首的歌曲,八路LED随着音乐变化。 花样灯模式:八路LED变化出各种花样,蜂鸣器随着发出“嘀嘀”声 2)按下按键1进入演奏音乐模式,再按切换歌曲,共两首歌曲。 3)按下按键2进入花样灯模式,再按切换LED花样,共四种花样。

此电路的程序只占用了1K左右,可编制更多的音乐和LED花样,使系统的功能更加强大。 3.实验器材:

(1)具备keil软件和proteus软件的电脑一台 4.实验电路

电路原理图

14

4.实验说明 由于51单片机的电流驱动能力较弱,而蜂鸣器的工作电流为几十MA,故驱动蜂鸣器需用一个pnp三极管。单片机给P3.0低电平,则蜂鸣器开;给高电平则蜂鸣器关。

LED接到单片机的P1口,拉低IO口,可使LED亮起。

两个按键的一端接单片机的IO口,另一端接地。不按下去时与按键相连的IO口被单片机内部上拉电阻拉高,按下则与之相连的IO口变成低电平,引发单片机中断。

程序设置了两个标志——count1和count2,分别初始化为1和0。按键1使得count1在1和2之间切换,按键2使得count2在1~4之间切换。程序检测count1的值,count1等于1时播放第一首歌曲,等于2时播放第二首。另一方面根据count2的值来切换LED的花样。Count1和count2的值是互斥的,设置count1等于1、2时,count2同时设置为0;设置count2等于1~4时,count1也同时设置为0。

歌曲简谱的编码规则:

do re mi fa so la si分别编码为1~7,重音do编为8,重音re编为9,停顿编为0。播放长度以十六分音符为单位(在本程序中为165ms),一拍即四分音符等于4个十六分音符,编为4,其它的播放时间以此类推。音调作为编码的高4位,而播放时间作为低4位,如此音调和节拍就构成了一个编码。以0xff作为曲谱的结束标志。

举例1:音调do,发音长度为两拍,即二分音符,将其编码为0x18。 举例2:音调re,发音长度为半拍,即八分音符,将其编码为0x22 歌曲播放的设计。先将歌曲的简谱进行编码,储存在一个数据类型为unsigned char 的数组中。程序从数组中取出一个数,然后分离出高4位得到音调,接着找出相应的值赋给定时器0,使之定时操作蜂鸣器,得出相应的音调;接着分离出该数的低4位,得到延时时间,接着调用软件延时。 确定定时器0对应于音调的初值:

假设要得到500HZ的声音。500HZ的声音信号每个周期为2ms,即2000us。假设单片机采用12MHZ的晶振,每个机器周期的时间为12/12M=1 us。故单片机操作(对与蜂鸣器相连的IO口取反)一次蜂鸣器的时间间隔为

2000us/1us/2=1000个机器周期,故给工作在方式1的定时器0赋的初值为TH0=(65536-1000)/256,TL0=(65536-1000)%256。

下面给出定时器0工作在方式1对应各音调的初值,假定使用的晶振是12MHZ:

15

5.实验框图: 主程序流程图

16

播放音乐子程序流程图

计数i=0 yes Count2=0? no Count2=1? yes 从第一个编码表取第i个数 no 从第二个编码表取第i个数 结束标志? no 取数高4位,点亮相应LED yes 是0? yes 关蜂鸣器,停顿一次 no 给定时器0置入相应初值 取数的低4位,调用软件延时 i=i+1,修改编码指针 结束

17

6.程序清单: 软件源程序:

#include

#define uchar unsigned char #define uint unsigned int sbit duan=P2^6;

sbit key1=P3^2;//按key1可切换花样 sbit key2=P3^3;//按key2可切换歌曲 sbit fm=P3^7;//蜂鸣器连续的IO口 sbit P34=P3^4;//矩阵键盘的一列

uchar code huayang1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe, 0xfd,0xfb,0xf7,0xef,0xdf,0xbf};//花样1 uchar code huayang2[]={0x7f,0xfe,0xbf,0xfd,0xdf,0xfb,0xef,0xf7, 0xef,0xfb,0xdf,0xfd,0xbf,0xfe};//花样2 uchar code huayang3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x0, 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; char code huayang4[]={ 0x55,0xaa,0xcc,0x33,0x99,0x66,0x0f,0xf0}; uchar count1;//花样标志 uchar count2;//歌曲标志 uchar timeh,timel,i;

//================简谱==================== //编程规则:字节高位是简谱,低位是持续时间, //代表多少个十六分音符

//1-7代表C调,8-E代表高八度,0代表停顿 //最后的0是结束标志

uchar code qnzl[]={ //千年之恋

0x12,0x22,0x34,0x84,0x74,0x54,0x38,0x42,0x32,0x22,0x42,0x34,0x84,0x72,0x82,0x94,0xA8,0x08, //前奏

0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62, //竹林的灯火 到过的沙漠

0x32,0x31,0x21,0x32,0x82,0x71,0x81,0x71,0x51,0x32,0x22, //七色的国度 不断飘逸风中

0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62, //有一种神秘 灰色的旋涡

0x32,0x31,0x21,0x32,0x83,0x82,0x71,0x72,0x02, //将我卷入了迷雾中

0x63,0xA1,0xA2,0x62,0x92,0x82,0x52, //看不清的双手

0x31,0x51,0x63,0x51,0x63,0x51,0x63,0x51,0x62,0x82,0x7C,0x02, //一朵花传来谁经过的温柔

0x61,0x71,0x82,0x71,0x62,0xA2,0x71,0x76,

18

//穿越千年的伤痛

0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36, //只为求一个结果

0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53, //你留下的轮廓 指引我

0x42,0x63,0x83,0x83,0x91,0x91, //黑夜中不寂寞

0x61,0x71,0x82,0x71,0x62,0x0A2,0x71,0x76, //穿越千年的哀愁

0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36, //是你在尽头等我

0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53, //最美丽的感动 会值得

0x42,0x82,0x88,0x02,0x74,0x93,0x,0xff//结束标志 //用一生守候 };

uchar code jmszl[]={ //寂寞沙洲冷

0x12,0x12,0x22,0x32,0x31,0x22,0x21,0x22, //自你走后心憔悴

0x21,0x31,0x51,0x52,0x31,0x52,0x61,0x15,0x14, //白色油桐风中纷飞

0x51,0x52,0x31,0x52,0x62,0x13,0x11,0x13,0x32,0x28,0x08,0x28, //落花似人有情 这个季节

0x31,0x32,0x31,0x32,0x11,0x21,0x51,0x52,0x51,0x52, //河畔的风放肆拼命地吹

0x51,0x51,0x31,0x32,0x31,0x32,0x81,0x72,0x63, //不断拨弄离人的眼泪

0x62,0x71,0x81,0x72,0x61,0x61,0x52,0x31,0x21,0x32,0x51,0x54, //那样浓烈的爱再也无法给

0x22,0x12,0x11,0x12,0x11,0x12,0x12,0x14,0x26,0x32,0x26, //伤感一夜一夜

0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51, //当记忆的线缠绕过往支离破碎

0x02,0x32,0x81,0x81,0x81,0x81,0x62,0x52,0x34,

//是慌乱占据了心扉

0x31,0x81,0x81,0x81,0x61,0x91,0x82, //有花儿伴着蝴蝶

0x51,0x51,0x51,0x51,0x31,0x61,0x53, //孤雁可以双飞

0x21,0x11,0x21,0x11,0x22,0x11,0x21,0x26, //夜深人静独徘徊

19

0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,0x52,

//当幸福恋人寄来红色分享喜悦

0x31,0x31,0x81,0x81,0x81,0x61,0x91,0x81,0x61,0x31,0x56, //闭上双眼难过头也不敢回

0x32,0x32,0x81,0x81,0x81,0x81,0x91,0x81,0x61,0x81,0x61,0x51,0x31,0x51,0x34,

//仍然捡尽寒枝不肯安歇微带着后悔

0x21,0x31,0x51,0x31,0x21,0x11,0x61,0x21,0x16, //寂寞沙洲我该思念谁 0xff};

//==============简谱音调对应的定时器初值======= //适合11.0592M的晶振 uchar code cuzhi[]={ 0xff,0xff,//占位

0xFC,0x8E,//C调1-7 0xFC,0xED, 0xFD,0x43, 0xFD,0x6A, 0xFD,0xB3, 0xFD,0xF3, 0xFE,0x2D,

0xFE,0x47, //高八度1-7 0xFE,0x76, 0xFE,0xA1, 0xFE,0xC7, 0xFE,0xD9, 0xFE,0xF9, 0xFF,0x16 }; uchar

yinyue[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x0,0x0}; //将音调转化为对应的LED样式 void delay1(uint z); //延时1MS

void delay(uint z); //延时165MS,即十六分音符 void song();

void beep();//蜂鸣器叫一声 main()

{ uchar x;

count1=0;//流水灯无花样 count2=1;//唱第一首歌

P34=0;//选取矩阵键盘的一列 EA=1;//开总中断

EX0=1;//开外部中断0

20

IT0=1;//外部中断0下降沿触发方式 EX1=1;//开外部中断1

IT1=1;//外部中断1下降沿触发方式 TMOD=0x01;//定时器0工作在方式1 TH0=0; TL0=0; ET0=1;

while(1) {

if(count1!=0) {

switch(count1) {

case 1:

for(x=0;x<14;x++) {

duan=1;

P1=huayang1[x]; beep();

delay1(300); duan=0;

if(count1!=1) break; } break; case 2:

for(x=0;x<14;x++) {

duan=1;

P1=huayang2[x]; beep();

delay1(300); duan=0;

if(count1!=2) break; } break; case 3:

for(x=0;x<16;x++) {

duan=1;

P1=huayang3[x];

21

beep();

delay1(300); duan=0;

if(count1!=3) break; } break; case 4:

for(x=0;x<8;x++) {

duan=1;

P1=huayang4[x]; beep();

delay1(300); duan=0;

if(count1!=4) break; } break; } } else {

song();

delay1(1000); } }

}

void int0() interrupt 0 {

EA=0;//关总中断 delay1(1);//去抖 if(key1==0) {

count2=0;//不让蜂鸣器唱歌 TR0=0; count1++; if(count1==5) count1=1;

}

EA=1;//开总中断 }

22

void int1() interrupt 2 {

EA=0;//关总中断 delay1(1);//去抖 if(key2==0) {

count1=0;//流水灯无花样 TR0=1;

i=0;//从头开始唱 count2++; if(count2==3) count2=1;

}

EA=1;//开总中断 }

void timer0() interrupt 1 //用于产生各种音调 {

TH0=timeh; TL0=timel; fm=~fm; }

void song() {

uint temp;

uchar jp;//jp是简谱 i=0; while(1)

{ if(count2==0) {

break; }

if(count2==1) //选曲 temp=qnzl[i]; if(count2==2)

temp=jmszl[i]; if(temp==0xff) break;

jp=temp/16; //取数的高4位 duan=1;

P1=yinyue[jp]; duan=0; if(jp!=0)

23

{

timeh=cuzhi[jp*2]; timel=cuzhi[jp*2+1]; } else {

TR0=0;

fm=1;//关蜂鸣器 }

delay(temp%16); //取数的低4位 TR0=0; //唱完一个音停10MS fm=1;

delay1(10); TR0=1; i++; }

TR0=0; fm=1; }

void delay(uint z) //延时165MS,即十六分音符 { uint x,y;

for(x=z;x>0;x--)

for(y=19000;y>0;y--); }

void delay1(uint z) //延时1MS { uint x,y;

for(x=z;x>0;x--)

for(y=112;y>0;y--); }

void beep() //蜂鸣器叫一声 { uchar i;

for(i=0;i<50;i++) { fm=~fm; delay1(1); }

fm=1; } 24

7.实验总结 音乐盒的程序设计过程中,遇到了很多问题,但是通过不断调试仿真,最终都得到解决。问题是出在蜂鸣器与单片机的输出端口上,在这个环节消耗了很多时间。之前这些程序通过星研软件编译没有错误,而且通过ptotues仿真成功,但在实验板上调试运行时却不行。最终在迟老师的指导下发现问题的所在,就是在单片机输出端口出现问题,由于实验箱中单片机芯片的P2口在实验箱中被其他硬件电路所占用,所以我们在使用此端口时没有达到我们预想的效果,当我们把程序中单片机给蜂鸣器的信号输出端修改为由P3口输出信号,问题最终得到了解决。

通过这次单片机设计,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,同时也使我认识到自身存在的不足之处,无论是理论上还是遇到问题的处理能力上都还有待提高,而且这也激发了我今后努力学习的兴趣。发现问题、提出问题、分析问题、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。

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