只控制一位数码管没啥意思,如果只是研究一下倒是可以的
给你一份我自己写的,利用四位数码管显示模拟时钟的程序吧,供你研究
另外,再给你一个一位数码管的,是你要求的那种
下面这个是 四位数码管的,最下边的是一位数码管的,端口不一样的话,自己改下
//
#include<reg51h>
sbit p20=P3^7; sbit p21=P3^6; sbit led=P2^7;//按键及LED端口定义
sbit Axs=P1^3; sbit Bxs=P1^2; sbit Cxs=P1^1; sbit Dxs=P1^0;//数码管位选端口
char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管显示编码
unsigned int h,m,s,t,n;
//
void YS(char hs)//延时函数
{char hk;for(;hs>0;hs--){for(hk=200;hk>0;hk--);}}
//
void XS(int xh,int xm) //显示子函数
{
char d1,d2,d3,d4;
d1=(xh/1)%10; d2=(xh/10)%10;//分离小时
d3=(xm/1)%10; d4=(xm/10)%10;//分离分钟
P0=table[d1];Cxs=0;YS(10);Cxs=1;//小时个位
P0=table[d2];Dxs=0;YS(10);Dxs=1;//小时十位
P0=table[d3];Axs=0;YS(10);Axs=1;//分钟个位
P0=table[d4];Bxs=0;YS(10);Bxs=1;//分钟十位
P0=0x7f; P1=0xfd; YS(10); P1=0xff;//小数点
}
//
void main(void)
{
TH0=(65536-1000)/256; TL0=(65536-1000)%256;
TMOD=0x01; EA=1; ET0=1; TR0=1;//定时器初始化
while(1)//主循环
{
if(p20==0){YS(10);if(p20==0){h++;if(h>23){h=0;}}while(!p20){XS(h,m);}}
if(p21==0){YS(10);if(p21==0){m++;if(m>59){m=0;}}while(!p21){XS(h,m);}}
XS(h,m);//调用数码管显示函数
}
}
//
void int1() interrupt 1 //定时器中断
{
TH0=(65536-1000)/256; TL0=(65536-1000)%256; n++;t++;
if(t>500){t=0;led=~led;}//LED闪烁
if(n>1000){n=0;s++;}//如果达到一秒,秒加一
if(s>59){s=0;m++;}//如果达到一分,分加一
if(m>59){m=0;h++;}//如果达到一小时,小时加一
if(h>23){h=0;}//如果达到24小时,小时清零
}
//
//
#include<reg51h>
sbit Axs=P1^3;//数码管位选端口
char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管显示编码
unsigned int h,m,s,t,n;
//
void YS(char hs)//延时函数
{char hk;for(;hs>0;hs--){for(hk=200;hk>0;hk--);}}
//
void main(void)
{
TH0=(65536-1000)/256; TL0=(65536-1000)%256;
TMOD=0x01; EA=1; ET0=1; TR0=1;//定时器初始化
while(1)//主循环
{
P0=table[m];Axs=0;YS(10);Axs=1;//小时个位
}
}
//
void int1() interrupt 1 //定时器中断
{
TH0=(65536-1000)/256; TL0=(65536-1000)%256; n++;
if(n>1000){n=0;m++;}//如果达到一秒,秒加一
if(m>9){m=0;}//如果达到一小时,小时加一
}
//
1、二进制立即数后面要加B,也就是MOV P2,#111110B这样子。#6FH后面的H就是代表十六进制数。
2、题目描述的是“p0是输出数字,P1是选片”,你的代码实际是P1输出数据,P2片选
3、子函数的最后一行要写RET
4、没有消隐,实际运行时会出现拖影的现象,也就是左边的数,在它右边的那个数码上有轻微的显示。
修改后的代码:
ORG 0000HJMP MAIN
ORG 0100H
MAIN:
MOV P0,#00H
MOV P1,#111110b
MOV P0,#6FH
ACALL DL1ms
MOV P0,#00H
MOV P1,#111101b
MOV P0,#07H
ACALL DL1ms
MOV P0,#00H
MOV P1,#111011b
MOV P0,#3FH
ACALL DL1ms
MOV P0,#00H
MOV P1,#110111b
MOV P0,#6FH
ACALL DL1ms
MOV P0,#00H
MOV P1,#101111b
MOV P0,#5BH
ACALL DL1ms
MOV P0,#00H
MOV P1,#011111b
MOV P0,#66H
ACALL DL1ms
LJMP MAIN
DL1ms: MOV R7,#0fH
DL: MOV R6,#0FFH
DL6: DJNZ R6,DL6
DJNZ R7,DL
RET
END
仿真结果:
#include<reg52h>
#define uchar unsigned char//宏定义
#define uint unsigned int
uchar count;
uint disnum;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code tabledu[]={//段码表
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void display(uchar,uchar,uchar);
void delay(uchar);
void main()
{
EA=1;//开总中断
ET1=1;//开定时器T1中断
TMOD=0x10;//设置定时器T1为工作方式1
TH1=(65536-50000)/256;//定时50ms
TL1=(65536-50000)%256;
TR1=1;//启动定时器T1
while(1)
{
if(count==20)//定时1s
{
count=0;
if(disnum==1000)
disnum=0;
disnum++;//disnum值自加1
}
display(disnum/100,disnum%100/10,disnum%100%10);//显示disnum的值,从0显示到1000,时间间隔为1s
}
}
void tim1() interrupt 3 using 3
{
TH1=(65536-50000)/256;//重置定时参数
TL1=(65536-50000)%256;
count++;
}
void display(uchar bai,uchar shi,uchar ge)//显示子程序
{P0=tabledu[bai];//显示百位
dula=1;
dula=0;
P0=0xfe;
wela=1;
wela=0;
delay(1);
P0=tabledu[shi];//显示十位
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(1);
P0=tabledu[ge];//显示个位
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(1);
}
void delay(uchar x)//延时子程序
{
uchar a,b;
for(a=x;a>0;a--)
for(b=255;b>0;b--);
}
#include <reg51h>
unsigned char code Select[]={0x01,0x02};
unsigned char code Led_Codes[]=
{
0xc0,0xf9,0xa4,0xb0,0x99, //0-4
0x92,0x82,0xf8,0x80,0x90, //5-9
0x88,0x83,0xc6,0xa1,0x86, //A,b,C,d,E
0x8e,0xff,0x0c,0x89,0x7f,0xbf //F,空格,P,H,,-
};
void main()
{
char i=0;
long int j;
while(1)
{
P2=0;
P1=Led_Codes[i];
P2=Select[i];
for(j=3000;j>0;j--);
i++;
if(i>1)i=0;
}
连线方法:P1为段选,由P10到P17分别通过保护电阻连接到阴极数码管的a-g、dp,P2为位选,连接1、2。单片机另接晶振、电源即可。显示字符和延时时间可根据需要改变
/
1位数码管显示
/
#include "REG52H"
sbit SHUG_01 = P2^0; //数码管1位
#define LED_DATA P1 //P1数据端口
unsigned char value_temp = 0;unsigned char value_Outk = 0;
unsigned char code value_tab0[]=
{
0xc0,
0xf9,
0xa4,
0xb0,
0x99,
0x92,
0x82,
0xf8,
0x80,
0x90
}; //共阳极0-9段码
/
数码管显示子函数
/
void Disp_layledketCmd(void)
{
SHUG_01 = 1;
LED_DATA = value_tab0[value_Outk]; /数码管显示0-9/
}
/
定时器初始化定时50ms
/
void Tero_Init(void)
{
TMOD = 0x01;
TH0 = 0x4C;
TL0 = 0x00;
ET0 = 1;
TR0 = 1;
EA = 1;
}
/
函数主体
/
int main(void)
{
P1 = P2 = P3 = 0x00;
Tero_Init();
while(1)
{
Disp_layledketCmd();
}
}
/
定时器中断服务程序
/
void Tmero()interrupt 1
{
TH0 = 0x4C;
TL0 = 0x00;
value_temp++;
if(value_temp == 10) //定时500ms {
value_temp = 0;
value_Outk++;
if(value_Outk == 10)
{
value_Outk = 0;
}
}
}
如果共阴的已验证过,
比较稳妥的方法是,赋值前的位码和段码值都加上 ~ ,按位取反。
P0 = 0; P2 =~0xf7; P0 = ~table[ch]; delay(2);//通道号码
P0 = 0; P2 =~0xfb; P0 =~table[num / 100] + 128; delay(2);//百位加上小数点
P0 = 0; P2 =~0xfd; P0 = ~table[num % 100 / 10]; delay(2);//十位
P0 = 0; P2 = ~0xfe; P0 = ~table[num % 10]; delay(2);//个位
注意:如果你的P2另外4个引脚不能赋值0(例如用于输入),那上述代码就还要处理。
#include<reg51h> // 包含51单片机寄存器定义的头文件
/
函数功能:延时函数,延时一段时间
/
void delay(void)
{
unsigned char i,j;
for(i=0;i<255;i++)
for(j=0;j<255;j++)
;
}
/
函数功能:主函数
/
void main(void)
{
unsigned char i;
unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//数码管显示0~9的段码表,程序运行中当数组值不发生变化时,
//前面加关键字code ,可以大大节约单片机的存储空间
P2=0x7f; //P27引脚输出低电平,数码显示器第7位接通电源工作
while(1) //无限循环
{
for(i=0;i<10;i++)
{
P0=Tab[i]; //让P0口输出数字的段码92H
delay(); //调用延时函数
}
}
}
以上就是关于用单片机控制一个8段数码管,其循环显示数字0到9,每位数字显示时间为一秒,定时功能用单片机中断显示全部的内容,包括:用单片机控制一个8段数码管,其循环显示数字0到9,每位数字显示时间为一秒,定时功能用单片机中断显示、用8段数码管共阴动态输出970924,程序如下,p0是输出数字,P1是选片,为什么不行啊,求大佬、请帮忙,这是运用51单片机实现4位8段LED数码管的动态数字显示的c语音程序,帮我详细注解一些关键性的句子等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)