实验目的: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 0000hstart: 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,#2temp1: mov r1,#0ffhtemp2: mov r2,#100temp3: mov r3,#10 djnz r3,$ djnz r2,temp3 djnz r1,temp2 djnz r0,temp1 retend 查表法实现如下: org 0000hstart: mov p2,#01h mov r7,#0ffh mov a,#0ffh mov dptr,#table mov a,#0loop: 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,#2temp1: mov r1,#0ffhtemp2: mov r2,#10temp3: 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时的处理会麻烦一些,这并不是本实验所关心的,故未做处理。 下载到板子上实测结果与上述仿真结果相符。

评论