4位共阳数码管 显示数字,调节亮度,时钟调时,控制LED巧妙编程

wKioL1ZHO8rx7rb4AAGf6EiCpFM936.jpg

图纸是共阴的,共阳的原理和这个一样



wKiom1ZHPCXDqijFAAMK6-ojavM643.jpg

wKiom1ZHPCiwsxGyAAPRnQ4-Rv4722.jpg


/***************************************************
程序名:    4位共阳数码管驱动程序
编写时间:  2015年11月14日
硬件支持:  STC12C4052AD
接口说明:  点扫描  
数码管是

字段  管脚  MCU IO口
a 13脚  P1.0
b  9脚  P1.1
c  4脚  P1.2
d  2脚  P1.3
e  1脚  P1.4
f 12脚  P1.5
g  5脚  P1.6
dp 8脚  P1.7

1位 14脚  P3.0
2位 11脚  P3.1
3位 10脚  P3.2
4位  6脚  P3.3





/***************************************************/

#include <STC12C2052AD.H> //STC头文件
#define LI			9	 //设置LED显示的亮度(值域:1~9)
#define DELAY		10 	//设置每一个点显示的时间长度,40以内较合适,改为999可以看到数码管点亮步骤

sbit	LED1_H1	=P3 ^ 0; //设置LED点阵屏连接的I/O口
sbit	LED1_H2	=P3 ^ 1; //设置LED点阵屏连接的I/O口
sbit	LED1_H3	=P3 ^ 2; //设置LED点阵屏连接的I/O口
sbit	LED1_H4	=P3 ^ 3; //设置LED点阵屏连接的I/O口

sbit	LED1_L1	=P1 ^ 0; //设置LED点阵屏连接的I/O口
sbit	LED1_L2	=P1 ^ 1; //设置LED点阵屏连接的I/O口
sbit	LED1_L3	=P1 ^ 2; //设置LED点阵屏连接的I/O口
sbit	LED1_L4	=P1 ^ 3; //设置LED点阵屏连接的I/O口
sbit	LED1_L5	=P1 ^ 4; //设置LED点阵屏连接的I/O口
sbit	LED1_L6	=P1 ^ 5; //设置LED点阵屏连接的I/O口
sbit	LED1_L7	=P1 ^ 6; //设置LED点阵屏连接的I/O口
sbit	LED1_L8	=P1 ^ 7; //设置LED点阵屏连接的I/O口

#define P1M0SET		0x00 //设置I/O口工作方式//00000000(左到右,高到低位)
#define P1M1SET		0x00 //设置I/O口工作方式//00101000
#define P3M0SET		0x00 //设置I/O口工作方式//00000000
#define P3M1SET		0xff //设置I/O口工作方式//10010100

data unsigned char TIME_HH,TIME_MM,TIME_SS;//设置时、分、秒存放区
data unsigned char cou  = 0;               // 软计数器,对10ms时基信号累加到1s 
data unsigned char bn;                     //扫描映射全局变量
data unsigned char PWM;                 //显示亮度

unsigned char code disdata[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f //无小数点数码管段码表(0~9) 
};

void delay (unsigned int a){ // 用于点扫描的延时
	unsigned int i;
	while( a-- != 0){
		for(i = 0; i < DELAY; i++); 
	}   				   
}

void delay1ms (unsigned int a){ // 1ms延时程序(12MHz 10倍于51单片机速度时)
	unsigned int i;
	while( a-- != 0){
		for(i = 0; i < 600; i++); 
	}   				   
}

void dis_off (void){
	P1 = ~P1M1SET; //关所有显示
	P3 = ~P3M1SET;
	delay(10-PWM); 
}

void displayHH1 (unsigned char d){ //第1列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H1 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H1 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H1 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H1 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H1 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H1 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H1 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H1 = 1;LED1_L8 = 0;}delay(PWM);dis_off();
} 

void displayHH2 (unsigned char d){ //第2列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H2 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H2 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H2 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H2 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H2 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H2 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H2 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H2 = 1;LED1_L8 = 0;}delay(PWM);dis_off();

} 

void displayHH3 (unsigned char d){ //第3列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H3 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H3 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H3 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H3 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H3 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H3 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H3 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H3 = 1;LED1_L8 = 0;}delay(PWM);dis_off();

} 

void displayHH4 (unsigned char d){ //第4列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H4 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H4 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H4 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H4 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H4 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H4 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H4 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H4 = 1;LED1_L8 = 0;}delay(PWM);dis_off();
} 

void diplay_data (unsigned char l,unsigned char d){
		switch (l){//显示的列位置		
				case 1://			
					displayHH1(d); //将显示数据送入		
					break;//		
				case 2://			
					displayHH2(d); //将显示数据送入		
					break;//		
				case 3://			
					displayHH3(d); //将显示数据送入		
					break;//		
				case 4://			
					displayHH4(d); //将显示数据送入		
					break;//		
		}
}

void init (void){ //上电初始化
	P1M0 = P1M0SET;
	P1M1 = P1M1SET;
	P3M0 = P3M0SET;
	P3M1 = P3M1SET;
	dis_off(); 
	PWM = LI;
	TMOD = 0x11;         // 定时/计数器0,1工作于方式1   
	TH0 = 0x3c;          // 预置产生50ms时基信号   
	TL0 = 0xb0;   
	EA = 1;              // 开总中断   
	ET0 = 1;             // 定时/计数器0允许中断   
	TR0 = 1;             // 开定时/计数器0   
}

void main (void){ //主程序 
	init();
	while (1){
				diplay_data (1,disdata[TIME_MM/10]);
				diplay_data (2,disdata[TIME_MM%10]);
				diplay_data (3,disdata[TIME_SS/10]+0x80);
				diplay_data (4,disdata[TIME_SS%10]+0x80);

	}
}

void tiem0(void) interrupt 1{   // T/C0中断服务程序(产生50ms时基信号)   
    cou++;                      // 软计数器加1   
    if(cou > 19){                 // 计数值到100(1s)   
        cou = 0;               // 软计数器清零   
        TIME_SS++;                 // 秒计数器加1(进位10ms*100=1s)   
        if(TIME_SS > 59){          // 秒计数值到60   
           
            TIME_SS = 0;           // 秒计数器清零   
            TIME_MM++;             // 分计数器加1(进位60s=1m)  
            if(TIME_MM > 59){      // 分计数到60   
                TIME_MM = 0;       // 分计数器清零   
                TIME_HH++;         // 时计数器加1(进位60m=1h)   
                if(TIME_HH > 23){  // 时计数到23   
                    TIME_HH = 0;   // 时计数器清零
				}  
            }   
        }   
    }   
    TH0 = 0x3c;                // 重置定时常数   
    TL0 = 0xb0;   
}






【调节亮度,时钟调时】

wKioL1ZHR7ySibv7AASEeiOi3dw103.jpg

/*******************************************************
程序名:    4位共阳数码管驱动程序
接口说明:  点扫描方式 时钟调时   

STC12C2052AD 12M 
KEY 低电平触发
短按触发 亮度10级调节
长按触发 时钟调节
字段  管脚  MCU IO口
a 13脚  P1.0
b  9脚  P1.1
c  4脚  P1.2
d  2脚  P1.3
e  1脚  P1.4
f 12脚  P1.5
g  5脚  P1.6
dp 8脚  P1.7

1位 14脚  P3.0
2位 11脚  P3.1
3位 10脚  P3.2
4位  6脚  P3.3



/******************************************************/
#include <STC12C2052AD.H> //STC头文件

#define LI			9	 //设置LED显示的亮度(值域:1~9)
#define DELAY		12 	//设置每一个点显示的时间长度(1~20)

sbit	LED1_H1	=P3 ^ 0; //设置LED点阵屏连接的I/O口
sbit	LED1_H2	=P3 ^ 1; //设置LED点阵屏连接的I/O口
sbit	LED1_H3	=P3 ^ 2; //设置LED点阵屏连接的I/O口
sbit	LED1_H4	=P3 ^ 3; //设置LED点阵屏连接的I/O口

sbit	LED1_L1	=P1 ^ 0; //设置LED点阵屏连接的I/O口
sbit	LED1_L2	=P1 ^ 1; //设置LED点阵屏连接的I/O口
sbit	LED1_L3	=P1 ^ 2; //设置LED点阵屏连接的I/O口
sbit	LED1_L4	=P1 ^ 3; //设置LED点阵屏连接的I/O口
sbit	LED1_L5	=P1 ^ 4; //设置LED点阵屏连接的I/O口
sbit	LED1_L6	=P1 ^ 5; //设置LED点阵屏连接的I/O口
sbit	LED1_L7	=P1 ^ 6; //设置LED点阵屏连接的I/O口
sbit	LED1_L8	=P1 ^ 7; //设置LED点阵屏连接的I/O口

#define P1M0SET		0x00 //设置I/O口工作方式//00000000(左到右,高到低位)
#define P1M1SET		0x00 //设置I/O口工作方式//00101000
#define P3M0SET		0x00 //设置I/O口工作方式//00000000
#define P3M1SET		0x7f //设置I/O口工作方式//10010100

sbit	KEY		=P3 ^ 7; //按键1

bit PD;//秒点显示标志
unsigned char MENU;//菜单切换标志位
data unsigned char TIME_HH,TIME_MM,TIME_SS;//设置时、分、秒存放区
data unsigned char cou  = 0; // 软计数器,对10ms时基信号累加到1s 
data unsigned char bn;//扫描映射全局变量
data unsigned char PWM;//显示亮度

unsigned char code disdata[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f //无小数点数码管段码表(0~9) 
};

void delay (unsigned int a){ // 用于点扫描的延时
	unsigned int i;
	while( a-- != 0){
		for(i = 0; i < DELAY; i++); 
	}   				   
}

void dis_off (void){
	P1 = ~P1M1SET; //关所有显示
	P3 = ~P3M1SET;
	delay(10-PWM); 
}

void displayHH1 (unsigned char d){ //第1列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H1 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H1 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H1 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H1 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H1 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H1 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H1 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H1 = 1;LED1_L8 = 0;}delay(PWM);dis_off();
} 

void displayHH2 (unsigned char d){ //第2列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H2 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H2 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H2 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H2 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H2 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H2 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H2 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H2 = 1;LED1_L8 = 0;}delay(PWM);dis_off();

} 

void displayHH3 (unsigned char d){ //第3列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H3 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H3 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H3 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H3 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H3 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H3 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H3 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H3 = 1;LED1_L8 = 0;}delay(PWM);dis_off();

} 

void displayHH4 (unsigned char d){ //第4列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H4 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H4 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H4 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H4 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H4 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H4 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H4 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H4 = 1;LED1_L8 = 0;}delay(PWM);dis_off();
} 

void diplay_data (unsigned char l,unsigned char d){
		switch (l){//显示的列位置		
				case 1://			
					displayHH1(d); //将显示数据送入		
					break;//		
				case 2://			
					displayHH2(d); //将显示数据送入		
					break;//		
				case 3://			
					displayHH3(d); //将显示数据送入		
					break;//		
				case 4://			
					displayHH4(d); //将显示数据送入		
					break;//		
		}
}

void init (void){ //上电初始化
	P1M0 = P1M0SET;
	P1M1 = P1M1SET;
	P3M0 = P3M0SET;
	P3M1 = P3M1SET;
	dis_off(); 
	PWM = LI;
	TMOD = 0x11;         // 定时/计数器0,1工作于方式1   
    TH0 = 0x3c;          // 预置产生50ms时基信号   
    TL0 = 0xb0;   
    EA = 1;              // 开总中断   
    ET0 = 1;             // 定时/计数器0允许中断   
    TR0 = 1;             // 开闭定时/计数器0   
}

void main (void){ //主程序 
	unsigned char s;
	init();
	MENU=0;
	s=0;
	while (1){
		if(MENU==0){	//显示正常走时主界面
			diplay_data (1,disdata[TIME_HH/10]);
			diplay_data (2,disdata[TIME_HH%10]);
			if(PD){ // 判断DP标志位,开启关闭DP点
				diplay_data (3,disdata[TIME_MM/10]);
				diplay_data (4,disdata[TIME_MM%10]);
			}else{
				diplay_data (3,disdata[TIME_MM/10]+0x80); // DP处于最高位,加0x80
				diplay_data (4,disdata[TIME_MM%10]+0x80);
			}
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (1,disdata[TIME_HH/10]);
						diplay_data (2,disdata[TIME_HH%10]);
					}
				}
			}//长短按键处理//长按转到MENU1
			if(KEY==1 && s>10 && s<200){s=0;PWM++;if(PWM>9)PWM=1;}//短按设置亮度
			
		}
		if(MENU==1){//设置时间:小时
			diplay_data (1,disdata[TIME_HH/10]);
			diplay_data (2,disdata[TIME_HH%10]);
			diplay_data (3,0x80);
			diplay_data (4,0x80);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (3,disdata[TIME_MM/10]);
						diplay_data (4,disdata[TIME_MM%10]);
					}
				}
			}//长短按键处理//长按转到MENU1
			if(KEY==1 && s>10 && s<200){s=0;TIME_HH++;if(TIME_HH>23)TIME_HH=0;}//短按设置亮度

		}
		if(MENU==2){//设置时间:分钟
			diplay_data (3,disdata[TIME_MM/10]+0x80);
			diplay_data (4,disdata[TIME_MM%10]+0x80);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU=0;
					while(KEY==0){
						diplay_data (1,disdata[TIME_HH/10]);
						diplay_data (2,disdata[TIME_HH%10]);
						diplay_data (3,disdata[TIME_MM/10]);
						diplay_data (4,disdata[TIME_MM%10]);
					}
				}
			}//长短按键处理//长按转到MENU1
			if(KEY==1 && s>10 && s<200){s=0;TIME_MM++;TIME_SS=0;if(TIME_MM>59)TIME_MM=0;}//短按设置亮度
		}
	}
}

void tiem0(void) interrupt 1{   // T/C0中断服务程序(产生50ms时基信号)   
    cou++;                      // 软计数器加1   
    if(cou > 19){                 // 计数值到100(1s)   
        cou = 0;               // 软计数器清零   
        TIME_SS++;                 // 秒计数器加1(进位10ms*100=1s)   
		PD =~ PD;				//秒点闪烁 
        if(TIME_SS > 59){          // 秒计数值到60   
           
            TIME_SS = 0;           // 秒计数器清零   
            TIME_MM++;             // 分计数器加1(进位60s=1m)  
            if(TIME_MM > 59){      // 分计数到60   
                TIME_MM = 0;       // 分计数器清零   
                TIME_HH++;         // 时计数器加1(进位60m=1h)   
                if(TIME_HH > 23){  // 时计数到23   
                    TIME_HH = 0;   // 时计数器清零
				}  
            }   
        }   
    }   
    TH0 = 0x3c;                // 重置定时常数   
    TL0 = 0xb0;   
}


【控制LED,】

wKiom1ZHVpbS3NjCAAS3Eu-LaY8637.jpg

wKiom1ZHVpiRq1mvAAR9kW0oteo581.jpg

wKioL1ZHVvCCgDhZAA5Wt5Zi09g378.jpg

/*********************************************************************************************
程序名:    数码管驱动程序
编写时间:  2011年8月16日
硬件支持:  STC12C4052AD
接口说明:  点扫描  

KEY 低电平触发
短按触发 亮度10级调节
长按触发 时钟调节
1,设置时间
2,设置开启时间
3,设置关闭时间

字段  管脚  MCU IO口
a 13脚  P1.0
b  9脚  P1.1
c  4脚  P1.2
d  2脚  P1.3
e  1脚  P1.4
f 12脚  P1.5
g  5脚  P1.6
dp 8脚  P1.7
 
1位 14脚  P3.0
2位 11脚  P3.1
3位 10脚  P3.2
4位  6脚  P3.3


/*********************************************************************************************/

#include <STC12C2052AD.H> //STC头文件

#define LI			9	 //设置LED显示的亮度(值域:1~9)
#define DELAY		12 	//设置每一个点显示的时间长度(1~20)
sbit	LED1_H1	=P3 ^ 0; 
sbit	LED1_H2	=P3 ^ 1; 
sbit	LED1_H3	=P3 ^ 2; 
sbit	LED1_H4	=P3 ^ 3; 

sbit	LED1_L1	=P1 ^ 0; 
sbit	LED1_L2	=P1 ^ 1; 
sbit	LED1_L3	=P1 ^ 2; 
sbit	LED1_L4	=P1 ^ 3; 
sbit	LED1_L5	=P1 ^ 4; 
sbit	LED1_L6	=P1 ^ 5; 
sbit	LED1_L7	=P1 ^ 6; 
sbit	LED1_L8	=P1 ^ 7; 

#define P1M0SET		0x00 //设置I/O口工作方式//00000000(左到右,高到低位)
#define P1M1SET		0x00 //设置I/O口工作方式//00101000
#define P3M0SET		0x00 //设置I/O口工作方式//00000000
#define P3M1SET		0x1f //把P3.5 和P3.7 留出来

sbit	KEY		=P3 ^ 7; //按键1
sbit	J1		=P3 ^ 5; //继电器1*

bit PD;//秒点显示标志
unsigned char MENU;//菜单切换标志位
data unsigned char TIME_HH,TIME_MM,TIME_SS;//设置时、分、秒存放区
data unsigned char AL1_HH,AL1_MM;//设置J时、分*
data unsigned char AL2_HH,AL2_MM;//设置J时、分*
data unsigned char cou  = 0; // 软计数器,对10ms时基信号累加到1s 
data unsigned char bn;//扫描映射全局变量
data unsigned char PWM;//显示亮度

unsigned char code disdata[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f //无小数点数码管段码表(0~9) 
};

void delay (unsigned int a){ // 用于点扫描的延时
	unsigned int i;
	while( a-- != 0){
		for(i = 0; i < DELAY; i++); 
	}   				   
}

void dis_off (void){
	P1 = ~P1M1SET; //关所有显示
	P3 &= ~P3M1SET;// 避开P3.5 P3.7
	delay(10-PWM); 
}

void displayHH1 (unsigned char d){ //第1列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H1 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H1 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H1 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H1 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H1 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H1 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H1 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H1 = 1;LED1_L8 = 0;}delay(PWM);dis_off();
} 

void displayHH2 (unsigned char d){ //第2列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H2 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H2 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H2 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H2 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H2 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H2 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H2 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H2 = 1;LED1_L8 = 0;}delay(PWM);dis_off();

} 

void displayHH3 (unsigned char d){ //第3列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H3 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H3 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H3 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H3 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H3 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H3 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H3 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H3 = 1;LED1_L8 = 0;}delay(PWM);dis_off();

} 

void displayHH4 (unsigned char d){ //第4列横向显示程序
	unsigned char i;
	i = d & 0x01;
	if(i == 0x01){
		LED1_H4 = 1;LED1_L1 = 0;}delay(PWM);dis_off();
	i = d & 0x02;
	if(i == 0x02){
		LED1_H4 = 1;LED1_L2 = 0;}delay(PWM);dis_off();
	i = d & 0x04;
	if(i == 0x04){
		LED1_H4 = 1;LED1_L3 = 0;}delay(PWM);dis_off();
	i = d & 0x08;
	if(i == 0x08){
		LED1_H4 = 1;LED1_L4 = 0;}delay(PWM);dis_off();
	i = d & 0x10;
	if(i == 0x10){
		LED1_H4 = 1;LED1_L5 = 0;}delay(PWM);dis_off();
	i = d & 0x20;
	if(i == 0x20){
		LED1_H4 = 1;LED1_L6 = 0;}delay(PWM);dis_off();
	i = d & 0x40;
	if(i == 0x40){
		LED1_H4 = 1;LED1_L7 = 0;}delay(PWM);dis_off();
	i = d & 0x80;
	if(i == 0x80){
		LED1_H4 = 1;LED1_L8 = 0;}delay(PWM);dis_off();
} 

void diplay_data (unsigned char l,unsigned char d){
		switch (l){//显示的列位置		
				case 1://			
					displayHH1(d); //将显示数据送入		
					break;//		
				case 2://			
					displayHH2(d); //将显示数据送入		
					break;//		
				case 3://			
					displayHH3(d); //将显示数据送入		
					break;//		
				case 4://			
					displayHH4(d); //将显示数据送入		
					break;//		
		}
}

void init (void){ //上电初始化
	P1M0 = P1M0SET;
	P1M1 = P1M1SET;
	P3M0 = P3M0SET;
	P3M1 = P3M1SET;
	dis_off(); 
	PWM = LI;
	TMOD = 0x11;         // 定时/计数器0,1工作于方式1   
    TH0 = 0x3c;          // 预置产生50ms时基信号   
    TL0 = 0xb0;   
    EA = 1;              // 开总中断   
    ET0 = 1;             // 定时/计数器0允许中断   
    TR0 = 1;             // 开定时/计数器0   
}

void main (void){ //主程序 
	unsigned char s;
	init();
	MENU=0;
	s=0;
	J1=1;
	while (1){
		if(MENU==0){	//显示正常走时主界面
			diplay_data (1,disdata[TIME_HH/10]);
			diplay_data (2,disdata[TIME_HH%10]);
			if(PD){
				diplay_data (3,disdata[TIME_MM/10]);
				diplay_data (4,disdata[TIME_MM%10]);
			}else{
				diplay_data (3,disdata[TIME_MM/10]+0x80);
				diplay_data (4,disdata[TIME_MM%10]+0x80);
			}
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (1,disdata[TIME_HH/10]);
						diplay_data (2,disdata[TIME_HH%10]);
					}
				}
			}//长短按键处理//长按转到MENU
			if(KEY==1 && s>10 && s<200){s=0;PWM++;if(PWM>4)PWM=1;}//短按设置亮度
			
		}
		if(MENU==1){//设置时间:小时
			diplay_data (1,disdata[TIME_HH/10]);
			diplay_data (2,disdata[TIME_HH%10]);
			diplay_data (3,0x80);
			diplay_data (4,0x80);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (3,disdata[TIME_MM/10]);
						diplay_data (4,disdata[TIME_MM%10]);
					}
				}
			}  //长短按键处理//长按转到MENU
			if(KEY==1 && s>10 && s<200){s=0;TIME_HH++;if(TIME_HH>23)TIME_HH=0;}//短按设置亮度

		}
		if(MENU==2){//设置时间:分钟
			diplay_data (3,disdata[TIME_MM/10]+0x80);
			diplay_data (4,disdata[TIME_MM%10]+0x80);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (1,disdata[AL1_HH/10]);//*
						diplay_data (2,disdata[AL1_HH%10]);
						diplay_data (3,0x80);
					}
				}
			}//长短按键处理//长按转到MENU
			if(KEY==1 && s>10 && s<200){s=0;TIME_MM++;TIME_SS=0;if(TIME_MM>59)TIME_MM=0;}//短按设置亮度
		}
		if(MENU==3){//设置J1:小时
			diplay_data (1,disdata[AL1_HH/10]);
			diplay_data (2,disdata[AL1_HH%10]);
			diplay_data (3,0x80);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (3,disdata[AL1_MM/10]+0x80);
						diplay_data (4,disdata[AL1_MM%10]);
					}
				}
			}//长短按键处理//长按转到MENU
			if(KEY==1 && s>10 && s<200){s=0;AL1_HH++;if(AL1_HH>23)AL1_HH=0;}//短按设置亮度

		}
		if(MENU==4){//设置J1:分钟
			diplay_data (3,disdata[AL1_MM/10]+0x80);
			diplay_data (4,disdata[AL1_MM%10]);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (1,disdata[AL2_HH/10]);
						diplay_data (2,disdata[AL2_HH%10]);
						diplay_data (4,0x80);
					}
				}
			}//长短按键处理//长按转到MENU
			if(KEY==1 && s>10 && s<200){s=0;AL1_MM++;if(AL1_MM>59)AL1_MM=0;}//短按设置亮度
		}
		if(MENU==5){//设置J2:小时
			diplay_data (1,disdata[AL2_HH/10]);
			diplay_data (2,disdata[AL2_HH%10]);
			diplay_data (4,0x80);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU++;
					while(KEY==0){
						diplay_data (3,disdata[AL2_MM/10]);
						diplay_data (4,disdata[AL2_MM%10]+0x80);
					}
				}
			}//长短按键处理//长按转到MENU
			if(KEY==1 && s>10 && s<200){s=0;AL2_HH++;if(AL2_HH>23)AL2_HH=0;}//短按设置亮度

		}
		if(MENU==6){//设置J2:分钟
			diplay_data (3,disdata[AL2_MM/10]);
			diplay_data (4,disdata[AL2_MM%10]+0x80);
			if(KEY==0){
				s++;
				if(s>200){
					s=0;MENU=0;
					while(KEY==0){
						diplay_data (1,disdata[TIME_HH/10]);
						diplay_data (2,disdata[TIME_HH%10]);
						diplay_data (3,disdata[TIME_MM/10]);
						diplay_data (4,disdata[TIME_MM%10]);
					}
				}
			}//长短按键处理//长按转到MENU
			if(KEY==1 && s>10 && s<200){s=0;AL2_MM++;if(AL2_MM>59)AL2_MM=0;}//短按设置亮度
		}
		if(MENU==0&&AL1_HH==TIME_HH&&AL1_MM==TIME_MM&&(AL1_HH!=AL2_HH||AL1_MM!=AL2_MM)){// 开启和关闭是同一个时间,不动作
			J1=0;
		}
		if(MENU==0&&AL2_HH==TIME_HH&&AL2_MM==TIME_MM&&(AL1_HH!=AL2_HH||AL1_MM!=AL2_MM)){
			J1=1;
		}

	}
}

void tiem0(void) interrupt 1{   // T/C0中断服务程序(产生50ms时基信号)   
    cou++;                      // 软计数器加1   
    if(cou > 19){                 // 计数值到100(1s)   
        cou = 0;               // 软计数器清零   
        TIME_SS++;                 // 秒计数器加1(进位10ms*100=1s)   
		PD =~ PD;				//秒点闪烁 
        if(TIME_SS > 59){          // 秒计数值到60   
           
            TIME_SS = 0;           // 秒计数器清零   
            TIME_MM++;             // 分计数器加1(进位60s=1m)  
            if(TIME_MM > 59){      // 分计数到60   
                TIME_MM = 0;       // 分计数器清零   
                TIME_HH++;         // 时计数器加1(进位60m=1h)   
                if(TIME_HH > 23){  // 时计数到23   
                    TIME_HH = 0;   // 时计数器清零
				}  
            }   
        }   
    }   
    TH0 = 0x3c;                // 重置定时常数   
    TL0 = 0xb0;   
}

你可能感兴趣的:(4位数码管,显示数字)