当前位置:文档之家› 单片机原理实验指导书

单片机原理实验指导书

实验一LED 流水灯一、实验目的1. 学习单片机并口的使用方法。

2. 学习延时子程序的编写和使用。

3. 学习集成开发环境MedWin的安装与使用。

4. 学习STC单片机在线下载软件STC-ISP的使用。

二、实验内容所谓流水灯就是4 个发光二极管(LED)轮流点亮,周而复始。

实验板上以P3口作输出口,接有四只发光二极管,当单片机的引脚输出为低电平时发光二极管点亮,为高电平时息灭。

编写程序,使4 个发光二极管循环点亮,时间间隔约0.5 秒。

三、实验电路连线实验板上与本实验有关的硬件如下图所示。

4 个LED上串联4 个限流电阻,以防止其电流过大而烧坏。

单片机的主时钟为11.0592MHz。

四、实验说明1、P3 口是准双向口,它作为输出口时与一般的双向口使用方法相同。

由准双向口结构可知当P1 口用作输入口时必须先对它置“1”。

若不先对它置“1”,读入的数据是不正确的。

输出时需要接上拉电阻,P3 口内部有弱上拉,若将外围电路设计为低有效,高无效,则无需再外接上拉电阻。

2、为使每次点亮一个LED,应使P3.4~P3.7 4 个端口中有一个为低,其余均为高,延时一段时间后再点亮另一个LED。

3、编写for 循环构成的软件延时子程序,在MedWin 下模拟执行,根据MedWin 显示的执行时间,调整循环变量的终值,使延时时间约0.5秒,在晶振频率为11.0592MHz情况下,循环终值约27000。

程序如下:void delay(void){ unsigned int i,j,k,l;for(i=0;i<=27000;i++){j++; k++;l++;};}#include <REG51.H>void main (void){ unsigned char i,c[4] = {0xef,0xdf,0xbf,0x7f};// 从左往右流水i = 0;while(1){ P3 = c[i & 3];i++;11delay();}}五、思考1、如何使点亮的LED 从右往左移动?2、如何使点亮的LED 从两边往中间移动?实验二用一位数码管循环显示0~9一、实验目的1. 学习单片机并口的使用方法。

2. 学习延时子程序的编写和使用。

3. 学习LED数码管的驱动编码。

二、实验内容实验板上有4 个LED 数码管,编写程序,使最右边的一个LED 数码管循环显示0~9 十个数字。

时间间隔约0.5 秒___________,其余LED数码管关闭。

12三、实验电路连线实验板上与本实验有关的硬件如上页图所示。

4 个共阳的LED 数码管上同名的引脚连接在一起,通过限流电阻接到单片机的P0 口(段控制)。

单片机P2 口的4个引脚分别控制4个LED 数码管的公共端(位控制)。

单片机的主时钟为11.0592MHz。

四、实验说明1、P0 口和P2 都是准双向口,输出时需要接上拉电阻。

P0 内部没有上拉电阻,P2 口内部有弱上拉,本实验外围电路设计均为低有效,故无需外接上拉电阻。

2、下表为驱动LED 数码管的段代码表,“0”代表对应的笔段亮,“1”代表不亮。

若需要在最右边显示数字“5”,只要将从表中查得的段代码2CH 写入P0口,再将P2.4 置低即可。

g c h d e b f a数字P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0十六进制0 1 0 1 0 0 0 0 0 A01 1 0 1 1 1 0 1 1 BB2 0 1 1 0 0 0 1 0 623 0 0 1 0 1 0 1 0 2A4 0 0 1 1 1 0 0 1 395 0 0 1 0 1 1 0 0 2C6 0 0 1 0 0 1 0 0 247 1 0 1 1 1 0 1 0 BA8 0 0 1 0 0 0 0 0 209 0 0 1 0 1 0 0 0 28A 0 0 1 1 0 0 0 0 30b 0 0 1 0 0 1 0 1 25C 1 1 1 0 0 1 0 0 E4d 0 0 1 0 0 0 1 1 23E 0 1 1 0 0 1 0 0 64F 0 1 1 1 0 1 0 0 74- 0 1 1 1 1 1 1 1 7F3、实现最右边的一个LED 数码管循环显示0~9十个数字的C 语言程序如下:#define U8 unsigned charsbit P2_4 = P2^4;code U8 tab[]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28};void delay(void){ unsigned int i,j,k,l;for(i=0;i<=27000;i++){j++; k++;l++;};}13void main(void){ U8 i;P2_4 = 0;while(1){ P0 = tab[i];delay();i++;if(i==10) i = 0;}}五、思考题1. 分别写出六个字母(用于显示十六进制数)的段代码。

2. 能否交替点亮4个LED 数码管?实验三LED 数码管的动态驱动一、实验目的1、学习LED 数码管的动态驱动编程。

2、学习使用定时/计数器。

二、实验内容编写程序,使实验板上的4个LED数码管稳定显示4个不同的数字,并使这四位数从0000开始,每秒钟加一。

三、实验电路连线本实验有关的硬件见实验二。

四、实验说明在实验二中,我们已经能够让某一个LED数码管显示需要的数字,比如选让第一个LED显示“1”,隔一较短的时间(如5 毫秒)后关闭第一个LED,让第二个LED 显示“2”,如此周而复始,让4 个LED 依次显1、2、3、4,我们就能看到4 个LED 上稳定地显示4 个不同的数字。

当然,每个瞬间只有一个LED 被点亮,大家亮的时间相同,均为5 毫秒,4 个LED 数码管点亮一遍需要20 毫秒,一秒钟各亮50 次,所以看上去不会有闪烁感,但亮度只是实验二中LED亮度的四分之一。

要实现每隔5 毫秒变换一个LED,最好的方法是使用定时器中断。

C51 程序如下:#define U8 unsigned charU8 tab[] = {0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28};U8 scn[] = {0x7f,0xbf,0xdf,0xef};//先点亮左边一个数码管14U8 buf[4] = {0,0,0,0};// 显示缓冲区,开机先显示"0000"U8 cnt = 0; // 扫描计数void main(void){ EA = 1; // 允许中断TMOD = 0x01; // 设定时器0 为模式1(16 位)ET0 = 1; // 定时器0中断允许TH0 = 0xee; // 晶振11.0592MHz,5mSTL0 = 0;TR0 = 1; // 开始计数while(1); // 死循环,等待中断}void timeint(void) interrupt 1 // 定时器0中断服务程序{ char i;TH0 = 0xee; // 设置定时器时间常数TL0 = 0;i = cnt & 0x03; // 求应点亮的LED 号(从左到右依次为0,1,2,3)P0 = tab[buf[i]]; // 笔划代码送P0 口P2 = scn[i]; // 控制扫描码送P2口if(cnt==200){ cnt=0; // 到1 秒钟,显示的数字加一for(i=3;i>=0;i--){ buf[i]++;if(buf[i]==10) buf[i]=0;// 加到10 向前进位else break;}}cnt++;}五、思考题如何让4 个LED 数码管从0000开始,每秒钟自动加1,前两位代表分,后两位代表秒?实验四数字电子钟一、实验目的进一步熟悉定时/计数器的使用。

二、实验内容15在实验板上编写程序,实现电子钟功能。

时间显示格式为HH.MM,中间的小数点每秒钟闪烁一次。

三、实验电路连线本实验有关显示部分的硬件见实验二,按钮连接见实验四。

四、实验说明实验二及实验三中LED 数码管的笔划代码均不含小数点(h 位为1,小数点不亮),为了让第2 个LED 的小数点在每一秒的前半秒亮,后半秒灭,应在定时器的中断子程序中,判断当前时间为前半秒,而且动态扫描到第2 个LED时,将其笔划代码取出,和0xDF 相与后再写入P0 口。

该电子钟在上电或复位后时间均从00 时00 分00秒开始,若要使电子钟断电后照常行走,应采取电池供电。

为了降低使用成本及减小体积,可采用两节5 号电池,其满电量时电压为3 伏,89C51单片机的正常工作电压范围为4.5~5.5 伏,无法使用,可选用89C2051 单片机(电压范围2.7~6 伏),最好使用工作电压更低的单片机(如工作电压为1.8伏的AVR单片机)。

为了延长电池使用寿命,必须采取一些节电措施,如将LED 换成液晶、让单片机不工作时进入休眠方式、适当降低单片机的时钟频率等。

五、思考题给电子钟加上能输入当前时间的功能。

实验五自动演奏乐曲一、实验目的(1)进一步熟悉89C51定时器/计数器的功能及应用;(2)掌握其初始化与中断服务程序的编程方法;(3)掌握用定时器/计数器产生不同频率方波的编程方法。

二、实验内容用单片机的定时器/计数器0 作定时器使用,工作于模式1,中断产生方波发声,根据简谱中各个音阶的频率,计算对应的定时时间常数,定时器中断后按此常数赋初值,从而发出对应的音调。

将歌曲的音调和节拍各编成一个表(数组),用音调作为定时器的初值,用节拍控制发音时间,就可以实现自动演奏乐曲。

三、实验电路连线本实验有关的硬件如右图所示。

四、实验说明16产生音阶定时初值的计算:根据下表的音阶频率,计算对应的音阶周期T,用T/2 计算定时周期数(晶振11.0592MHz),填入下表中。

定时器的计数初值为65536-定时周期数,由程序计算产生。

定时周期数增加1 倍,音阶降低八度,定时周期数降低1 倍,音阶升高八度。

音阶表的编码规则为,音阶1-7 用11-17 表示,高八度音阶1-7用21-27表示,低八度音阶1.-7.用1-7 表示。

节拍表的编码规则为,1 拍为16,约570mS,1/2 拍为8,1/4 为4,依此类推。

下面是《康定情歌》的简谱及编码,上一行数字是音阶编码,下一行数字是节拍编码。

自动演奏《康定情歌》乐曲的C51程序为:#include <REG51.h>#define U8 unsigned charcode unsigned int cyc[]={1800,1600,1440,1351,1200,1079,960};//音阶1-7 的半周期数code U8 tone[]={13,15,16,16,15,16,13,12,12,13,15,16,16,15,16,13,13, 13,15,16,16,15,16,13,12,12,15,13,12,13,12,11,12,6,6,12,15,13,12,6,6,15,13,12,13,12,11, 12,6,5,6,0xff};// 乐曲《康定情歌》的简谱表code U8 time[]={8,8,8,4,4,8,8,12,4,8,8,8,4,4,8,16,8,8,8,8,4,4,8,8,12,4,8,8,4,4,音阶(C 调) 1 2 3 4 5 6 7频率(Hz) 256 288 320 341 384 427 480周期(μs) 3906 3472 3125 2932 2604 2342 2083半周期数1800 1600 1440 1351 1200 1079 960174,4,8,24,8,24,8,24,8,16,8,8,8,4,4,4,4,8,16,8,32};// 节拍表U8 H0,L0,cnt;sbit P2_3 = P2^3;sbit P3_2 = P3^2;void cntint0(void) interrupt 1 // 定时器0中断用于产生音阶方波{ TH0=H0;TL0=L0;P2_3=~P2_3; // P2.3是音乐信号输出脚,P2.3反相,产生方波}void cntint1(void) interrupt 3 // 定时器1 中断用于产生节拍延时{ cnt++; // 计数初值为0,所以不用赋值}void main(void){ U8 i,a,t;unsigned int b;next:TMOD=0x11;EA=1;ET0=1;ET1=1;cnt=0;TR1=1;i=0;while(1){ t=tone[i]; // 读音调if(t==0xff) break; // 0xff 是结束符if(t!=0) // 0 是休止符{ b=cyc[t%10-1]; // 根___________据基本音阶,求出半周期数if(t<10) b=b*2; // 若是低八度音阶,半周期数加倍if(t>20) b=b/2; // 若是高八度音阶,半周期数减半H0=(65536-b)/256; // 根据半周期数,计算T0初值的高字节和低字节L0=(65536-b)%256;TR0=1; // 启动定时器0 发音}cnt=0;a=time[i]; // 读节拍while(a>cnt);TR0=0;i++;for(b=0;b<1000;b++); // 稍加延时,增强节奏感18}P2_3=1; // 关闭喇叭while(P3_2==1); // 等待按INT 键goto next; // 重放一遍}五、思考题将程序改成演奏别的乐曲。

相关主题