10. 00-99 计数器
1. 实验任务
利用 AT89S51 单片机来制作一个手动计数器,在 AT89S51 单片机的 P3.7 管脚接
一个轻触开关,作为手动计数的按钮,用单片机的 P2.0-P2.7 接一个共阴数码
管,作为 00-99 计数的个位数显示,用单片机的 P0.0-P0.7 接一个共阴数码管,
作为 00-99 计数的十位数显示;硬件电路图如图 19 所示。
2. 电路原理图
3. 系统板上硬件连线
图 4.10.1
(1. 把“单片机系统”区域中的 P0.0/AD0-P0.7/AD7 端口用 8 芯排线连接到
“四路静态数码显示模块”区域中的任一个 a-h 端口上;要求:P0.0/AD0
对应着 a,P0.1/AD1 对应着 b,……,P0.7/AD7 对应着 h。
(2. 把“单片机系统”区域中的 P2.0/A8-P2.7/A15 端口用 8 芯排线连接到
“四路静态数码显示模块”区域中的任一个数码管的 a-h 端口上;
(3. 把“单片机系统”区域中的 P3.7/RD 端口用导线连接到“独立式键盘”区
域中的 SP1 端口上;
4. 程序设计内容
(1. 单片机对按键的识别的过程处理
(2. 单片机对正确识别的按键进行计数,计数满时,又从零开始计数;
(3. 单片机对计的数值要进行数码显示,计得的数是十进数,含有十位和个位,
我们要把十位和个位拆开分别送出这样的十位和个位数值到对应的数码
管上显示。如何拆开十位和个位我们可以把所计得的数值对 10 求余,即
可得个位数字,对 10 整除,即可得到十位数字了。
(4. 通过查表方式,分别显示出个位和十位数字。
5. 程序框图
图 4.10.2
自己第一遍搞错的:
#include
sbit K=P3^3;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
while(1)
{
P1=0xf0;
delay10ms();
P1=0xff;
if(K==0)
{
P1=0xfe;
delay10ms();
P1=0xff;
delay10ms();
if(K==0)
{
P1=0xfc;
delay10ms();
P1=0xff;
delay10ms();
if(K==0)
{
P1=0xfb;
delay10ms();
P1=0xff;
delay10ms();
if(K==0)
{
P1=0xf7;
delay10ms();
P1=0xff;
}
}
delay10ms();
}
}
}
}
参考程序:
#include
unsigned char ID;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void delay02s(void)
{
unsigned char i;
for(i=20;i>0;i--)
{
delay10ms();
}
}
void main(void)
{
while(1)
{
if(P3_3==0)
{
delay10ms();
if(P3_3==0)
{
ID++;
if(ID==4)
{
ID=0;
}
while(P3_3==0);
}
}
switch(ID)
{
case 0:
P1_0=~P1_0;
delay02s();
break;
case 1:
P1_1=~P1_1;
delay02s();
break;
case 2:
P1_2=~P1_2;
delay02s();
break;
case 3:
P1_3=~P1_3;
delay02s();
break;
}
}
}
修改的程序:
#include
unsigned char const dofly[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(unsigned int cnt)
{
while(--cnt);
}
int num=0;
main()
{
EA=1;
EX0=1;
IT0=1;
while(1)
{
//全局中断开
//外部中断 0 开
//电平触发
P2=1;
delay(50);
P0=dofly[num%10];
P2=2;
delay(50);
P0=dofly[num/10];
//在此添加其他程序
}
}
void ISR_Key(void) interrupt 0 using 1
{
num++;
if(num==100)
num=0;
}
源程序:
6. 汇编源程序
Count EQU 30H
SP1 BIT P3.7
ORG 0
START: MOV Count,#00H
NEXT: MOV A,Count
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
WT: JNB SP1,WT
WAIT: JB SP1,WAIT
LCALL DELY10MS
JB SP1,WAIT
INC Count
MOV A,Count
CJNE A,#100,NEXT
LJMP START
DELY10MS: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
7. C 语言源程序
#include
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Count;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
Count=0;
P0=table[Count/10];
P2=table[Count%10];
while(1)
{
if(P3_7==0)
{
delay10ms();
if(P3_7==0)
{
Count++;
if(Count==100)
{
Count=0;
}
P0=table[Count/10];
P2=table[Count%10];
while(P3_7==0);
}
}
}
}