资源描述
实验1 跑马灯实验
一、实验目的
l 初步学会Proteus ISIS和 uVision2单片机集成开发环境的使用;
l 初步掌握采用汇编语言与C语言开发单片机系统的程序结构;
l 掌握80C51单片机通用I/O口的使用;
l 掌握单片机内部定时/计数器的使用及编程方法以及中断处理程序的编写方法。
二、实验设备及器件
l 硬件:PC机,HNIST-1型单片机实验系统
l 软件:Proteus ISIS单片机仿真环境,uVision2单片机集成开发环境
三、实验内容
l 编写一段程序,采用P1口作为控制端口,使与P1口相接的四个发光二极管(D1、D2、D3、D4)按照一定的方式点亮。如点亮方式为:先点亮D1,延时一段时间,再顺序点亮D2……D4,然后又是D4……D1,同时只能有一个灯亮;然后每隔一段时间一次使相邻两个灯亮,三个灯亮,四个灯亮,最后闪烁三次,接着循环变化。
l 基于Proteus ISIS仿真环境完成上述功能的仿真。
l 基于uVision2单片机集成开发环境与硬件平台完成程序的脱机运行。
四、实验原理图
图3.1 跑马灯实验电路原理图
电路原理图如上图3.1所示,AT89S52的P1.0~P1.3控制4个发光二极管,发光二极管按照一定次序发光,相邻发光二极管的发光时间间隔可以通过定时器控制,还可以通过软件延时实现。
五、软件流程图与参考程序
l 主程序流程图如下:
开 始
初始化(定时器、中断、标志位设置)
Flag=1?
流水灯操作
结 束
Y
N
l 参考程序
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar aa,num,speed,flag;
uchar code table[]={0x0e,0x0d,0x0b,0x07};
uchar code table1[]={0x0a,0x05,0x09,0x06};
uchar codetable2[]={0x0c,0x09,0x03,0x08,0x01,0x0e,0x0c,0x08,0x00};
void delay(uint z)//延时函数
{
uint x;
uchar y;
for(x=z;x>0;x--)
for(y=200;y>0;y--);
}
void init()//条件初始化函数
{ flag=0;
speed=10;//控制跑马灯流水速度
TMOD=0x01;//中断方式
TH0=(65535-50000)/256;
TL0=(65536-50000)%256;//初值
EA=1;//打开总中断
ET0=1;//打开外中断0
TR0=1;
}
void main()
{
init();//调用初始化函数
while(1)
{
if(flag)
{
delay(2000);//调用延时函数
for(num=0;num<4;num++)//从左至右间隔一个依次闪烁
{
P1=table[num];
delay(2000);
}
for(num=3;num>0;num--)//从左至右间隔一个依次闪烁
{
P1=table[num];
delay(2000);
}
for(num=0;num<4;num++)//从左至右间隔两个依次闪烁
{
P1=table1[num];
delay(2000);
}
for(num=3;num>0;num--)//从左至右间隔两个依次闪烁
{
P1=table1[num];
delay(2000);
}
for(num=0;num<6;num++)//两个,三个,四个跑马灯依次闪烁
{
P1=table2[num];
delay(2000);
}
for(num=0;num<5;num++)//闪烁5次
{
P1=0xff;//全暗
delay(2000);
P1=0X00;//全亮
delay(2000);}
speed=speed-3;//变速
if(speed==4)
{speed=10;}
}
}
}
void timer0() interrupt 1//中断函数
{
TH0=(65535-50000)/256;
TL0=(65536-50000)%256;
aa++;
if(aa==speed)
{
aa=0;
flag=1;
}
}
六、实验思考题
l 请用汇编指令完成本实验内容,深刻理解汇编语言程序设计结构。
l 在本实验中,I/O口作为输出口使用,如果把I/O口的某些口线作为输入口使用时,如何获得输入引脚状态?请举例说明。
l 在画软件流图时,各种不同形式方框意义是否相同?请举例示之。
l 请简要叙述中断服务程序功能并画出其流程图。
l 在采用I/O口作为输出口时要考虑哪些因素?如果负载变化,如何设计单片机与负载之间的接口电路?
实验2 交通灯实验
一、实验目的
l 进一步掌握Proteus ISIS和 uVision2单片机集成开发环境的使用;
l 进一步掌握单片机内部定时/计数器的使用及编程方法以及中断处理程序的编写方法
l 掌握单片机的I/O口编程使用。
二、实验设备及器件
l 硬件:PC机,HNIST-1型单片机实验系统,USB下载线一根、连接线若干
l 软件:Proteus ISIS单片机仿真环境,uVision2单片机集成开发环境
三、实验内容
l 编写一段程序,实现用单片机的I/O口控制12个发光二极管(四组,每组有红绿蓝三个发光二极管),使发光二极管按照一定的规则模拟交通灯功能。
l 基于Proteus ISIS仿真环境完成上述功能的仿真。
l 基于uVision2单片机集成开发环境与硬件平台完成程序的脱机运行。
四、实验原理
图3.2 交通灯实验原理图
用单片机的IO口控制4组红绿蓝共12个发光二极管,使发光二极管按照一定规则与次序发光与闪亮以实现模拟交通灯的功能。假设初始状态为:(南北通行状态)南北绿灯、东西红灯(25s);后转为过度状态:南北黄灯、东西红灯(5s);再转为东西通行状态:东西绿灯、南北红灯25(s)。再转为过渡状态:东西黄灯、南北红灯(5s),然后循环往复。
硬件原理图如上图3.2所示。由于发光二极管的导通电压为1.7V,所以在电源与二极管之间加一个电阻,目的是保护二极管;实验中利用定时计数器实现1S的定时,然后在此基础上实现所需要的定时时间。
五、软件流程图与参考源程序
l 软件设计思想:在编程时,我们一般把一个独立的功能设计成一个子程序或者说函数。对于不同的设计者而言,对软件功能的划分角度不同,对应的函数功能也存在差异。
开 始
南北绿灯 东西红灯25
南北黄灯 东西红灯5
东西绿灯 南北红灯25
东西黄灯 南北红灯5
结 束
定 时 器
图3.3 软件结构图
l 参考源程序如下:
#include<reg52.h>//头文件
#define uint unsigned int
#define uchar unsigned char//定义下方便使用
sbit kong=P1^4;//位声明 数码管锁存控制端
uchar code table[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};//数字0-9编码
uint tt,temp=0;
/************************************************
延时函数
**************************************************/ void delay(uint x)
{
uchar i,k;
for(i=0;i<x;i++)
for(k=0;k<100;k++)
;
}
/**************************************************
初始化函数
***************************************************/
void init()
{
temp=0;
tt=0;
TMOD=0x01;//定时器工作方式
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;//装初值
EA=1;//开总中断
ET0=1;//开定时器中断
TR0=1;//启动定时器中断
}
/*************************************************
数码管显示函数
*************************************************/
void display(uint x1)
{
uchar i,c;
uint cod[4];
cod[3]=x1/1000;
cod[2]=x1%1000/100;
cod[1]=x1%1000%100/10;
cod[0]=x1%10 ;//求个数码管的值
c=0x01;
for(i=0;i<4;i++)
{
P1=c;//数码管的显示选择
P0=table[cod[i]];//送要显示的值
kong=1;//打开锁存
c=c<<1;//左移一位选择下一个数码管
kong=0;//关闭锁存
delay(10);
}
}
/****************************************
交通灯驱动函数
*****************************************/
void jiaotong()
{ // uint t=0;
if(temp==0)
temp=60;//给temp装值,也即是交通灯循环一次要的时间
if(temp>30)
{
if(temp<=35)
{
display(temp-30);
P2=0Xf5;//南北黄灯、东西红灯(5s)
}
else
{
display(temp-30);
P2=0xdd; //南北绿灯、东西红灯(25s)
}
}
else
{ if(temp<=5)
{
display(temp);
P2=0xee; //东西黄灯、南北红灯(5s)
}
else
{
display(temp);
P2=0xeb; //东西绿灯、南北红灯25(s)
}
}
if(tt==20) //判断时间是否过了1s
{
tt=0;
temp--;//倒计数
}
}
/************************************************
主函数
************************************************/
void main()
{
init();//初始化函数调用
while(1)//主循环
{
jiaotong();//交通灯函数调用
}
}
//中断函数
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //重新装初值
tt++;
}
六、实验思考题
l 如何实现扩充功能,实现救护车优先通过十字路口?请叙述硬件设计与软件设计原理。
l 在利用单片机片内定时器实现精确定时时,是否会产生误差?如果存在误差请分析误差产生原因以及减小误差方法。
实验3 数码管动态显示实验
一、实验目的
l掌握数码管静态显示与动态显示原理以及数码管与单片机的接口原理。
l学会利用单片机的I/O口实现数码管的动态显示。
二、实验仪器
l硬件:PC机、HNIST-1型单片机实验系统
l软件:Proteus ISIS单片机仿真环境,uVision2单片机集成开发环境
三、实验内容
l编写一段程序,采用P1口某些口线作为4位数码管的位控制端;采用P0口输出段码,实现4位数码管的测试(让4位数码管同时输出0~F);
l编写程序,让4位数码管循环显示1—2—3—4(即让第一位显示”1”,然后第一位熄灭,第二位显示”2”……)
四、实验原理
使用LED数码显示器时,要注意区分数码管两种不同的接法(共阴LED和共阳LED),为了显示数字或字符,必须对数字或字符进行编码。七段数码管加上一个小数点,共计8段,因此为LED显示器提供的编码正好是一个字节。八段LED数码管显示器原理与结构如下图3.4所示。对于共阴接法,要使某位LED显示相应数码,则使LED的对应段点亮,则对应控制电平为高,如:要显示数字”0”,如果a~dp分别受P0.7~P0.0控制,则LED的a,b,c,,d,e,f需点亮,对应驱动电平为”1”,其他为”0”,则对应数码”0”的段码为”FCH” 。
共阴极 共阳极
图3.4 八段LED数码管原理与结构图
LED显示器工作方式有两种:静态显示方式和动态显示方式。静态显示的特
点是每个数码管的段码必须需要一个数据锁存器锁存,当送入字形码后,显示字形可一直保持,直到送入新字形码为止,显示亮度较强。而动态显示是多个LED轮流显示,但由于人眼的视觉惰性,使人感觉各LED同时显示不同字符。
表3.1 本实验硬件所采用共阴极数码管码表
数字
数码管代码
数字
数码管代码
数字
数码管代码
0
0xfc
6
0xbe
C
0x9c
1
0x60
7
0xe0
d
0x7a
2
0xda
8
0xfe
E
0x9e
3
0xf2
9
0xf6
F
0x8e
4
0x66
A
0xee
无显示
0x00
5
0xb6
b
0x3e
一般而言,为了减少硬件开销,降低成本,单片机系统通常采用LED动态扫描显示方式。本实验电路原理图如下图3.5所示。
图3.5 LED动态显示电路原理图
五、部分软件流程图与参考程序
●流程图
开始
初始化P0口,P1
口及变量num.
判断num是否小于16
否
num=0
是
显示table[num];
num++.
延时
图3.6 软件流程图
●源程序.
#include<reg52.h>//包含头文件
#define uchar unsigned char
#define uint unsigned int //宏定义
sbit dula=P1^4; //端口定义
uchar num,y;
uint x; //定义变量uchar
code table[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,
0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e}; //0到F的数码管管码
/********************主函数**********************/
void main()
{
while(1)//进入大循环
{
P1=P1︱0x1f;
for(num=0;num<16;num++) //判断是否到F
{
dula=1;//开启锁存器
P0=table[num];//送数码管管码
dula=0;//关闭锁存器
for(x=2000;x>0;x--)
for(y=220;y>0;y--); //延时
}
}
}
六、实验思考题
●本实验源程序是让4位LED同时显示相同的内容,完成其测试。请编写程序让4位LED轮流显示从0~F的数码(即让第一位数码管显示0后,接着第二位数码管显示0,…,一个轮回结束后,让第一个显示1,…)。
● 请设计一个单片机控制的4位数码管的静态显示电路,解释其工作原理。
● 如何采用本实验电路以及单片机片内定时器实现一个简易时钟功能(精度较低),说明实现方式。
实验4 8*8 LED点阵实验
一、实验目的
l 了解LED点阵显示原理;
l 掌握LED点阵显示器件与单片机的接口电路设计原理;
l 掌握LED显示器件显示驱动程序设计方法,能编写LED显示驱动程序。
二、实验设备及器件
l 硬件:PC机,HNIST-1型单片机实验系统
l 软件:Proteus ISIS单片机仿真环境,uVision2单片机集成开发环境
三、实验内容
l 根据给定实验设备,选用相关模块,完成LED点阵显示实验系统的硬件平台构建;
l 根据所构建硬件平台,编程实现点阵循环显示数字0~9。
四、实验原理
l 芯片介绍
1:74LS138 :3 线-8 线译码器。原理:当一个选通端(G1)为高电平,另两个选通端(/G2A和/G2B)为低电平时,可将地址端(A、B、C)的二进制编码在一个对应的输出端以低电平译出,Y0-Y7为输出端。另外,74LS138真值表请参看相关资料。
2:74LS595:串入并出8位输出移位锁存器。以下为其引脚功能说明:
QA--QH: 八位并行输出端,可以直接控制数码管的8个段(或者点阵LED的列线)。
QH': 级联输出端。我将它接下一个595的SI端。
SER: 串行数据输入端。
/SCLR(10脚): 低电平时将移位寄存器的数据清零。通常我将它接Vcc。
SCK(11脚):上升沿时数据寄存器的数据移位。QA-->QB-->QC-->...-->QH;
下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。通 常都选微秒级)
RCK(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将RCK置为低点平,当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。通常都选微秒级),更新显示数据。
/G(13脚): 高电平时禁止输出(高阻态)。
另外,74LS595操作时序请参考相关资料。请根据操作时序,叙述操作过程。
l 实验原理图
如下图3.7所示。
图3.7 点阵LED实验电路原理图
五、软件流程图与参考程序
l 软件流程图
首选确定所需要的子程序。子程序主要包括:一是74LS595芯片驱动程序,完成串入并出,控制LED点阵列的驱动;一个是驱动74LS138芯片的,实现LED点阵行的驱动;还有一个是延时函数。读者可以根据相应芯片工作原理完成其驱动流程图绘制;
对于要显示的字符0~9的循环显示,显示间隔采用定时器实现,此时涉及到定时器中断服务子程序的编写,另外,LED点阵列驱动采用的是动态显示原理,也需要定时器定时;
对于主程序而言就很简单了,主要是完成一些初始化工作。
l 源程序:
#include<reg52.h> //头文件
#include<intrins.h>
#define uchar unsigned char //宏定义
#define uint unsigned int
sbit SCK=P0^0; //芯片端口连线定义
sbit RCK=P0^1;
sbit SER=P0^2;
sbit D138_A=P0^5;
sbit D138_B=P0^6;
sbit D138_C=P0^7;
uchar code hang[8]={1,2,3,4,5,6,7,8}; //点阵行数组定义
uchar code lie[10][8]={ //数字0~9列代码
{0x00,0x7c,0x82,0x82,0x82,0x7c,0x00,0x00}, //0
{0x00,0x00,0x84,0xfe,0x80,0x00,0x00,0x00}, //1
{0x00,0xe4,0x92,0x92,0x92,0x8c,0x00,0x00}, //2
{0x00,0x44,0x92,0x92,0x92,0x6c,0x00,0x00}, //3
{0x00,0x10,0x18,0x14,0xfe,0x10,0x10,0x00}, //4
{0x00,0x4e,0x8a,0x8a,0x8a,0x72,0x00,0x00}, //5
{0x00,0x7c,0x92,0x92,0x92,0x64,0x00,0x00}, //6
{0x00,0x02,0x02,0xfa,0x06,0x02,0x00,0x00}, //7
{0x00,0x6c,0x92,0x92,0x92,0x6c,0x00,0x00}, //8
{0x00,0x4c,0x92,0x92,0x92,0x7c,0x00,0x00} //9
};
uint timecount;
uchar a,b;
void Delay(uchar time)//延时函数
{
uchar i,j;
for(i=time;i>0;i--)
for(j=320;j>0;j--);
}
void Set595(unsigned char Data)//74LS595驱动函数
{
unsigned char i;
for(i = 0; i < 8; i++)
{
SCK = 0; //先置为低
SER = Data & 0x80; //取数据的最高位
Data <<= 1; //将数据的次高位移到最高位,为下一次取数据做准备
SCK = 1; //再置为高,产生移位时钟上升沿,上升沿时数据
//寄存器的数据移位
}
RCK=0;
_nop_();
RCK=1;
}
void Set138(unsigned char Data) //138芯片二进制译码选择行输出
{
switch(Data)
{
case 0:
D138_A = 0;
D138_B = 0;
D138_C = 0;
Delay(1); break;
case 1:
D138_A = 1;
D138_B = 0;
D138_C = 0;
Delay(1); break;
case 2:
D138_A = 0;
D138_B = 1;
D138_C = 0;
Delay(1); break;
case 3:
D138_A = 1;
D138_B = 1;
D138_C = 0;
Delay(1); break;
case 4:
D138_A = 0;
D138_B = 0;
D138_C = 1;
Delay(1); break;
case 5:
D138_A = 1;
D138_B = 0;
D138_C = 1;
Delay(1); break;
case 6:
D138_A = 0;
D138_B = 1;
D138_C = 1;
Delay(1); break;
case 7:
D138_A = 1;
D138_B = 1;
D138_C = 1;
Delay(1); break;
}
}
void main(void)
{
TMOD=0x01; //设置定时器的工作方式;
TH0=(65536-3000)/256; TL0=(65536-3000)%256; //设置初值,每次定时中断3ms;
EA=1; //开启总中断;
ET0=1; //开启定时器0中断;
TR0=1; //启动定时器;
P0=0x00;
while(1)
{
;
}
}
void extern0() interrupt 1
{
TH0=(65536-3000)/256;
TL0=(65536-3000)%256;
Set138(hang[a]);
Set595(lie[b][a]);
_nop_();
_nop_();
a++;
if (a==8)
{
a=0;
}
timecount++;
if(timecount==330) //每次到了330次中断后,又重新开
//始计时,每次差不多1s;即每隔1s显示一个数字;
{
timecount=0;
b++;
if(b==10)
{
b=0;
}
}
}
六、实验思考题
l 可否不用这两个芯片,直接用I/O口来控制点阵的行与列来达到我们的目的,并分析这样做的优缺点。
l 查阅资料,比较74LS164与74LS595这两个串入并出芯片的特点。
l 若显示的数字出现左右倒相,上下倒位,请分析可能的原因,以及解决的方法。
l 8*8 LED点阵显示器采用动态显示原理。分析其驱动工作过程。
实验5 矩阵式键盘显示
一、实验目的
l 掌握矩阵式键盘的工作原理以及与单片机的接口方法;
l 掌握矩阵式键盘的按键识别方法(扫描法与线反转法),并能够编写相应键盘处理程序实现按键的识别。
二、实验仪器
l 硬件:PC机,HNIST-1型单片机实验系统
l 软件:Proteus ISIS单片机仿真环境,uVision2单片机集成开发环境
三、实验内容
l 编写程序:读取矩阵式键盘按键键码,并通过数码管显示。
l 显示要求:四个数码管同时显示同一字符:
(1)按0—9号键显示数字0—9;
(2)按A—F号键显示字母A—F。
四、实验原理
单片机的P2口作为矩阵式键盘扫描I/O口,对键盘进行逐行扫描,若检测到按键,则将得到的扫描结果返回给CPU,转换成相应的数码管显示代码,通过数码管显示子程序在数码管上显示按键。 实验原理如下图3.8所示。
图3.8 键盘扫描电路原理图
五、软件流程图与参考程序
l 流程图
图3.9 键盘扫描显示主程序流程图 图3.10 键盘扫描程序流程图
l 参考源程序
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar num,temp,i;
uchar code table[]=
{0xfc,0x60,0xda,0xf2,
0x66,0xb6,0xbe,0xe0,
0xfe,0xf6,0xee,0x3e,
0x9c,0x7a,0x9e,0x8e,0};
uchar code table1[]=
{0xf7,0xfb,0xfd,0xfe};
sbit ale=P1^4;
void display(uchar aa);
uchar keyscan();
/************************************************************
延时子程序
************************************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
num=17;
while(1)
{
display(keyscan());
}
}
/************************************************************
数码管显示
************************************************************/
void display(uchar aa)
{
ale=1;
P0=table[aa-1];
ale=0;
}
/************************************************************
键盘扫描
************************************************************/
uchar keyscan()
{
for(i=1;i<5;i++)
{
P2=table1[i-1];
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P2;
switch(temp)
{
case 0xe7:num=1;
break;
case 0xd7:num=2;
break;
case 0xb7:num=3;
break;
case 0x77:num=4;
break;
case 0xeb:num=5;
break;
case 0xdb:num=6;
break;
case 0xbb:num=7;
break;
case 0x7b:num=8;
break;
case 0xed:num=9;
break;
case 0xdd:num=10;
break;
case 0xbd:num=11;
break;
case 0x7d:num=12;
break;
case 0xee:num=13;
break;
case 0xde:num=14;
break;
case 0xbe:num=15;
break;
case 0x7e:num=16;
break;
}
while(temp!=0xf0)
{
temp=P2;
temp=temp&0xf0;
}
}
}
return num;
}
六、实验思考题
l 如何实现键盘信号的可靠采集?请叙述原理,并请简要说明如果系统软件采用前后台的程序结构,采集按键信号安排在后台程序(主程序)和安排在定时中断服务程序中有什么差异?
l 请简要叙述如何处理按键连击。
实验6 马达调速控制
一、实验目的
l 掌握步进电机的工作原理、控制方式和调速方法,以及其与单片机的接口和驱动编程方法。
l 掌握直流电机的开启控制与转动速度控制方法。
二、实验仪器
l 硬件:PC机、HNIST-1型单片机实验系统
l 软件: uVision2单片机集成开发环境
三、实验内容与原理
l 实验内容:编写程序,通过单片机的P1口控制步进电机的控制端,使其按照一定的控制方式进行转动。
l 实验原理
◆步进电机的控制
单片机的P1口输出脉冲信号,驱动步进电机旋转。引入开关,实现对步进电机(马达)的启停、转向和速度控制。
(1) 旋转方向控制
步进电机以四相四拍方式工作,若按次序通电为正转,按次序通电为反转。
(2) 旋转速度控制
每改变1次节拍,步进电机旋转18度。调节脉冲的周期就可以控制步进电机的转速。
图3.11 步进电机控制原理图
◆直流电机的控制
直流电机的转动由DAC0800来控制,当DAC0800的输出为高电平时直流电机开始转动,当DAC0800的输出为低电平时直流电机停止转动。
图3.12 直流电机控制原理图
四、实验步骤
1、连线、编程
步进电机的插头接J3; BA~BD接89S52的P1.1~P1.4;
展开阅读全文