9机电 单片机实验指导书.docx
《9机电 单片机实验指导书.docx》由会员分享,可在线阅读,更多相关《9机电 单片机实验指导书.docx(20页珍藏版)》请在冰豆网上搜索。
![9机电 单片机实验指导书.docx](https://file1.bdocx.com/fileroot1/2023-1/28/3a627fd1-b9de-4e2f-aeb8-9aed7b1a0c17/3a627fd1-b9de-4e2f-aeb8-9aed7b1a0c171.gif)
9机电单片机实验指导书
单片机实验指导书
实验一、模拟开关灯实验
一、实验目的
1、认识单片机芯片内部基本结构和功能;2、学习Keil和Proteus软件的基本使用方法;3、了解了解单片机最小系统及单片机应用系统的设计过程。
二、实验说明
1、单片机应用系统基本过程
1)启动Keil,创建一个项目文件*.UV2;
2)选择单片机的型号,如AT89C51;
3)单击菜单“File”→“New”命令,新建源程序文件,输入代码,保存为*.c;
4)把源程序文件添加到项目中,在项目管理器中,在展开的“SourceGroup1”上单击右键,选择“AddFilestoGroup’SourceGroup1’”命令,选择文件添加。
5)选中Target1,鼠标右键菜单“OptionsforTarget‘Target1’”命令,在“Output”选项卡中选中“CreateHEXfile”复选框;
6)执行菜单“Project”→“Rebuildalltargetfiles”命令,编译项目并生成*.hex文件;
7)打开ProteusISIS软件,建立硬件控制电路;
8)用鼠标双击“ATC89C51”单片机弹出对话框,在“ProgramFile”中载入编译好的“*.HEX”文件;
9)在Proteus环境中启动调试程序,观察仿真结果。
三、实验内容及步骤
1、实验内容
使用单片机监控一个按键开关,通过一个发光二极管显示其工作状态。
如果开关打开,LED灯熄灭;开关合上,LED灯亮
2、硬件原理图
3、软件设计
#include//包含的头文件,对单片机内部特殊功能寄存器进行了符号定义
sbitLed=P1^0;//定义位名称
sbitKey=P1^7;
voidmain()
{
P1=0xff;
while
(1)
{
Led=Key;
}
}
画出程序流程图:
四、思考题
1、使用Keil和Proteus如何建立单片机开发系统,描述基本过程。
2、单片机的最小系统包含哪些电路?
实验二、流水灯实验
一、实验目的
1、学习单片机并行I/O端口的使用方法;2、学习延时子程序的编写;3、学习Keil和Proteus软件的基本使用方法。
二、实验说明
1、P1口为一组双向口,每位都可独立地定义为输入或输出线,在作输入线使用前,必须向锁存器相应位写入“1”,该位才能作为输入(即:
P1=0xff)。
2、本实验中延时采用循环程序来实现,入口参数控制延时时间长短。
三、实验内容及步骤
1、实验内容
P1口做输出口,接八位逻辑电平显示,编写程序,使发光二极管循环点亮。
通过一个按键开关控制显示顺序,如果开关打开,LED自上而下依次点亮;开关合上,LED从下向上依次点亮。
2、硬件原理图
3、软件设计
1)、画出程序流程图2)源程序
#include
#defineucharunsignedchar//类型重定义
#defineuintunsignedint
sbitKey=P0^0;//定义位名称
voidDelayMS(uintms);//延时函数原型声明
voidmain()
{
uchari,keyPre,shift;
Key=1;
while
(1)
{
keyPre=Key;
if(keyPre)
{
shift=0x01;
for(i=0;i<8;i++)
{P1=~shift;DelayMS(200);shift<<=1;}
}
else
{shift=0x80;
for(i=0;i<8;i++)
{P1=~shift;DelayMS(200);shift>>=1;}
}
}
}
voidDelayMS(uintms)
{
uchari;
while(ms--)
for(i=0;i<120;i++);
}
四、思考题
1、MCS-51系列单片机的P0~P3四个I/O端口在结构上有何异同?
使用时应注意的事项?
实验三、定时器实验
一、实验目的
1、学习单片机内部计数器的使用和编程方法;2、掌握中断处理程序的编写方法;3、学习Keil和Proteus软件的基本使用方法。
二、实验说明
1、采用定时器方式设计一交通灯控制系统,使道路状态切换时间更准确。
正常情况下,90s后信号灯由“红灯”转“黄灯”,经过2s的过渡后“黄灯”转“绿灯”,另外设东西方向、南北方向紧急开关各一个,紧急开关闭合时,相应方向切换成“绿灯”,以方便特种车辆通过。
另设置一个开关,在晚上由人工闭合,此时所有的灯都变成黄灯。
2、系统的晶振是12MHZ,定时器1工作于方式1,即16位定时器,定时器50000uS(50mS)中断一次,所以定时常数的设置可按以下方法计算:
定时时间=(65536-定时常数)×1uS=50000uS
定时常数=15536,(0x3CB0)对50mS中断次数计数10次,就是0.5秒钟。
定时器0工作于方式1,定时20ms,定时常数=45536,(0XB1E00)。
三、实验内容及步骤
1、硬件原理图
2、软件设计
1)、画出程序流程图2)源程序
#include
#include
unsignedchart0;
voidyellow();//东西、南北方向同时打开黄灯
voidyellowflash();//东西、南北方向同时打开黄灯,每隔0.5秒开始闪烁
voiddelay0_5s();//延时0.5秒
voiddelayxms(unsignedchart);//延时t*0.5秒
/******************************************************************
函数名称:
ex_intex0;函数功能:
外部中断0服务子程序
******************************************************************/
voidex_intex0(void)interrupt0
{
EA=0;//关闭中断,不允许中断嵌套
while((P3&0x04)==0)//检测外部中断0是否持续有效
{
P1=0x1E;//东西方向绿灯亮、南北方向红灯亮,其它四个灯关闭。
}
EA=1;//打开中断
}
/******************************************************************
函数名称:
ex_intex1;函数功能:
外部中断1服务子程序
******************************************************************/
voidex_intex1(void)interrupt2
{
EA=0;//关闭中断,不允许中断嵌套
while((P3&0x08)==0)//检测外部中断1是否持续有效
{
P1=0x33;//东西方向红灯亮、南北方向绿灯亮,其它四个灯关闭。
}
EA=1;//打开中断
}
/******************************************************************
函数名称:
tm_timer0;函数功能:
定时器0服务子程序
******************************************************************/
voidtm_timer0(void)interrupt1
{
EA=0;//关闭中断,不允许中断嵌套
while((P3&0x40)==0)//检测P3.6开关是否闭合
{
yellow();//东西、南北方向同时打开黄灯
}
TH0=0xb1;//20ms定时初值重新装入
TL0=0xe0
EA=1;//打开中断
}
//主程序
voidmain()
{
TMOD=0x11;//T1工作方式1,T0工作方式0
EA=1;
EX0=1;IT0=0;//打开外部中断0
EX1=1;IT1=0;//打开外部中断1
ET0=1;//打开定时器0中断
TH0=0xb1;//20ms定时初值重新装入
TL0=0xe0
TR0=1;//启动定时器0
while
(1)//无限循环
{
P1=0x1e;//东西方向绿灯亮、南北方向红灯亮,其他四个灯关闭。
delayxms(180);//延时90秒
yellowflash();//东西、南北方向同时打开黄灯,每隔0.5秒闪烁一次
P1=0x33;//东西方向红灯亮、南北方向绿灯亮,其他四个灯关闭。
delayxms(180);//延时90秒
yellowflash();//东西、南北方向同时打开黄灯,每隔0.5秒闪烁一次
}
}
/******************************************************************
函数名称:
yellow;功能:
东西、南北方向同时打开黄灯
******************************************************************/
voidyellow()
{
P1=0x2d;//两个黄灯同时打开
}
/******************************************************************
函数名称:
yellowflash;功能:
东西、南北方向同时打开黄灯,每隔0.5秒闪烁一次
******************************************************************/
voidyellowflash()
{
unsignedchari;
for(i=0;i<2;i++)
{
P1=0x2d;//两个黄灯同时打开
delay0_5s();
P1=0xff;//两个黄灯同时关闭
delay0_5s();
}
}
/******************************************************************
函数名称:
delay0_5s
函数功能:
延时0.5s,用T1工作方式1定时50ms,再循环10次得到0.5s的延时时间
******************************************************************/
voiddelay0_5s()
{
for(t0=0;t0<10;t0++)
{
TH1=0x3c;
TL1=0xb0;
TR1=1;
while(!
TF1);//TF1=1时50ms定时时间到
TF1=0;
TR1=0;
}
}
/******************************************************************
函数名称:
delayxms;函数功能:
在函数delay0_5s的基础延时,即延时t*0.5秒
******************************************************************/
voiddelayxms(unsignedchart)
{
for(t0=0;t0delay0_5s();
}
四、思考题
1、如果更换不同频率的晶振,会出现什么现象?
如何调整程序?
实验四、外部中断实验
一、实验目的
1、掌握外部中断技术的基本使用方法;2、掌握中断处理程序的编写方法;3、学习Keil和Proteus软件的基本使用方法。
二、实验说明
1、外部中断的初始化设置共有三项内容:
中断总允许即EA=1;外部中断允许即EXi=1(i=0或1);中断方式设置,中断方式设置一般有两种方式:
电平方式和脉冲方式。
本实验选用脉冲方式,中断请求信号由引脚INT0(P3.2)引入。
2、51系列用于中断的控制寄存器有四个:
TCON、IE、SCON及IP。
3、中断过程分为三个阶段:
中断请求、中断响应、中断服务。
4、开关K0(中断请求信号)利用外部中断INT0接入。
采用中断边沿触发方式,每中断一次,单片机对P1口完成一次读写操作。
当P1.0~P1.3任何一位输出0时,相应的发光二极管就会发光。
当开关K0来回拨动一次时,将产生一个下降沿信号,通过INT0发出中断请求。
三、实验内容及步骤
1、硬件原理图
2、软件设计
1)分别画出主程序和中断服务程序流程图2)源程序
#include
sbitP1_0=P1^0;sbitP1_1=P1^1;
sbitP1_2=P1^2;sbitP1_3=P1^3;
sbitP1_4=P1^4;sbitP1_5=P1^5;
sbitP1_6=P1^6;sbitP1_7=P1^7;
/******************************************************************
函数名称:
ex_intex0;函数功能:
外部中断0服务子程序
******************************************************************/
voidex_intex0(void)interrupt0
{
P1_0=P1_4;P1_1=P1_5;
P1_2=P1_6;P1_3=P1_7;
}
//主程序
voidmain()
{
P1=0xff;//P1口四个按键位置1
EX0=1;//开外部中断0
EA=1;//开中断总开关
IT0=1;//外部中断0电平触发
while
(1)//等待中断
{;}
}
四、思考题
1、简述中断处理的一般过程。
实验五、单片机之间的串行双机通信
一、实验目的
1、学习单片机串行口的工作原理;2、掌握串行通信的编程方法及波特率的设置;3、进一步学习定时器的功能和编程。
二、实验说明
1、本实验采用两台AT89C51单片机U1和U2进行串行双机通信设计。
U1作为发送机,U2作为接收机,两者的发送脚RXD和接收脚TXD交叉连接。
U1通过串行口间接控制与U2的P1口相连的8个LED发光管亮灭。
2、单片机间通信采用串行口方式1,对单片机U1编程时,需令SM0=0,SM1=1;对单片机U2编程时,除了令SM0=0,SM1=1,还需设置REN=1,使其允许接收。
3、晶体振荡器频率为11.0592MHz,选择波特率为9600b/s,SMOD=0,定时器1工作方式2:
TH1=TL1=FDH。
三、实验内容及步骤
1、硬件原理图
2、软件设计
1)、画出程序流程图2)源程序
⑴单片机U1的发送程序
使用Keil软件建立“send”工程项目,建立源程序文件“send.c”,输入如下源程序:
#include
//流水灯控制码
unsignedcharTab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
/********************************************************************
函数名称:
Send;函数功能:
发送一个字节数据
********************************************************************/
voidSend(unsignedchardat)
{
SBUF=dat;//将待发送数据写入发送缓冲器
while(TI==0);
TI=0;//用软件将TI清零
}
/********************************************************************
函数名称:
delay;函数功能:
延时约150ms
********************************************************************/
voiddelay(void)
{
unsignedcharm,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++);
}
//主程序
voidmain(void)
{
unsignedcharI;
TMOD=0x20;//TMOD=00100000B,定时器T1工作在方式2
SCON=0x40;//SCON=01000000B,串口工作在方式1
PCON=0x00;//PCON=00000000B,波特率9600b/s
TH1=0xfd;//给定时器T1高8位赋初值
TL1=0xfd;//给定时器T1低8位赋初值
TR1=1;//启动定时器T1
while
(1)
{
for(i=0;i<8;i++)//共8位流水灯控制码
{
Send(Tab[i]);//发送数据i
delay();//每发送一次数据,延时150ms再发送
}
}
⑵单片机U2的接收程序
使用Keil软件建立“receive”工程项目,建立源程序文件“receive.c”,输入如下源程序:
#include
/********************************************************************
函数名称:
Receive;函数功能:
接收串行口数据
********************************************************************/
unsignedcharReceive(void)
{
unsignedchardat;
while(RI==0);//空操作
RI=0;//用软件将RI清零,为接收下一帧数据做准备
dat=SBUF;//将接收缓冲器的数据存于dat
returndat;
}
//主程序
voidmain(void)
{TMOD=0x20;//TMOD=00100000B,定时器T1工作在方式2
SCON=0x50;//SCON=01010000B,串口工作在方式1,允许接收(REN=1)
PCON=0x00;//PCON=00000000B,波特率9600b/s
TH1=0xfd;//给定时器T1高8位赋初值
TL1=0xfd;//给定时器T1低8位赋初值
TR1=1;//启动定时器T1
REN=1;//允许接收
while
(1){P1=Receive();}
}
四、思考题
1、异步串行通信协议的帧格式是怎样的?
已知系统时钟频率和波特率,如何计算定时器初值?
2、接收时采用中断方式时,程序代码应该如何改?
实验六、数码管显示4×4阵列式键盘按键
一、实验目的
1、掌握数字、字符转换成显示段码的软件译码方法2、掌握键盘和显示器的接口方法和编程方法;3、掌握阵列式键盘的硬件组成和软件编程方法。
二、实验说明
1、本实验提供了一个4X4小键盘,向P0口的低四位逐个输出低电平,如果有键盘按下,则相应输出为低,如果没有键按下,则输出为高。
通过输出的列码和读取的行码来判断按下什么键。
2、去抖动,有键按下后,要有一定的延时,防止由于键盘抖动而引起误操作。
三、实验内容及步骤
1、硬件原理图
2、源程序及流程图
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharconstdofly[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F的显示代码
ucharkeys_scan();
voiddelay(uinti);
voidmain()//主程序
{ucharkey;
P0=0x00;//数码管灭,为显示键码作准备
while
(1)
{key=keys_scan();//调用键盘扫描,
switch(key)
{case0xee:
P0=dofly[0];break;//0按下相应的键显示相应的码值
case0xde:
P0=dofly[1];break;//1
case0xbe:
P0=dofly[2];break;//2
case0x7e:
P0=dofly[3];break;//3
case0xed:
P0=dofly[4];break;//4
case0xdd:
P0=dofly[5];break;//5
case0xbd:
P0=dofly[6];break;//6
case0x7d:
P0=dofly[7];break;//7
case0xeb:
P0=dofly[8];break;//8
case0xdb:
P0=dofly[9];break;//9
case0xbb:
P0=dofly[10];break;//a
case0x7b:
P0=dofly[11];break;//b
case0xe7:
P0=dofly[12];break;//c
case0xd7:
P0=dofly[13];break;//d
case0xb7:
P0=dofly[14];break;//e
case0x77:
P0=dofly[15];break;//f
}
}
}
/********************************************************************
函数名称:
keys_scan;函数功能:
键盘扫描函数
返回值:
返回键盘码,高4位为行码,低4位为列码
********************************************************************/
ucharkeys_scan()
{
ucharcord_h,cord_l;//行列值
P3=0x0f;//列线输出全为0
cord_h=P3&0x0f;//读入行线值
if