数码管连接电路如图1所示,P0口输出码型,P2口输出位选。锁存器74HC573起驱动作用,提供驱动电流供数码管发光。译码器74HC138将位选地址转换成位选信号,例如当前是第5个数码管显示,那么P2口输出位选地址05H,译码器输入CBA=110,输出位选信号Y7-Y0=11101111,其中Y5=0,第5个数码管选通并显示,其它数码管不显示。实验时将J6的左边两个引脚针(1和2)用跳冒连接,锁存器11脚接VCC,关闭锁存功能。
数码管显示方式为动态扫描方式,当P0口送第一个数0的码型到锁存器时,P2送位选地址01H,即Y0=0,只有第一个数码管亮,显示0,其他数码管不显示。当P0口送第二个数1的码型到锁存器时,P2送位选地址02H,即Y1=0,只有第二个数码管亮,显示1,其他数码管不显示。即每次只有一个数码管点亮,8个数码管是轮流被点亮的,轮流点亮的间隔时间很短(一般用延时程序延时几个毫秒),由于视觉的暂留现象,看到的却好象全都点亮着,这就是动态扫描。
数码管显示数字的码型由数码管的数据脚a~dp决定,图2为数码管的笔段分布图,由于是共阴极的,所以当a~dp为高电平时相应的笔段会亮,电路中P1.0~P1.7分别接数码管的a.b.c.d.e.f.g.dp,得到0~9这10个数字的码型如表1所示。
图2 数码管的笔段分布图
引脚 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1P0.0数字 码型
笔段 dp g f e d c b a
0 0 1 1 1 1 1 1 0 3FH
0 0 0 0 0 1 1 0 1 06H
0 1 0 1 1 0 1 1 2 5BH
0 1 0 0 1 1 1 1 3 4FH
0 1 1 0 0 1 1 0 4 66H
0 1 1 0 1 1 0 1 5 6DH
0 1 1 1 1 1 0 1 6 7DH
0 0 0 0 0 1 1 1 7 07H
0 1 1 1 1 1 1 1 8 7FH
0 1 1 0 1 1 1 1 9 6FH
1 0 0 0 0 0 0 0 小数点80H
只要把上面的相关数,改成学好就可以了。
AJMP MAIN
ORG 30H
MAIN: MOV 20H,#2 ;把你的学号的10位送到相应单元
MOV 21H,#8
MOV 22H,#3
MOV 23H,#0
MOV 24H,#8
MOV 25H,#5
MOV 26H,#0
MOV 27H,#4
MOV 28H,#0
MOV 29H,#7
LCALL DISP ;显示子程序
AJMP MAIN
DISP: MOV A,20H ;送最高位到A
ACALL SEG7 ;取码指针子程序
MOV P0,A ;段码送P0口
CLR P2.0 ;位选
ACALL DLY ;延时1MS,即显示1MS
SETB P2.0 ;关显示。 动态显示的方法就是 :取优码,送段码,位选,延时1MS,关显示.
MOV A,21H ;下一位
ACALL SEG7
MOV P0,A
CLR P2.1
ACALL DLY
SETB P2.1
MOV A,22H
ACALL SEG7
MOV P0,A
CLR P2.2
ACALL DLY
SETB P2.2
MOV A,23H
ACALL SEG7
MOV P0,A
CLR P2.3
ACALL DLY
SETB P2.3
MOV A,24H
ACALL SEG7
MOV P0,A
CLR P2.4
ACALL DLY
SETB P2.4
MOV A,25H
ACALL SEG7
MOV P0,A
CLR P2.5
ACALL DLY
SETB P2.5
MOV A,26H
ACALL SEG7
MOV P0,A
CLR P2.6
ACALL DLY
SETB P2.6
MOV A,27H
ACALL SEG7
MOV P0,A
CLR P2.7
ACALL DLY
SETB P2.7
MOV A,28H
ACALL SEG7
MOV P0,A
CLR P3.0
ACALL DLY
SETB P3.0
MOV A,29H
ACALL SEG7
MOV P0,A
CLR P3.1
ACALL DLY
SETB P3.1
RET
DLY: MOV R7,#10 ;延时1MS子程序。12M晶振,粗略算法:2X R7 X R6
D1: MOV R6,#50
DJNZ R6,$
DJNZ R7,D1
RET
SEG7: INC A
MOVC A,@A+PC
RET
DB 03FH;0 共阴管段码
DB 006H;1
DB 05BH;2
DB 04FH;3
DB 066H;4
DB 06DH;5
DB 07DH;6
DB 007H;7
DB 07FH;8
DB 06FH;9
数码管显示方式为动态扫描方式,当P0口送第一个数0的码型到锁存器时,P2送位选地址01H,即Y0=0,只有第一个数码管亮,显示0,其他数码管不显示。当P0口送u全都点亮着,这就是动态扫描。
#include <intrins.h>
#include "absacc.h"
void time(unsigned int ucMs); /*延时单位: ms*/
void display(void); /*显示0, 1,..,7*/
/*********************************************************/
void main (void)
{
while(1)
{
display();
}
}
void display(void) /*显示0, 1, ,7*/
{
unsigned char code LEDValue[8]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};
unsigned char i;
unsigned char position=0x01;
for (i=0; i<8; i++)
{
XBYTE[0x0FFF8] = LEDValue[i]; /*显示内容*/
XBYTE[0x0FFF9] = position; /*位译码输入*/
position = position<<1;
time(1); /*状态维持*/
}
}
/*********************************************************
* 函数说明:延时5us,晶振改变时只用改变这一个函数!
1、对于11.0592M晶振而言,需要2个_nop_();
2、对于22.1184M晶振而言,需要4个_nop_();
*********************************************************/
void delay_5us(void) //延时5us,晶振改变时只用改变这一个函数!
{
_nop_();
_nop_();
}
/************ delay_50us ***************/
void delay_50us(void) //延时50us
{
unsigned char i;
for(i=0;i<4;i++)
{
delay_5us();
}
}
/******** 延时100us ******************/
void delay_100us(void) //延时100us
{
delay_50us();
delay_50us();
}
/*********** 延时单位:ms *******************/
void time(unsigned int ucMs)//延时单位:ms
{
unsigned char j;
while(ucMs>0){
for(j=0;j<10;j++) delay_100us();
ucMs--;
}
}