单片机实验报告
时间:2021-10-01 来源:博通范文网 本文已影响 人
实 实 验 验 报 报 告
实验课程:
单片机原理及应用
班
级:
12 自动化 2 班
学
号:
姓
名:
教
师:
张
玲
成
绩:
实 验 日 期 :
年
月
日
实验名称:
实验 1-—计数显示器
一、实验目得: 学习 Proteus 软件得使用,掌握单片机原理图得绘图方法。
二、实验内容:
ﻩ1、绘制“计数显示器”电路原理图; 2、利用提供得hex 文件验证此电路得运行效果。
三、实验要求:
提交得实验报告中应包括:1、绘图方法简述,要求说明元件与电源得选取、摆放及属性编辑,总线与标签得画法等内容;2、电路原理图; 3、仿真运行效果展示,要求就仿真文件加载方法及 3~4幅运行截图进行简要说明;4、实验小结,说明遇到得主要问题或实验 1 体会等.参考电路原理图如下:
元件类别 电路符号 元件名称 Microprocessor ICs “U1" 80C51 Miscellaneous “X1”/12MHz CRYSTAL Capacitors “C1”~“C2"/1nF CAP Capacitors “C3”/22μF CAP—ELEC Resistors Packs “RP1"/7—100Ω RESPACK—7 Resistors “R1"/100Ω RES Optoelectronics “LED1”~“LED2” 7SEG--CAT-GRN Switches & Relays “BUT” BUTTON 1、、及 编程思路及 C51 源程序:
2 、电路原理图:
:
3、仿真运行效果展示:
4 、实验小结 :
熟悉Proteus 软件,了解软件得结构组成与功能;学习 ISIS 模块得使用方法, 学会设置图纸、选元件、线画总线、修改属性等基本操作;学会可执行文件 加载及程序仿法;理解Proteus在单片机开发中得作用,完成单片机电路原 理图得绘制. 实验名称:
实验 2——LED 指示灯循环控制
一、
实验目得 熟悉μVision3 编译软件、掌握 C51编程与调试方法。
二、
实验内容 1、按照教材 P243 得图 A、34,绘制实验二电路原理图; 2、编写 C51 程序,实现 8 个 LED 灯依次点亮得功能: P0、0→P0、1→ P0、2→P0、3→ ┅ →P0、7→P0、6→P0、5→ ┅ →P0、0 得顺序,无限循环,间隔约50ms; 3、观察仿真结果,完成实验报告。
三、
实验要求 1、采用两种加载并运行可执行文件得方法,即proteus独立运行与prote
us + Keil 联合运行,体会其中得差异与意义; 2、练习采用单步、断点以及监视窗等手段进行程序调试得方法; 3、观察仿真结果,完成实验报告:绘制得电路原理图、编程思路分析及 C51源程序、调试过程简述,仿真运行效果以及实验小结。
1 、电路原理图:
:
及 2、编程思路及 C51 源程序:
3 、仿真运行效果:
4 、实验小结 :
通过本次实验我熟悉 uVision3 编译软件了解软件得结构组成与功能学习 C51 语言得程序设计方法)学会在 uVision3中进行 C51 程序录入、编译、与 调试理解 Proteus 与 Keil 联合得仿真原理实现 LED 指示灯循环控制功能。
更好得将 C 语言与 C51 语言联系在了一起)学到得知识能准确得利用了出来。
实验名称:
实验3——指示灯与数码管得中断控制
一、
实 验目得 掌握外部中断得工作原理,学会中断程序设计.二、实验内容 1、按照教材帕图 A、53,绘制实验四电路原理图; 2、要求采用外部中断原理完成本次实验,其中按键 K1、K2 均设置为下降沿触发方式,自然优先级; 3、编写 C51 程序实现如下功能:开机后 D1灭灯,LED1黑屏,随后单击 K1→D1状态反转,单击 K2 →LED1 从 0 开始循环显示0~F 字符。
4、观察仿真结果,完成实验报告。
三、
实验要求 提交得实验报告中应包括:电路原理图,外部中断工作原理阐述(以 K1 为例说明中断响应过程),C51 源程序(含流程图与注释语句),运行效果(含运行截图
与说明),实验小结. 1 、电路原理图 :
2 、外部中断工作原理阐述:
持续按下 K1 则 D1 将“亮→灭→亮→灭→„→亮→灭如此循环,表明实现了 K1 对应于 D1 状态反转这个功能;持续按下持续按 K2 则数码显示管依次显 示 1-F,实现了 K2 对应于 0~F 间得数码管加一计数显示.
3、、及 编程思路及 C51 源 源 程序:
4 、仿真运行效果:
5 、实验小结:
通过实验对 Protues 有了更多得了解,同时了解到中断系统在实际中得更好 应用。经过编程操作起来更加熟练能很快得完成绘图,编程时也得心应手, 能熟练得运用软件找出自己所编程中得语法问题及其她问题,并以改正。
实验名称:
实验4—- 电子秒表显示器
一、实 实 验目得 掌握定时/计数器得中断法工作原理,熟悉 C51 编程与调试方法
二、实验要求:
1、实验电路原理图如教材 P260 A、65 图所示.程序开始时显示“00”;当1s 产生时,秒计数加1;秒计数到 59 后,自动从“00”开始。
2、采用12MHz晶振频率,T0 定时方式 1、50ms 定时中断法编程(1s 需要经过 20 软循环)(流程图与参考程序模版如下所示).//定时中断方式实现得电子秒表
15( )件文头ﻩ(定义无符号字符型变量 t—-中断次数计数器,并赋初值0 (定义无符号字符型变量 second—-秒计数器,并赋初值 0 (定义位于 ROM 区得无符号字符型数组table-—显示字模) timer0()
(中断函数关键词) { ﻩ( )0T 闭关ﻩ (初值重装载 0x3cb0)
( )1增器数计数次断中ﻩ {)02==t(fiﻩﻩ
ﻩ
// 秒1于当相,次 02断中若ﻩ
;0=tﻩﻩﻩﻩﻩﻩﻩﻩ //中断次数计数器清零 ﻩ
;++dnocesﻩﻩ ﻩ // 零清器数计秒ﻩ
} ( )零清,06 到达值器数计秒若ﻩﻩ(
)值示显得 dnoces 量变出输别分口 2P与0Pﻩ( )0T动启ﻩﻩ} main(){
ﻩ
;]01/dnoces[elbat=0Pﻩﻩ // 值示显出输别分口 2P 与 0Pﻩ
;]01%dnoces[elbat=2Pﻩ (定义T0 定时方式 1—-TMOD) 05( )0LT与0HT——载加0bc3x0值初出溢 smﻩ( )AE,0TE——化始初断中ﻩ (启动 T0)
(死循环)
3 3 、编程思路及C1 51 源程序: :
4 、仿真运行效果:
5、实验小结 :
本次实验进行得比较顺利,根据指导材料中提供得流程图完成了源程序得编 写,成功生成了、hex文件,经过仿真运行达到了预期得实验结果.通过本次得 实验,我更加深入得了解到单片机定时/计数功能实现得机理,通过与单片机中 断功能得结合,可以完成更多得预期功能。但就是进过讨论我也发现,程序还就是存 在很大得缺陷,想要实现更加准确实现计时功能还需综合利用各种知识完善程 序。
作者写这篇文章的目的达到了!
感情丰富。
实验一
一、实验题目:试编写一段程序,其功能为将21H单元的内容8位分别依次存放到从22H开始的8单元中。
二、keil代码:
org 0000h jmp start
org 0100h start: mov 21h,#8; mov A ,21h;取出21中的数 mov R0,#22h ;初始化 mov R1,#7h ;循环次数为7 loop:
RRC A;把A之中的最低位移到C
JC real;判断C里面是数是否为1,如果是1.则跳转到real mov @R0,#0h jmpkk; real: mov @R0,#1h;如果是1,则将1赋到R0单元里 kk: INC r0;依次判断A中的每一位
DJNZ R1,loop; jmp $;死循环 end
三、实验截图:
四、实验小结:
这是我们单片机的第一个实验,因为刚接触,所以会感觉很陌生,内心有一种畏惧感,看到题目的时候也是没有头绪,可以说完全是不知道到底题目是一个什么意思,更是不知道我们应该如何编写程序。不过后面通过老师的讲解,自己也去查看了一些有关的书籍,慢慢也理解了该如何去实现这种实验题目。 在认真琢磨之后,我开始学会像以前刚开始学习C语言一样慢慢绘制一个程序的流程图,理清思绪,然后根据流程图编写相应的代码。
下面是本题的实验流程图:
通过完成这个实验,我对单片机的程序有了很大的认识。实验中,也是深刻的理解到了一个单片机程序每一步的实现与运行。当然,也掌握了在keil中调试的方法。
实验二
一、实验题目:若0-5号键的键值分别是:EEH、DEH、BEH、7EH、EDH、DDH。设键值存放在内部RAM 20H单元中,编程实现根据2OH中的键值分别使程序转移到PR0-PR4程序段。要求当以上程序段的功能完成后,都采用RET指令,指定返回到程序的初始入口START标号处。 要求:PR0 :教材75页习题。
PR1 :同上习题9题 PR2:同上习题10 其余入口,只需完成空操作就返回。
二、keil代码:
org 0000 ljmp start org 0100 TAB: DB 0EEH,0DEH,0BEH,7EH,0EDH,0DDH start: movdptr ,#start pushdpl pushdph
mov A,#0EEH MOV 20H,A
MOV DPTR ,#TAB
MOV A,#0 NEXT: PUSH ACC;先保存A寄存器中的值
MOVC A,@A+DPTR
;A是键码表的编码
;置键码表首址
;表的起始位置的偏移量为零 CJNE A,20H,NEXT1 POP ACC RL A
;将20H值和键码表的值比较
;如相等,序号乘以2,得到分支表内偏移量2n (8位变16位)
MOV DPTR,#APJ
JMP @A+DPTR PRn指令
NEXT1: POP ACC
INC A CJNE A,#6,NEXT;表示如果==6了,说明编码查完了也没有相等的,程序直接结束
SJMP $
APJ: AJMP PR0 AJMP PR1 AJMP PR2 AJMP PR3 AJMP PR4
;不相等,则比较下一个
;置分支表首址
;执行表JPT+2H中的AJMP
PR0:
MOV R7,#5H MOV 3DH,#00H MOV 3EH,#20H MOV 4EH,#88H MOV 5EH,#98H MOV A,#0 MOV R4,A MOV R5,A MOV R6,A
;正数个数
;负数个数
;零的个数
MOV R0,#40H MOV R1,#50H MOV SP,#3FH LOOP: POP ACC JZ ZERO JB ACC.7,FS INC R4 MOV @R0,A INC R0 AJMP DJ FS: INC R5 MOV @R1,A INC R1 AJMP DJ ZERO: INC R6 DJ: DJNZ R7,LOOP RET
DATA1:DB 0EFH,3FH,3EH,07H PR1:
MOV R7,#03H;进行3次循环 MOV R0,#DATA1 MOV A,@R0
CPL A ;取反 ADD A,#01
;加1 MOV @R0,A AB1: INC R0 MOV A,@R0 CPL A ADDC A,#0 ;带进位 DJNZ R7,AB1 ;SJMP $
RET BUF1:DB 1111B,0101B,0010B,0100B,0101B,0010B,0001B,0000B,1001B,0000B,1010B,1011B,0000B,0011B,0010B,0001B BUF2:DB 0 BUF:DB 0 PR2:
;30h放平均值 40h放余数 MOV R0,#BUF1
MOV R7,#16 ;循环16次数 MOV B,#0 MOV A,@R0 MOV R2,A LOOP1: MOV A,R2 INC R0 ADD A,@R0 MOV R2,A MOV A,B ADDC A,#0 MOV B,A DJNZ R7,LOOP1
MOV R6,#04H MOV 30H,#BUF2 MOV 30H,A MOV 40H,#BUF MOV 40H,#0 NEX: CLR C MOV A,B RRC A MOV B,A MOV A,30H RRC A
MOV 30H,A MOV A,40H RRC A MOV 40H,A DJNZ R6,NEX SJMP $ RET PR5:
RET PR3:
RET PR4:
RET END
三、实验截图:
初始化:
结果:
四、实验小结:
本实验中,将键码排成表,将键码表中的值和20H单元中的内容进行比较;另外编制一张转移表,存放AJMP指令,利用JMP @A+DPTR执行表内的AJMP指令,从而实现分支转移。
“RL A”:因为每个AJMP指令占两个字节,将刚记下来的键码中的值(即:键码的序号)乘以2即为转移表的偏移地址,在利用JMP @A+DPTR执行表内的AJMP指令,从而实现分支转移。
“movdptr ,#start Pushdpl push dph”:指定每次主程序返回到start。在单片机中,每一个子程序的返回用RET指令,而RET指令的功能正好可以使得子程序从栈顶弹出断点到PC,从而返回到主程序
实验三
一、实验题目:使用C语言完成,实验一,实验二。
二、keil代码:
实验一:
#include #include void main() { char *p1=0x21; char *p2=0x22; int i=1;
*p1=0x8;
while(i
{
*p2=*p1&0x01;
*p1=*p1>>1; p2++; i++;
} } 实验二: #include void PR0(); void PR1(); void PR2(); void PR3(); void PR4(); void PR5();
int main() { int i;//键码表code[]的下表
int key=0; char code1[]={0xEE,0xDE,0xBE,0x7e,0xED,0xDD}; char *p0=0x20;
//指针变量*p0指向20H这个单元
*p0=0xDE;
//给20H单元赋初值(20H单元里存放键码表中任一值)
for(i=0;i
}
key=i; switch(key) if(*p0==code1[i]){break;}
} {
} return 0; case 0:PR0();break; case 1:PR1();break; case 2:PR2();break; case 3:PR3();break; case 4:break; case 5:break; default:break; void PR0() { char table1[16]={1,2,-6,7,8,9,0,-1,-2,-3,-4,-5,-6,1,4,6}; char data *p30 = 0x30; char data *p40 = 0x40; char data *p50 = 0x50; int i; int countR4=0; R4,R5,R6中
int countR5=0;
//分别将正数、负数和零的个数存入 int countR6=0; for(i=0;i
//依次将table1表里的16个数据存入30H单元开始的单元里。
{
} for(i=0;i
{
if(*p30>0) {
} else if(*p30
} else *p50=*p30; ++p50; ++countR5;
*p40=*p30; ++p40; ++countR4;
p30[i]=table1[i];
{ } ++countR6;
}
++p30; } }
void PR1() { char data1[]={0x10,0x11,0x12,0x13}; int i; int j; char Cy=PSW^7; data1[0]=(~data1[0])+0x1; //while(j
} } data1[i]=(~data1[i])+Cy; i++;
void PR2() { char buf1[]={0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x0A,0x0B,0x0C,0x0D,0x0E,0xF}; char buf2=0; charbuf=0; int sum=0; int i=1; while(i
{ sum=sum+buf1[i];
++i;
} buf2=sum/0x10; buf=sum%0x10; }
三、实验截图:
实验一:
实验二:
四、实验小结:
在本实验中,我们用C语言编写代码的时候,特别注意指针的使用。另外,在单片机中使用C语言,与我们之前写C语言的时候还是有一些不同的地方,尤其是在指针使用上面的不同。C语言是一种通用的程序设计语言,代码率高,数据类型丰富,且具有良好的程序结构;单片机的C语言采用C51编译器,由C51产生的目标代码短,运行速度快,所需内存空间小。
实验中,注意:
“for(i=0;i
{
p30[i]=table1[i]; }”:表示依次将table1表里的16个数据存入30H单元开始的单元里。实际上,在C中指针就相当于一个数组。
在本实验中,我可以根据之前的汇编程序实验,较为容易的根据每个子程序编子函数模块。由于之前有C语言的基础,所以能够比较好的完成本实验。
实验四
五、实验题目: 当K1键按下后,首先使蜂鸣器响一声,然后使LED1- LED8完成3种闪亮的花样(自己定义),每一种花样循环 3次,然后周而复始。
六、keil代码:
/*当K1键按下后,首先使蜂鸣器响一声,
然后使LED1- LED8完成3种闪亮的花样(自己定义),每一种花样循环 3次,然后周而复始。*/ #include sbit P2_0=P2^0;//接蜂鸣器 sbit P2_7=P2^7; sbit P1_0=P1^0; sbit P1_1=P1^1; sbit P1_2=P1^2; sbit P1_3=P1^3; sbit P1_4=P1^4; sbit P1_5=P1^5; sbit P1_6=P1^6; sbit P1_7=P1^7;
void DELAY(int time)//延时 { while(time--) {} }
void BUZ_ON() { if(P2_7==0)
{ P2_0=1; } else { P2_0=0; }
}
void F1(void) { int i; char data_group_mide[5]={0x00,0x18,0x24,0x42,0x81};//向两边延伸 for(i=0;i
P1=0x00;
} void F2(void) { int i; char data_group_left[8]={0xFF,0x7F,0x3F,0x0F,0x07,0x03,0x01,0x00};//向左延伸 for(i=0;i
P1=0x00;
} void F3(void) { int i; char date_group_right[8]={0x00,0x01,0x03,0x07,0x0f,0x3f,0x7f,0xff};//向右延伸 for(i=0;i
P1=0x00;
} void main() {
unsigned int i; //每种花样循环三次
P2_0=0;
P2_7=1;
BUZ_ON();
P1=0x00; while(P2_7==0)
{
for(i=0;i
{F1();}
for(i=0;i
{F2();}
for(i=0;i
{F3();}
}
}
三、protues电路图:
四、实验截图:
五、实验小结:
通过本次实验,我们熟悉了protues的编译环境,对以后的单片机学习有很大帮助。
实验五
一、实验题目: 程序启动后4位LED显示器滚动显示“-”,每按下1次K1键后,首先使蜂鸣器响一声。然后,依次使LED滚动显示CNT的计数值(0-9)。
二、Keil代码:
/*程序启动后4位LED显示器滚动显示“-”,每按下才1次K1键后,首先使蜂鸣器响一声。然后,依次使LED滚动显示CNT的计数值(0-9)。
1、按键K1采用中断来管理。(INT0采用边沿触发)
2、中断服务程序完成四个功能:
1)消除按键K1抖动。
2)CNT计数。
3)查表将计数值转换成LED显示器的段代码。
4)将段代码分别放入4个显示缓冲单元。*/ #include #define uchar unsigned char #define uint unsigned int sbit P2_7=P2^7; sbit P3_3=P3^3; uchar CORDING[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc0,0xf9,0xa4,}; //0,1,2,3,4....9,0,1,2的段码 intdelayms(uint t) {
uint n; while(--t) { n=200; while(--n); }; return 0; }
int main() { uint CNT=0;
P2_7=0;
P3_3=1; P1=0xF7; while(1)
{ if(P3_3==0)
{
uint i;
CNT++;
P2_7=1; delayms(100); for(i=1;i
//4位
{
P1=CORDING[CNT-1];
switch(i)
{
//点亮第1位
//点亮第2位
//点亮第3位
//点亮第4位
delayms(100);
}
case
case
case
case }
P2=0x00; 1:P2=0x01;break; 2:P2=0x02;break; 3:P2=0x04;break; 4:P2=0x08;break;
// 熄灭
if(CNT>10) {
CNT=CNT-10; }
}
三、protues电路图:
P2_7=0; } return 0; }
四、实验截图:
五、实验总结:
通过本次实验,我们熟悉了CNT计数,学会了如何使LED灯上显示0-9数字。
实验六
一、实验题目:
两个数码管,K1,K2两个按键,完成K1启动计数,K2暂停计数,每一秒钟数码管增加1,60秒钟后,数码管回归0,重新计数。
二、keil代码:
/*两个数码管,K1,K2两个按键,完成K1启动计数,K2暂停计数,每一秒钟数码管增加1,60秒钟后,数码管回归0,
重新计数。按键K1,K2采用中断来管理。(INT0采用边沿触发)*/ #define uchar unsigned char #define uint unsigned int #include uchar CNT=0; uchar
m=0; sbit P3_7=P3^7; sbit P3_2=P3^2; sbit P0_0=P0^0; uchar CORDING[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0,1,2,3,4....9的段码 void Delay(uint a) {
while(--a){};
} voidintproc() interrupt 0 {
TR0=0; }
void Time0() interrupt 1 {
m++;
//中断一次,m加1
if(m==20) {
m=0;
//中断次数清零 CNT++; //秒加1 if(CNT==60) { CNT=0;}
P1=CORDING[CNT/10];//显示十位 Delay(10);
P2=CORDING[CNT%10];//显示个位 Delay(10);
} } voidinit() {
TMOD=0x01;
//使用定时器T0 使用方式1 TH0 = 0x3c;
TL0 = 0xb0;
ET0=1; TR0=1; EX0=1; IT0=1; EA=1; }
void main() {
P1=0x3f;
P2=0x3f;
P3_7=1; while(1)
{ if(P3_7==0) //50ms中断一次 //控制是否开启
{ init();
} }
三、protues电路图:
}
四、实验截图:
五、实验总结:
本次实验,我们用到了中断,按键K1,K2采用中断来管理。(INT0采用边沿触发),通过本次实验加强了中断的学习,更加有利于单片机的学习。
实验七
一、实验题目:晶振12MHz,波特率1200,程序启动后单片机主动发出Hello Server,PC使用串口助手应答单片机,单片机收到数据后,不做任何修改返回PC。
二、keil代码: #include #define uchar unsigned char #define uint unsigned int
uchar code table[]="HELLO SERVER!"; uint flag = 0; uchara,b; voidinit() {
}
voidSendByte(ucharch) { SBUF = ch; TMOD = 0x20; TH1 = 0xFD; TL1 = 0XFD; SCON = 0X50; TR1 = 1; EA = 1; ES = 1;
} while(!TI); TI = 0; voidSendString(uchar code *str) {
}
void main() {
init();
SendString("HELLO SERVER!"); while(1) {
if(flag == 1) {
ES = 0; SBUF = a; while(!TI); TI = 0; while(*str) SendByte(*str++);
}
} ES = 1; flag = 0;
}
voidser() interrupt 4 {
}
if(RI == 1) {
} RI = 0; a = SBUF; flag = 1;
三、protues电路图:
四、实验截图:
五
六、实验总结:
本次实验,我们利用了中断来实现,通过本次实验我们对中断有了更加深刻的了解,让我们在以后的为以后的学习之中打下了一定的基础。