标题:
6312 驱动程序 VFD显示屏 时钟
[打印本页]
作者:
51黑科技
时间:
2016-2-4 03:50
标题:
6312 驱动程序 VFD显示屏 时钟
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
/*
sbit VFD_REM = P1^7;
sbit VFD_CLK = P1^6;
sbit VFD_STB = P1^5;
sbit VFD_DIN = P1^4;
sbit DS1302_IO=P2^6;
sbit DS1302_CLK=P2^5;
sbit DS1302_RST=P2^7;
sbit k1=P3^4;//功能键
sbit k2=P3^5;//增加键
sbit k3=P3^6;//减小键
sbit k4=P3^7;//查看键
*/
sbit VFD_CLK = P1^6;
sbit VFD_STB = P1^5;
sbit VFD_DIN = P1^7;
sbit k1=P3^0;//功能键
sbit k2=P3^1;//增加键
sbit k3=P3^2;//减小键
sbit k4=P3^6;//闹钟查看键
sbit DS1302_IO=P1^0;
sbit DS1302_CLK=P3^7;
sbit DS1302_RST=P1^1;
bit r=1; //用来显示秒点
uchar code vfdmap[]={0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0x00};//0-9,-,全灭
uchar code tab[]={0x00,0x10,0x20,0x40,0x80,0x01,0x02,0x04};//用于星期的
uchar sec,min,hour,year,month,day,week,s1num,flag,shu;
unsigned char vfdbuf[]={0,0,0,0,0,0,0};
uchar time[7];
void vfd_cmd (uchar vfd_cmd0); /* 写命令*/
void vfd_wrdata (uchar vfd_wrdata0); /* 写数据 */
void vfd_init (void); /*16312初始化 */
void vfd_cmd (uchar vfd_cmd0) /* VFD 写控制命令子程序 */
{
unsigned char i;
VFD_STB=1;
VFD_CLK=1;
for ( i=0;i<8;i++ )
{
VFD_STB=0;
VFD_CLK=0;
VFD_DIN = vfd_cmd0&0x01;
VFD_CLK=1;
vfd_cmd0>>=1;
}
VFD_STB=1;
VFD_CLK=1;
}
void vfd_wrdata (uchar vfd_wrdata0) /* VFD 写数据子程序 */
{
unsigned char i;
for(i=0;i<8;i++)
{
VFD_CLK=1;
VFD_STB=0;
VFD_CLK=0;
VFD_DIN=vfd_wrdata0&0x01;
VFD_CLK=1;
vfd_wrdata0>>=1;
}
VFD_STB=0;
VFD_CLK=1;
}
void vfd_init(void)
{
vfd_cmd ( 0x02 ); /* 6栅X16段显示模式 */
vfd_cmd ( 0x40 ); /* 显示正常模式,数据地址递增 */
vfd_wrdata ( 0xc0 ); /* 设置地址从00H开始 */
}
void delay_ms(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=150;y>0;y--);
}
void vfd_time_disp(uchar t_sec,t_min,t_hour,t_week) //显示
{
uchar min_ge,sec_shi,sec_ge,min_shi,hour_ge,hour_shi,week;
sec_shi=(t_sec>>4)&0x0f;
sec_ge=t_sec&0x0f;
min_shi=(t_min>>4)&0x0f;
min_ge=t_min&0x0f;
hour_shi=(t_hour>>4)&0x0f;
hour_ge=t_hour&0x0f;
week=t_week&0x0f;
vfdbuf[0]=vfdmap[hour_shi];
vfdbuf[1]=vfdmap[hour_ge];
vfdbuf[2]=vfdmap[min_shi];
vfdbuf[3]=vfdmap[min_ge];
vfdbuf[4]=vfdmap[sec_shi];
vfdbuf[5]=vfdmap[sec_ge];
vfdbuf[6]=tab[week]; //星期
vfd_init( );
vfd_wrdata (vfdbuf[1]); //C0 第1栅
vfd_wrdata (vfdbuf[0]); //C1
vfd_wrdata (0x08); //C2 第2栅
vfd_wrdata (0); //C3
vfd_wrdata (vfdbuf[3]|r); //C4 第3栅
vfd_wrdata (vfdbuf[2]|0x01); //C5
vfd_wrdata (vfdbuf[5]); //C6 第4栅
vfd_wrdata (vfdbuf[4]|0x01); //C7
vfd_wrdata (0x10); //C8 第5栅
vfd_wrdata (0x10); //C9
vfd_wrdata (0); //CA
vfd_wrdata (vfdbuf[6]);//CB
VFD_STB=1;
delay_ms(10);
vfd_cmd ( 0x8f ); // 显示开,14/16脉宽
delay_ms(1);
}
void vfd_date_disp(uchar t_day,t_month,t_year,t_week) //显示
{
uchar day_shi,day_ge,month_shi,month_ge,year_ge,year_shi,week;
day_shi=(t_day>>4)&0x0f;
day_ge=t_day&0x0f;
month_shi=(t_month>>4)&0x0f;
month_ge=t_month&0x0f;
year_shi=(t_year>>4)&0x0f;
year_ge=t_year&0x0f;
week=t_week&0x0f;
vfdbuf[0]=vfdmap[year_shi];
vfdbuf[1]=vfdmap[year_ge];
vfdbuf[2]=vfdmap[month_shi];
vfdbuf[3]=vfdmap[month_ge];
vfdbuf[4]=vfdmap[day_shi];
vfdbuf[5]=vfdmap[day_ge];
vfdbuf[6]=tab[week]; //星期
vfd_init( );
vfd_wrdata (vfdbuf[1]); //C0 第1栅
vfd_wrdata (vfdbuf[0]); //C1
vfd_wrdata (0x08); //C2 第2栅
vfd_wrdata (0); //C3
vfd_wrdata (vfdbuf[3]); //C4 第3栅
vfd_wrdata (vfdbuf[2]); //C5
vfd_wrdata (vfdbuf[5]); //C6 第4栅
vfd_wrdata (vfdbuf[4]); //C7
vfd_wrdata (0x10); //C8 第5栅
vfd_wrdata (0x10); //C9
vfd_wrdata (0); //CA
vfd_wrdata (vfdbuf[6]);//CB
VFD_STB=1;
delay_ms(10);
vfd_cmd ( 0x8f ); // 显示开,14/16脉宽
delay_ms(1);
}
void wdayte_byte(uchar dat) //写1字节数据到1302,低位在前。
{
uchar i;
for(i=0;i<8;i++)
{
DS1302_IO=0;
if(dat&0x01)
DS1302_IO=1;
else
DS1302_IO=0;
dat=dat>>1;
DS1302_CLK=0;
DS1302_CLK=1;
}
DS1302_CLK=0;
}
uchar read_byte() //从DS1302中读1字节数据,读出时高位在前。
{
uchar i,dat;
for(i=0;i<8;i++)
{
dat=dat>>1;
if(DS1302_IO)
dat=dat|0x80;
DS1302_CLK=1;
DS1302_CLK=0;
}
DS1302_CLK=0;
return(dat);
}
void wdayte_ds1302(uchar add,uchar dat) //向DS1302的add地址中写入dat数据
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
wdayte_byte(add);
wdayte_byte(dat);
DS1302_CLK=0;
DS1302_RST=0;
}
uchar read_ds1302(uchar add) //从DS1302的add地址中读出数据
{
uchar time ;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
wdayte_byte(add);
time=read_byte();
DS1302_CLK=0;
DS1302_RST=0;
return(time);
}
void init_ds1302() //时间初始化函数,不进行初始化DS1302不能正常工作
{
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x8c,time[0]); //写入年数据
wdayte_ds1302(0x88,time[1]); //写入月数据
wdayte_ds1302(0x86,time[2]); //写入日数据
wdayte_ds1302(0x84,time[3]); //写入时数据
wdayte_ds1302(0x82,time[4]); //写入分数据
wdayte_ds1302(0x80,time[5]); //写入秒数据
wdayte_ds1302(0x8a,time[6]); //写入星期数据
wdayte_ds1302(0x90,0xa5); //充电(因用的是法拉电容,所以选一个二极管,2K电阻)
wdayte_ds1302(0x8e,0x80);
}
void read_time() //时间读取函数
{
sec=read_ds1302(0x81);
min=read_ds1302(0x83);
hour=read_ds1302(0x85);
week=read_ds1302(0x8b);
day=read_ds1302(0x87);
month=read_ds1302(0x89);
year=read_ds1302(0x8d);
time[0]=year;
time[1]=month;
time[2]=day;
time[3]=hour;
time[4]=min;
time[5]=sec;
time[6]=week;
}
void keyscan() //键盘检测函数,用于时间的调节
{
if(k4==0) //K4在没有调整时间时按下显示日期,有调时按下先保存退出再显示日期
{
delay_ms(1);
if(k4==0)
{
if(flag==1)
{
init_ds1302();
}
vfd_date_disp(day,month,year,week);
delay_ms(2000);
flag=0;
s1num=0;
}
}
if(k1==0)
{
delay_ms(1);
if(k1==0)
{
while(!k1);
s1num++;
flag=1;
if(s1num==7)
{
init_ds1302();
flag=0;
s1num=0;
}
}
}
if(s1num!=0)
{
if(k2==0)//加键按下
{
delay_ms(1);
if(k2==0)
{
switch(s1num)
{
case 1: min=((min/16)*10)+(min%16);
min++;
if(min==60)
min=0;
time[4]=(((min/10)<<4)&0xf0)|((min%10)&0x0f);
time[5]=0x00;
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x80,time[5]);
wdayte_ds1302(0x82,time[4]);
wdayte_ds1302(0x8e,0x80);
break;
case 2: hour=((hour/16)*10)+(hour%16);
hour++;
if(hour==24)
hour=0;
time[3]=(((hour/10)<<4)&0xf0)|((hour%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x84,time[3]);
wdayte_ds1302(0x8e,0x80);
break;
case 3: day=((day/16)*10)+(day%16);
day++;
if(day==32)
day=1;
time[2]=(((day/10)<<4)&0xf0)|((day%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x86,time[2]);
wdayte_ds1302(0x8e,0x80);
break;
case 4: month=((month/16)*10)+(month%16);
month++;
if(month==13)
month=1;
time[1]=(((month/10)<<4)&0xf0)|((month%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x88,time[1]);
wdayte_ds1302(0x8e,0x80);
break;
case 5: year=((year/16)*10)+(year%16);
year++;
if(year>99)
year=0;
time[0]=(((year/10)<<4)&0xf0)|((year%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x8c,time[0]);
wdayte_ds1302(0x8e,0x80);
break;
case 6: week=week%16;
week++;
if(week>7)
week=1;
time[6]=((week%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x8a,time[6]);
wdayte_ds1302(0x8e,0x80);
break;
}
}
}
if(k3==0)//减键按下
{
delay_ms(1);
if(k3==0)
{
switch(s1num)
{
case 1: min=((min/16)*10)+(min%16);
min--;
if(min==-1)
min=59;
time[4]=(((min/10)<<4)&0xf0)|((min%10)&0x0f);
time[5]=0x00;
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x80,time[5]);
wdayte_ds1302(0x82,time[4]);
wdayte_ds1302(0x8e,0x80);
break;
case 2: hour=((hour/16)*10)+(hour%16);
hour--;
if(hour==-1)
hour=23;
time[3]=(((hour/10)<<4)&0xf0)|((hour%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x84,time[3]);
wdayte_ds1302(0x8e,0x80);
break;
case 3: day=((day/16)*10)+(day%16);
day--;
if(day==0)
day=31;
time[2]=(((day/10)<<4)&0xf0)|((day%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x86,time[2]);
wdayte_ds1302(0x8e,0x80);
break;
case 4: month=((month/16)*10)+(month%16);
month--;
if(month==-1)
month=12;
time[1]=(((month/10)<<4)&0xf0)|((month%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x88,time[1]);
wdayte_ds1302(0x8e,0x80);
break;
case 5: year=((year/16)*10)+(year%16);
year--;
if(year==-1)
year=99;
time[0]=(((year/10)<<4)&0xf0)|((year%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x8c,time[0]);
wdayte_ds1302(0x8e,0x80);
break;
case 6: week=week%16;
week--;
if(week==0)
week=7;
time[6]=((week%10)&0x0f);
wdayte_ds1302(0x8e,0x00);
wdayte_ds1302(0x8a,time[6]);
wdayte_ds1302(0x8e,0x80);
break;
}
}
}
}
}
void set_time_disp(s1num,flag) //时间调节显示函数
{
uchar i;
if((s1num==1)&&(flag==1))
{
read_time();
for(i=0;i<10;i++)
vfd_time_disp(sec,min,hour,week);
for(i=0;i<10;i++)
vfd_time_disp(sec,0xaa,hour,week);
}
if((s1num==2)&&(flag==1))
{
read_time();
for(i=0;i<10;i++)
vfd_time_disp(sec,min,hour,week);
for(i=0;i<10;i++)
vfd_time_disp(sec,min,0xaa,week);
}
if((s1num==3)&&(flag==1))
{
read_time();
for(i=0;i<10;i++)
vfd_date_disp(day,month,year,week);
for(i=0;i<10;i++)
vfd_date_disp(0xaa,month,year,week);
}
if((s1num==4)&&(flag==1))
{
read_time();
for(i=0;i<10;i++)
vfd_date_disp(day,month,year,week);
for(i=0;i<10;i++)
vfd_date_disp(day,0xaa,year,week);
}
if((s1num==5)&&(flag==1))
{
read_time();
for(i=0;i<10;i++)
vfd_date_disp(day,month,year,week);
for(i=0;i<10;i++)
vfd_date_disp(day,month,0xaa,week);
}
if((s1num==6)&&(flag==1))
{
read_time();
for(i=0;i<10;i++)
vfd_date_disp(day,month,year,week);
for(i=0;i<10;i++)
vfd_date_disp(day,month,year,0x00);
}
}
void main()
{
TMOD=0x01; //设定定时器0为方式1
TH0=(65536-50000)/256; //定时时间设置,时间设为50毫秒
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0
while(1)
{
keyscan();
read_time(); //按键检测
if(flag==0) //如果没有按键进入这里
{
vfd_time_disp(sec,min,hour,week);
}
if(flag==1) //如果有按键进入这里
{
set_time_disp(s1num,flag);
}
}
}
void T0_time() interrupt 1 //中断函数用于秒点的闪烁,周期1秒
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
shu++; //用于时间的计数10次500MS
if(shu==10)
{
shu=0;
r=~r; //每500毫秒led取反一次
}
}
复制代码
作者:
GUOPK
时间:
2016-2-6 13:01
可以发一下电路??控制是什么形号的VDF屏??
作者:
w1179benp
时间:
2020-1-26 09:08
求教各位走过路过的朋友,这个程序如何改成PT6311的?知道显存地址不同,可是不会改
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1