姓名江嵩学号:110802010017
实验一学习用Keil软件基本调试
一、实验目的
1、 熟悉keil软件的应用,掌握从工程的建立到程序调试,已经程序运行时各个接口的参数的情况。
2、 学习Keil软件的一般操作,步骤为:项目建立、程序录入、添加文件、编译生成HEX文件
二、实验步骤
首先在指定存储路径里新建工程文件夹,然后打开keil这个软件,点击新建工程文件然后点击新建编辑界面然后在左面右击选择文件类型点击add然后在编辑界面里正确输入程序代码然后单击图标依次单击。
三、实验现象
实验二RAM的扩展实验
一、实验目的
1、掌握扩展片外RAM的电路和程序设计方法;
2、理解扩展片外RAM时读、写和ALE等控制线的作用;
3、了解片外RAM情况下,单片机指令MOVX的执行进程。
二、实验要求
在Keil C51系统中运行、调试程序,在Proteus 系统中,画出实验电路图并进行仿真。
三、硬件电路图
四、参考程序
1、汇编语言程序
ORG 00H
MOV DPTR, #1000H
MOV A, #68H
STAR: MOVX @DPTR, A
MOVX A, @DPTR
MOV 30H, A
LJMP STAR
END
2、C语言程序
#include
xdata unsigned char t _at_ 0x1000;
data unsigned char ti _at_ 0x30;
main()
{
while(1)
{ t=0x68;
ti=t;
}
}
四、实验步骤
1、进入Keil C51软件的操作环境,编辑源程序并对源文件进行编译;
2、进入Proteus 系统,画出实验电路图;
3、对Proteus系统和 Keil C51系统进行联机设置;
4、在Keil C51系统中运行、调试程序,在Proteus系统中检查输出结果。
五、实验验证
到指定的文件夹里去打开并运行。
实验三、基于protues的跑马灯电路
一、实验目的
1. 掌握proteus系统的使用,能够建立、保存、打开和修改文件。
2. 掌握使用各种元器件绘制电路原理图的方法,实现电路的仿真。
二、实验内容
跑马灯电路,即完成P1口上的八个发光二极管循环闪亮。
三.实验步骤
3.1、电路原理图:
3.2、电路仿真图:
3.3、实验参考程序(汇编语言):
org 00H
ajmp main
org 30H
main:mov r2,#16
mov a,#0feH
loop:mov p1,a
lcall d1
rl a
djnz r2,loop
d1:mov r4,#10
d2:mov r5,#100
d3:mov r6,#249
djnz r6,$
djnz r5,d3
djnz r4,d2
ret
end
实验四、LED点阵显示实验
一、实验目的
1、了解LED点阵显示的基本原理;
2、掌握用8×8LED点阵构成16×16LED点阵显示系统的硬件连接方法;
3、掌握LED点阵显示的编程方法。
二、实验要求
在Keil C51系统中运行、调试程序,在Proteus 系统中,画出实验电路图。编写程序在点阵显示器上轮流显示汉字。
三、硬件电路图
四、参考程序
1、汇编语言程序
ORG 0000H
START: MOV A,#00H
MOV P0,A
MOV P2,A
MOV 21H,#00
MOV R3,#250
M1: MOV R4,#250;延时程序
DJNZ R4,$
DJNZ R3,M1
MOV 22H,#128
MOV 20H,#00
LOOP2: MOV R5,#80
LOOP: MOV R7,#00
MOV R6,20H
MOV R1,#16
MAIN: MOV A,R6
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P0,A
INC R6
MOV A,R6
MOVC A,@A+DPTR
MOV P2,A
INC R6
MOV A,R7
MOV P1,A
INC R7
LCALL DELAY
MOV A,#00H
MOV P0,A
MOV P2,A
DJNZ R1,MAIN
DJNZ R5,LOOP
MOV A,20H
ADD A,#02
MOV 20H,A
DJNZ 22H,LOOP2
AJMP START
DELAY: MOV R4,#01
D1: MOV R3,#80
DJNZ R3,$
DJNZ R4,D1
RET
TAB:
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H, 00H,00H,00H,00H,00H,00H,00H,00H
DB 0x02,0x00,0x02,0x08,0x7F,0xFC,0x02,0x08,0x02,0x10,0x02,0x20,0xFF,0xFE,0x01,0x80,0x02,0x00,0x0C,0x30,0x34,0xC0,0xC7,0x00,0x04,0x04,0x04,0x04,0x03,0xFC,0x00,0x00
DB 0x08,0x00,0x0B,0xFE,0x48,0x20,0x48,0x20,0x4B,0xFE,0x4A,0x22,0x4A,0x22,0x4A,0x22,0x4A,0x22,0x52,0x22,0x52,0x2A,0x12,0x24,0x20,0x20,0x40,0x20,0x80,0x20,0x00,0x20
DB 0x08,0x00,0x09,0x00,0x11,0xFE,0x12,0x04,0x34,0x40,0x32,0x50,0x52,0x48,0x94,0x44,0x11,0x44,0x10,0x80,0x00,0x00,0x29,0x04,0x28,0x92,0x68,0x12,0x07,0xF0,0x00,0x00
DB 0x02,0x00,0x01,0x00,0x7F,0xFC,0x00,0x00,0x10,0x10,0x08,0x20,0x04,0x40,0xFF,0xFE,0x01,0x00,0x01,0x00,0x7F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00
DB 0x04,0x20,0x04,0x20,0x7F,0xFE,0x04,0x20,0x05,0x20,0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x00,0x00
DB 0x00,0x00,0x7F,0xFC,0x00,0x18,0x00,0x60,0x01,0x80,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00
DB
00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H, 00H,00H,00H,00H,00H,00H,00H,00H
END
2、C语言参考程序
#include
unsigned char tab[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
data unsigned char t1 _at_ 0x21;
data unsigned char t2 _at_ 0x22;
data unsigned char t3 _at_ 0x20;
void delay()
{
unsigned int times;
for(times=0;times<20000;times++);
}
main()
{
unsigned char r1,r5,r6,r7;
while(1)
{
P0=0;
P2=0;
t1=0;
delay();
t2=128;
t3=0;
while(t2>0)
{
for(r5=80;r5>0;r5--)
{
r7=0;
r1=16;
r6=0x20;
while(r1>0)
{
P0=tab[r6];
r6++;
P2=tab[r6];
r6++;
P1=r7;
delay();
P0=0;
P2=0;
r1--;
}
}
t3=t3+2;
t2--;
}
}
}
五、实验步骤
1、进入Keil C51软件的操作环境,编辑源程序并对源文件进行编译;
2、进入Proteus 系统,画出实验电路图;
3、对Proteus系统和 Keil C51系统进行联机设置;
4、在Keil C51系统中运行、调试程序,在Proteus系统中检查输出结果。
试验五10s的秒表
一、实验目的
1、了解八段译码器显示的基本原理;
2、掌握计数器的工作原理;
3、掌握10s双八段译码器显示的编程方法。
二、实验要求
在Keil C51系统中运行、调试程序,在Proteus 系统中,画出实验电路图。
三、实验代码:
#include
#define uchar unsigned char
#define uint unsigned int
sbit K1=P3^7;
uchar i,Second_Counts,Key_Flag_Idx;
bit Key_State;
uchar DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//延时
void DelayMS(uint ms)
{
uchar t;
while(ms--) for(t=0;t<120;t++);
}
//处理按键事件
void Key_Event_Handle()
{
if(Key_State==0)
{
Key_Flag_Idx=(Key_Flag_Idx+1)%3;
switch(Key_Flag_Idx)
{
case 1: EA=1;ET0=1;TR0=1;break;
case 2: EA=0;ET0=0;TR0=0;break;
case 0: P0=0x3f;P2=0x3f;i=0;Second_Counts=0;
}
}
}
//主程序
void main()
{
P0=0x3f; //显示00
P2=0x3f;
i=0;
Second_Counts=0;
Key_Flag_Idx=0; //按键次数(取值0,1,2,3)
Key_State=1; //按键状态
TMOD=0x01; //定时器0方式1
TH0=(65536-50000)/256; //定时器0:15ms
TL0=(65536-50000)%256;
while(1)
{
if(Key_State!=K1)
{
DelayMS(10);
Key_State=K1;
Key_Event_Handle();
}
}
}
//T0中断函数
void DSY_Refresh() interrupt 1
{
TH0=(65536-50000)/256; //恢复定时器0初值
TL0=(65536-50000)%256;
if(++i==2) //50ms*2=0.1s转换状态
{
i=0;
Second_Counts++;
P0=DSY_CODE[Second_Counts/10];
P2=DSY_CODE[Second_Counts%10];
if(Second_Counts==100) Second_Counts=0; //满100(10s)后显示00
}
}
/* 名称:10s的秒表
说明:首次按键计时开始,再次按键暂停,第三次按键清零。
*/
四、实验原理图
实验六用定时器设计的门铃
一、实验目的
1、了解定时器的基本原理;
2、掌握用定时器设计门铃编程方法。
二、实验要求
一、在Keil C51系统中运行、调试程序,在Proteus 系统中,画出实验电路图。编写程序在实现功能实验程序代码
三、程序代码:
/* 名称:用定时器设计的门铃
说明:按下按键时蜂鸣器发出叮咚的门铃声。
*/
#include
#define uchar unsigned char
#define uint unsigned int
sbit Key=P1^7;
sbit DoorBell=P3^0;
uint p=0;
//主程序
void main()
{
DoorBell=0;
TMOD=0x00; //T0方式0
TH0=(8192-700)/32; //700us定时
TL0=(8192-700)%32;
IE=0x82;
while(1)
{
if(Key==0) //按下按键启动定时器
{
TR0=1;
while(Key==0);
}
}
}
//T0中断控制点阵屏显示
void Timer0() interrupt 1
{
DoorBell=~DoorBell;
p++;
if(p<400) //若需要拖长声音,可以调整400和800
{
TH0=(8192-700)/32; //700us定时
TL0=(8192-700)%32;
}
else if(p<800)
{
TH0=(8192-1000)/32; //1ms定时
TL0=(8192-1000)%32;
}
else
{
TR0=0;
p=0;
}
}
四、实验原理图
实验七定时器控制交通指示灯
一、实验目的
1、了解定时器的基本原理;
2、了解交通灯的显示原理;
3、掌握如何设计用定时器设计交通灯编程方法。
二、实验要求
在Keil C51系统中运行、调试程序,在Proteus 系统中,画出实验电路图。
三、程序代码
/* 名称:定时器控制交通指示灯
说明:东西向绿灯亮5s后,黄灯闪烁,闪烁5次亮红灯,
红灯亮后,南北向由红灯变成绿灯,5s后南北向黄灯闪烁,
闪烁5次后亮红灯,东西向绿灯亮,如此往复。
*/
#include
#define uchar unsigned char
#define uint unsigned int
sbit RED_A=P0^0; //东西向指示灯
sbit YELLOW_A=P0^1;
sbit GREEN_A=P0^2;
sbit RED_B=P0^3; //南北向指示灯
sbit YELLOW_B=P0^4;
sbit GREEN_B=P0^5;
//延时倍数,闪烁次数,操作类型变量
uchar Time_Count=0,Flash_Count=0,Operation_Type=1;
//定时器0中断函数
void T0_INT() interrupt 1
{
TL0=-50000/256;
TH0=-50000%256;
switch(Operation_Type)
{
case 1: //东西向绿灯与南北向红灯亮5s
RED_A=0;YELLOW_A=0;GREEN_A=1;
RED_B=1;YELLOW_B=0;GREEN_B=0;
if(++Time_Count!=100) return; //5s(100*50ms)切换
Time_Count=0;
Operation_Type=2;
break;
case 2: //东西向黄灯开始闪烁,绿灯关闭
if(++Time_Count!=8) return;
Time_Count=0;
YELLOW_A=~YELLOW_A;GREEN_A=0;
if(++Flash_Count!=10) return; //闪烁
Flash_Count=0;
Operation_Type=3;
break;
case 3: //东西向红灯与南北向绿灯亮5s
RED_A=1;YELLOW_A=0;GREEN_A=0;
RED_B=0;YELLOW_B=0;GREEN_B=1;
if(++Time_Count!=100) return; //5s(100*50ms)切换
Time_Count=0;
Operation_Type=4;
break;
case 4: //南北向黄灯开始闪烁,绿灯关闭
if(++Time_Count!=8) return;
Time_Count=0;
YELLOW_B=~YELLOW_B;GREEN_A=0;
if(++Flash_Count!=10) return; //闪烁
Flash_Count=0;
Operation_Type=1;
break;
}
}
//主程序
void main()
{
TMOD=0x01; //T0方式1
IE=0x82;
TR0=1;
while(1);
}
四、实验原理图
实验八LCD1602字符液晶滚动演示程序
一、实验目的
1、了解液晶显示的基本原理;
2、字符液晶滚动显示系统的硬件连接方法;
3、液晶显示滚动字符的编程方法。
二、实验要求
在Keil C51系统中运行、调试程序,在Proteus 系统中,画出实验电路图。编写程序在液晶显示屏上显示滚动字符程序。
三、实验代码
//main.c
/* 名称:LCD1602字符液晶滚动演示程序
说明:K1~K3按钮分别实现液晶垂直或水平滚动显示及暂停与继续控制。
*/
#include
#include
#define uchar unsigned char
#define uint unsigned int
void Initialize_LCD();
void DelayMS(uint ms);
void ShowString(uchar,uchar,uchar *);
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
uchar code Prompt[]="Press K1 - K3 To Start Demo Prog";
//待滚动显示的信息段落,每行不超过80个字符,共6行
uchar const Line_Count=6;
uchar code Msg[][80]=
{
"Many CAD users dismiss schematic capture as a necessary evil in the ",
"process of creating PCB layout but we have always disputed this point ",
"of view. With PCB layout now offering automation of both component ",
"can often be the most time consuming element of the exercise.",
"And if you use circuit simulation to develop your ideas, ",
"you are going to spend even more time working on the schematic."
};
//显示缓冲(2行)
uchar Disp_Buffer[32];
//垂直滚动显示
void V_Scroll_Display()
{
uchar i,j,k=0;
uchar *p=Msg[0];
uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]);
//以下仅使用显示缓冲的前16字节空间
while(p { for(i=0;i<16&&p { //消除显示缓冲中待显示行首尾可能出现的空格 if((i==0||i==15)&&*p==' ') p++; if(*p!='\0') { Disp_Buffer[i]=*p++; } else { if(++k>Line_Count) break; p=Msg[k]; //p指向下一串的首地址 Disp_Buffer[i]=*p++; } } //不足16个字符时空格补充 for(j=i;j<16;j++) Disp_Buffer[j]=' '; //垂直滚动显示 while(F0) DelayMS(5); ShowString(0,0," "); DelayMS(150); while(F0) DelayMS(5); ShowString(0,1,Disp_Buffer); DelayMS(150); while(F0) DelayMS(5); ShowString(0,0,Disp_Buffer); ShowString(0,1," "); DelayMS(150); } //最后清屏 ShowString(0,0," "); ShowString(0,1," "); } //水平滚动显示 void H_Scroll_Display() { uchar i,j,k=0,L=0; uchar *p=Msg[0]; uchar *q=Msg[Line_Count]+strlen(Msg[Line_Count]); //将32个字符的显示缓冲前16个字符设为空格 for(i=0;i<16;i++) Disp_Buffer[i]=' '; while(p { //忽略缓冲中首尾可能出现的空格 if((i==16||i==31)&&*p==' ') p++; for(i=16;i<32&&p { if(*p!='\0') { Disp_Buffer[i]=*p++; } else { if(++k>Line_Count) break; p=Msg[k]; //p指向下一串的首地址 Disp_Buffer[i]=*p++; } } //不足32个字符时空格补充 for(j=i;j<32;j++) Disp_Buffer[j]=' '; //水平滚动显示 for(i=0;i<=16;i++) { while(F0) DelayMS(5); ShowString(0,L,Disp_Buffer+i); while(F0) DelayMS(5); DelayMS(20); } L=(L==0)?1:0; //行号在0,1间交替 DelayMS(300); } //如果显示结束时停留在第0行,则清除第1行的内容 if(L==1) ShowString(0,1," "); } //外部中断0,由K3控制暂停与继续显示 void EX_INT0() interrupt 0 { F0=!F0; //暂停与继续显示控制标志位 } //主程序 void main() { uint Count=0; IE=0x81; //允许外部中断0 IT0=1; //下降沿触发 F0=0; //暂停与继续显示控制标志位 Initialize_LCD(); ShowString(0,0,Prompt); ShowString(0,1,Prompt+16); while(1) { if(K1==0) { V_Scroll_Display(); DelayMS(300); } else if(K2==0) { H_Scroll_Display(); DelayMS(300); } } } //LCD1602.c /* 名称:液晶控制与显示程序 说明:本程序是通用的1602液晶控制程序。 */ #include #include #define uchar unsigned char #define uint unsigned int sbit RS=P2^0; sbit RW=P2^1; sbit EN=P2^2; //延时 void DelayMS(uint ms) { uchar i; while(ms--) for(i=0;i<120;i++); } //忙检查 uchar Busy_Check() { uchar LCD_Status; RS=0; //寄存器选择 RW=1; //读状态寄存器 EN=1; //开始读 DelayMS(1); LCD_Status=P0; EN=0; return LCD_Status; } //写LCD命令 void Write_LCD_Command(uchar cmd) { while((Busy_Check()&0x80)==0x80); //忙等待 RS=0; //选择命令寄存器 RW=0; //写 EN=0; P0=cmd;EN=1;DelayMS(1);EN=0; } //发送数据 void Write_LCD_Data(uchar dat) { while((Busy_Check()&0x80)==0x80); //忙等待 RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0; } //LCD初始化 void Initialize_LCD() { Write_LCD_Command(0x38);DelayMS(1); Write_LCD_Command(0x01);DelayMS(1); //清屏 Write_LCD_Command(0x06);DelayMS(1); //字符进入模式:屏幕不动,字符后移 Write_LCD_Command(0x0c);DelayMS(1); //显示开,光标关 } //显示字符串 void ShowString(uchar x,uchar y,uchar *str) { uchar i=0; if(y==0) Write_LCD_Command(0x80|x); //设置显示起始位置 if(y==1) Write_LCD_Command(0xc0|x); for(i=0;i<16;i++) //输出字符串 { Write_LCD_Data(str[i]); } } 四、实验原理图