项目名称: 数码管实验报告
姓名: 陈 姣
班级: 11电气(2)
学号: 11731204
指导老师: 赵海兰
1, 实验目的:
1, 巩固Keil软件的使用方法
2, 学习端口输入输出的高级应用
3, 掌握7段数码管的连接方式和动态显示法
4, 掌握查表程序和延时等子程序的设计
5, 学习关于数码管的知识,了解关于数码管的代码,更好的学习单片机。
2,实验流程:
项目1,《用数码管显示1~8》程序:
#include<reg52.h>
void delay(void)
{unsigned char i;
for(i=0;i<2000;i++);} //时间延长,
void main(void)
{
P0=0Xff;
P2=0xff;
while(1)
{
P2=0xfe;
P0=0xf9; delay();
P2=0xfd;
P0=0xa4; delay();
P2=0xfb;
P0=0xb0; delay();
P2=0xf7;
P0=0x99; delay();
P2=0xef;
P0=0x92; delay();
P2=0xdf;
P0=0x82; delay();
P2=0xbf;
P0=0xf8; delay();
P2=0x7f;
P0=0x80; delay();
P2=0xff;
}
}
项目2,《00~99计数》程序:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code tableP0[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90};//表示0~9
void delayms(uint m) //延时
{
uchar j;
while(m--)
{ for(j=0;j<120;j++)
{;}
}
}
void main()
{
uchar i,j;
P2=0XFF;
P0=0XFF;
while(1)
{ for(i=0;i<100;i++) //延时,先显示个位
{ for(j=0;j<100;j++) //在显示十位
{ P0=tablep0[i%10];//个位
P2=0x7f;
delayms(1);
P0=tablep0[i/10];//十位
P2=0xbf;
delayms(1); }
}}}
项目3,《用按钮来累计计数》程序:
#include<reg52.h>
unsigned code tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90};
sbit k5=P1^4;
void delay (void)
{unsigned int n;
for(n=0;n<20000;n++)
;}
void main (void)
{unsigned char i ;
i=0;
while(1)
{
if(k5==0)
{
delay();
if(k5==0)
i++ ;
if(i==10)
i=1 ;
while(!k5);
P2=0X7F;
P0=tab[i]; }
}
}
单片机最小系统:
图片
实验感悟与收获:
通过这次试验,我们深刻的了解到单片机的重要性,和学习单片机的乐趣。但是,同时也会遇到一些困难……
问题一:在进行程序编写时,经常编译不通过,存在语法问题。在c语言的学习上,无法活学活用。对待for语句,while语句,不熟练,不懂如何运用!导致程序混乱,编译不通过……
解决方法:
经过老师帮助和查找图书,经过反复调试,得出结果。
问题二:运行电路时,发现发光二极管只有7个亮。而且复位电路没有用。
解决的方法:检查电路,因为复位电路没用,所以我检查复位电路中的问题,最后发现在单片机最小系统中,没有将单片机的9脚接上,然后将9脚接上调换,重新运行。单片机正常运行。
问题三:重新运行后,经过大约1天时间,单片机最小系统又不亮了。
解决的方法:检查电路,发现是从排阻上引出的电源线,断路,后来又重新焊上。因为每次都要用电池,感觉不方便。又找了一个USB接口,引出来两根线接在板子上,插在电脑上,终于符合要求。
总结:
通过本次的实验,在前两个实验的基础上让我复习了知识点,也让我在次掌握了新的知识。在完成这次实验后,让我想到可以用多个按键控制多个数码管实现加减和暂停和开始。我觉得这次的课程实验让我知道,一次次的失败,并不会让我放弃去追求,相反它会引领着我去发现问题,从而解决问题,完成更深入的探索。每个人都想一次成功,殊不知一次成功会少了许多在问题中寻找解决方法,获得成功的喜悦!从这次失败失败成功中,也让我明白理论知识的重要性,并且与实际相结合,多动手,在实践中成长。所以我会很重视每一次的实验。我坚信:每次实验都会给我自身很大帮助。慢慢的积累点滴的知识,到最后就会多的。虽然,现在我还是对这个代码的编写不是很熟悉,但是经过一个学期的努力,我相信我会学的更好!
第二篇:数码管实验报告
单片机实验报告
一、实验名称
数码管动态扫描显示01234567(实验五)
二、实验目的
(1)掌握数码管显示数字的原理。
(2)通过不同的编程实现灵活运用数码管。
三、实验原理
数码管由7个发光二极管组成8字形构成的,加上小数点就是8个,分别把它命名为A,B,C,D,E,F,G,H。在共阳接法中,0(低电平)亮,1(高电平)灭。
原理图中把所有数码管的8个笔划段A-H同名端连在一起,而每一个显示器的公共机COM是各自独立受I\O线控制。CPU向字段输出口送出字型码时,所有显示器接收到的字型码相同。由8个PNP的三极管来控制这8位哪一位工作。在单片机里,首先显示一个数,然后关掉,然后在显示第二个数,又关掉,那么将看到连续的而数字显示,轮流点亮撒哦i案过程中,每位显示器的点亮时间是极为短暂的,由于人的视觉暂留和发光二级管的余光效应,是的给人的印象是一组稳定的显示数据,不会有闪烁感。
四、相关原理图
单片机实验报告
五、实验内容
数码管显示12345678
c程序:
#include <reg51.h>
#include <intrins.h>
unsigned char data dis_digit;
unsigned char code dis_code[11]={ 0x28, 0x7E, 0xA2, 0x62, 0x74, 0x61, 0x21, 0x7A, 0x20,
0x60,0xff};//0,1,2,3,4,5,6,7,8,9,关显示,数码管码表
unsigned char data dis_buf[8];// 显示缓冲区
单片机实验报告
unsigned char data dis_index;
char code SST516[3] _at_ 0x003b;
void main()
{
P0 = 0xff;
P2 = 0xff;
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x17;
IE = 0x82;
dis_buf[0] = dis_code[0x1];
dis_buf[1] = dis_code[0x2];
dis_buf[2] = dis_code[0x3];
dis_buf[3] = dis_code[0x4];
dis_buf[4] = dis_code[0x5];
dis_buf[5] = dis_code[0x6];
dis_buf[6] = dis_code[0x7];
dis_buf[7] = dis_code[0x8];
dis_digit = 0xfe;
dis_index = 0;
TR0 = 1;
while(1);}
void timer0() interrupt 1
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
// 选通P2.0口数码管
// dis_buf --- 显于缓冲区基地址
{
TH0 = 0xFC;
TL0 = 0x17;
P2 = 0xff; // 先关闭所有数码管
P0 = dis_buf[dis_index]; // 显示代码传送到P0口
P2 = dis_digit; //
dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管
dis_index++; //
dis_index &= 0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
}
单片机实验报告
汇编程序:
CODE_SEG SEGMENT CODE
DATA_SEG SEGMENT DATA
RSEG DATA_SEG
dis_digit: DS 1
dis_index: DS 1
dis_buf: DS 8
stack: DS 20
;===========================================================
CSEG AT 00000H ; Reset向量
LJMP MAIN
CSEG AT 0000BH ; 定时器0中断向量
LJMP TIMER0
;===========================================================
RSEG CODE_SEG
ORG 0080h
MAIN:
MOV SP,#(stack-1) ; 初始化堆栈指针
MOV P0,#0FFH ; 初始化I/O口
MOV P2,#0FFH
MOV TMOD,#01H ; 初始化timer0
MOV TH0,#0FCH
MOV TL0,#017H
MOV IE,#082H
MOV DPTR, #DIS_CODE ; 设定显示初值
MOV A,#1
MOVC A,@A+DPTR
MOV dis_buf,A
MOV A,#2
MOVC A,@A+DPTR
MOV dis_buf+01H,A
MOV A,#3
MOVC A,@A+DPTR
MOV dis_buf+02H,A
MOV A,#4
MOVC A,@A+DPTR
MOV dis_buf+03H,A
单片机实验报告
MOV A,#5
MOVC A,@A+DPTR
MOV dis_buf+04H,A
MOV A,#6
MOVC A,@A+DPTR
MOV dis_buf+05H,A
MOV A,#7
MOVC A,@A+DPTR
MOV dis_buf+06H,A
MOV A,#8
MOVC A,@A+DPTR
MOV dis_buf+07H,A
MOV dis_digit,#0FEH ; 初始从第一个数码管开始扫描
MOV dis_index,A
SETB TR0 ; 启动定时器0,开始动态扫描显示
MAIN_LP:
; 主程序循环,增加其它代码
SJMP MAIN_LP
;===========================================================
USING 0
TIMER0:
; 定时器0中断服程序, 用于数码管的动态扫描
; DIS_INDEX --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
; DIS_DIGIT --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
; 选通P2.0口数码管
; DIS_BUF --- 显于缓冲区基地址
PUSH ACC
PUSH PSW
PUSH AR0
MOV TH0,#0FCH
MOV TL0,#017H
MOV P2,#0FFH ; 先关闭所有数码管
MOV A,#DIS_BUF ; 获得显示缓冲区基地址
ADD A,DIS_INDEX ; 获得偏移量
MOV R0,A ; R0 = 基地址 + 偏移量
MOV A,@R0 ; 获得显示代码
MOV P0,A ; 显示代码传送到P0口
MOV P2,DIS_DIGIT ;
MOV A,DIS_DIGIT ; 位选通值左移, 下次中断时选通下一位数码管
RL A
单片机实验报告
MOV DIS_DIGIT,A
INC DIS_INDEX ; DIS_INDEX加1, 下次中断时显示下一位
ANL DIS_INDEX,#0x07 ; 当DIS_INDEX等于8(0000 1000)时, 清0
POP AR0
POP PSW
POP ACC
RETI
; END OF timer0
;===========================================================
RSEG CODE_SEG
DIS_CODE:
DB 28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h,30h,25h,0a9h,26h,0a1h,0b1h;数码管代码
END
六、实验运行