实验目的:1位数码管从0到9循环计数,间隔1s。
实验板: FB51A(查看)。
该实验用到实验板的资源电路图如下:
其中P0口是段码,低电平有效。P2口是位码,高电平有效。P2.0口控制第1个数码管,一直到P2.7口控制第8个。该板的段码表如下:
┌─────┬────────────────┬────┐
ㄧ ㄧ P0.*: 7 6 5 4 3 2 1 0 ㄧ P0口值 ㄧ
ㄧ 十进制数 ㄧ 段 : d dp e c g b f a ㄧ 即段码 ㄧ
├─────┼────────────────┼────┤
ㄧ 0 ㄧ 0 1 0 0 1 0 0 0 ㄧ 48H ㄧ
ㄧ 1 ㄧ 1 1 1 0 1 0 1 1 ㄧ ebH ㄧ
ㄧ 2 ㄧ 0 1 0 1 0 0 1 0 ㄧ 52H ㄧ
ㄧ 3 ㄧ 0 1 1 0 0 0 1 0 ㄧ 62H ㄧ
ㄧ 4 ㄧ 1 1 1 0 0 0 0 1 ㄧ e1H ㄧ
ㄧ 5 ㄧ 0 1 1 0 0 1 0 0 ㄧ 64H ㄧ
ㄧ 6 ㄧ 0 1 0 0 0 1 0 0 ㄧ 44H ㄧ
ㄧ 7 ㄧ 1 1 1 0 1 0 1 0 ㄧ eaH ㄧ
ㄧ 8 ㄧ 0 1 0 0 0 0 0 0 ㄧ 40H ㄧ
ㄧ 9 ㄧ 0 1 1 0 0 0 0 0 ㄧ 60H ㄧ
├─────┼────────────────┼────┤
ㄧ 0. ㄧ 0 0 0 0 1 0 0 0 ㄧ 08H ㄧ
ㄧ 1. ㄧ 1 0 1 0 1 0 1 1 ㄧ abH ㄧ
ㄧ 2. ㄧ 0 0 0 1 0 0 1 0 ㄧ 12H ㄧ
ㄧ 3. ㄧ 0 0 1 0 0 0 1 0 ㄧ 22H ㄧ
ㄧ 4. ㄧ 1 0 1 0 0 0 0 1 ㄧ a1H ㄧ
ㄧ 5. ㄧ 0 0 1 0 0 1 0 0 ㄧ 24H ㄧ
ㄧ 6. ㄧ 0 0 0 0 0 1 0 0 ㄧ 04H ㄧ
ㄧ 7. ㄧ 1 0 1 0 1 0 1 0 ㄧ aaH ㄧ
ㄧ 8. ㄧ 0 0 0 0 0 0 0 0 ㄧ 00H ㄧ
ㄧ 9. ㄧ 0 0 1 0 0 0 0 0 ㄧ 20H ㄧ
└─────┴────────────────┴────┘
首先采用一个比较笨的办法,即先送段码0到P0口,延时1s后,再送段码1到P0口,延时1s …… 如此循环。
汇编实现:
org 0000h
start: mov p2,#01h ; 位码
loop: mov p0,#48h ; 段码
lcall delay_1s
mov p0,#0ebh
lcall delay_1s
mov p0,#52h
lcall delay_1s
mov p0,#62h
lcall delay_1s
mov p0,#0e1h
lcall delay_1s
mov p0,#64h
lcall delay_1s
mov p0,#44h
lcall delay_1s
mov p0,#0eah
lcall delay_1s
mov p0,#40h
lcall delay_1s
mov p0,#60h
lcall delay_1s
ajmp loop
delay_1s: mov r0,#2
temp1: mov r1,#0ffh
temp2: mov r2,#100
temp3: mov r3,#10
djnz r3,$
djnz r2,temp3
djnz r1,temp2
djnz r0,temp1
ret
end
查表法实现如下:
org 0000h
start: mov p2,#01h
mov r7,#0ffh
mov a,#0ffh
mov dptr,#table
mov a,#0
loop: inc r7 ;计数
mov a,r7
movc a,@a+dptr
mov p0,a
lcall delay_1s
cjne a,#60h,loop
ajmp start
table: db 48h,0ebh,52h,62h,0e1h,64h,44h,0eah,40h,60h
delay_1s: mov r0,#2
temp1: mov r1,#0ffh
temp2: mov r2,#10
temp3: mov r3,#100
djnz r3,$
djnz r2,temp3
djnz r1,temp2
djnz r0,temp1
ret
end
C51实现(软延时):
#include <reg51.h>
void delay_1s(void); // 延时子程序
unsigned char code dis_code[11]={0x48,0xeb,0x52,0x62,0xe1, // 0,1,2,3, 4
0x64,0x44,0xea,0x00,0x60, 0xff}; // 5,6,7,8,9, off
unsigned char data dis; // 显示索引
void main()
{
P0 = 0xff; // 关闭所有数码管
P2 = 0x00;
P2 = 0x01; // 选通P2.0
dis = 0; // 当前偏移量为0
while(1)
{
P0 = dis_code[dis]; // 段码送P0口
delay_1s(); // 延时
dis++; // 下一个段码
if (dis == 10)
dis = 0;
}
}
void delay_1s(void)
{
unsigned char h,i,j,k;
for(h=5;h>0;h--)
for(i=4;i>0;i--)
for(j=116;j>0;j--)
for(k=214;k>0;k--);
}
C51(中断延时)
#include <reg51.h>
unsigned char code dis_code[11] = {0x48, 0xeb, 0x52, 0x62, 0xe1, // 0,1,2,3,4
0x64, 0x44, 0xea, 0x40, 0x60, 0xff}; //5,6,7,8,9,off
unsigned char data index; // 显示索引
unsigned char data count; // 软件计数器
void main()
{
P0 = 0xff; // 关闭全部数码管
P2 = 0x00;
TMOD = 0x01; // 00000001B,定时计数器0工作在方式1,为16位
TH0 = 0x3C;
TL0 = 0xB0; // 预置初值3CB0H=15536D, 即一次中断为65536-15536=50ms (12M)
IE = 0x82; // 10000010B T0溢出中断允许
TR0 = 1; // 启动T0
index = 0;
count = 0;
while(1); // 循环等待中断
}
void timer0() interrupt 1 // 定时器中断服务程序
{
TH0 = 0x3C; // 发生中断重装初值
TL0 = 0xB0;
count++; // 软件计数器递增
if (count == 20) // 50ms×20 = 1s 时
{
P2 = 0x01;
P0 = dis_code[index];
index++; // 段码自加
if (index == 10) // 控制循环值
index = 0;
count = 0; // 计数器归0
}
}
★ 用此方法实现, 实测开始会有一个1s的延时,即第一个1s内无显示,原因是在第一个中断(实际上是第20个)之前未对显示处理。若在main函数中开始就显示0,则在第一次显示9之后要归0时的处理会麻烦一些,这并不是本实验所关心的,故未做处理。
下载到板子上实测结果与上述仿真结果相符。
评论