基于单片机的多功能数字时钟? 51单片机数字时钟设计
基于单片机的多功能数字时钟的设计
就是调时定时还用的着ds1302啊,直接用单片机连显示就可以了,你把你的时钟功能列清楚,我帮你写一个
基于单片机的数字时钟设计
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};//共阳极数码管数据表0--F
uchar code scan_con[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选码表右-->左
uchar data timedata[]={0x00,0x00,0x00,0x00,0x00,0x00};//计时单元数据初值,共6个
uchar data dis[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//显示单元数据,共8个数据
uchar data con1s=0x00,con04s=0x00,con=0x00;//秒定时用
sbit key0=P1^0;
sbit key1=P1^1;
sbit key2=P1^2;
//
void delay(uint t) //延时子函数
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<110;j++);
}
//
keyscan()//键盘扫描子程序
{
EA=0;
if(key0==0)
{
delay(10);
while(key0==0);
if(dis[con]==10)
{dis[7]=dis[con];dis[con]=dis[6];dis[6]=dis[7];}
con++;
TR0=0;
ET0=0;
TR1=1;
ET1=1;
if(con>=6)
{
con=0;
TR1=0;
ET1=0;
TR0=1;
ET0=1;
}
}
//
if(con!=0)
{
if(key1==0)
{
delay(10);
while(key1==0);
timedata[con]++;
if(timedata[con]>=10)
{timedata[con]=0;}
dis[con]=timedata[con];dis[6]=0x0a;
}
}
//
if(con!=0)
{
if(key2==0)
{
delay(10);
while(key2==0);
if(timedata[con]==0)
{timedata[con]=0x09;}
else
{
timedata[con]--;
}
dis[con]=timedata[con];dis[6]=0x0a;
}
}
EA=1;
}
//
void scan()//扫描程序
{
char k;
for(k=0;k<6;k++)
{
P0=table[dis[k]];
P2=scan_con[k];
delay(1);
P2=0xff;
}
}
//
研究基于单片机的多功能电子时钟的设计的意思和目的是什么
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key0=P3^0;
sbit key1=P3^1;
sbit key2=P3^2;
sbit key3=P3^3;
sbit key4=P3^4;
sbit key5=P3^5;
sbit dula=P2^0;
sbit wet=P2^1;
sbit wef=P2^2;
uchar aa,m,s,ZZ,YY;
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void delayms(uint xms);
void displaytime(uchar m,uchar s);
void displayzuo(uchar Z,ucharY);
void delayms(uint xms);
void keyscan();
void time();
void init();
void main()
{
init();
while(1)
{
keyscan();
time();
displaytime( m, s);
displayzuo(ZZ,YY);
}
}
void displaytime(uchar m,uchar s)
{
uchar qian,bai,shi,ge;
qian=m/10;bai=m%10;shi=s/10; ge=s%10;
P0=tab[qian];dula=1;dula=0;P0=0x00;
wef=0;P1=0x01;wet=1;wet=0; delayms(2);
P0=tab[bai];dula=1; dula=0;P0=0x00;
wef=0;P1=0x02;wet=1;wet=0;delayms(2);
P0=tab[shi];dula=1;dula=0;P0=0x00;
wef=0;P1=0x04;wet=1;wet=0;delayms(2);
P0=tab[ge]; dula=1; dula=0; P0=0x00;
wef=0; P1=0x08;wet=1;wet=0;delayms(2);
wef=0;P1=0x00;wet=1;wet=0;//锁存器复位
}
void displayzuo(uchar Z,uchar Y)
{
uchar zbai,zshi,zge, ybai,yshi,yge;
zbai=Z/100;zshi=Z%100/10;zge=Z%100%10;
ybai=Y/100;yshi=Y%100/10;yge=Y%100%10;
P0=tab[zge]; dula=1;dula=0;P0=0x00;
wet=0;P1=0x08;wef=1;wef=0;delayms(2);
P0=tab[zshi];dula=1;dula=0;P0=0x00;
wet=0;P1=0x04;wef=1;wef=0; delayms(2);
P0=tab[zbai]; dula=1;dula=0;P0=0x00;
wet=0; P1=0x02;wef=1;wef=0;delayms(2);
P0=tab[ybai];dula=1; dula=0; P0=0x00;
wet=0; P1=0x20;wef=1;wef=0;delayms(2);
P0=tab[yshi];dula=1; dula=0; P0=0x00;
wet=0;P1=0x40;wef=1;wef=0;delayms(2);
P0=tab[yge];dula=1;dula=0; P0=0x00;
wet=0;P1=0x80;wef=1;wef=0; delayms(2);
wet=0;P1=0x00;wef=1;wef=0; //锁存器复位
}
void delayms(uint xms)
{
int i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1; ET0=1;TR0=0;
}
void keyscan()
{
uchar temp;
if(key0==0)
{
delayms(1);
if(key0==0)
{
ZZ--;
if(ZZ<0)
ZZ=255;
while(!key0);
}
}
if(key1==0)
{
delayms(1);
if(key1==0)
{
ZZ++;
if(ZZ>255)
ZZ=0;
while(!key1);
}
}
if(key2==0)
{
delayms(1);
if(key2==0)
{
YY--;
if(YY<0)
YY=255;
while(!key2);
}
}
if(key3==0)
{
delayms(1);
if(key3==0)
{
YY++;
if(YY>255)
YY=0;
while(!key3);
}
}
if(key4==0)
{
delayms(1);
if(key4==0)
{
TR0=~TR0;
while(!key4);
}
}
if(key5==0)
{
delayms(1);
if(key5==0)
{
temp=YY;
YY=ZZ;
ZZ=temp;
while(!key5);
}
}
}
void time()
{
if(aa==20)
{
aa=0;
s++;
if(s==60)
{
s=0;
m++;
if(m==99)
{
m=0;
}
}
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
用单片机设计一个数字时钟
#include <REG51.H>#include <intrins.h>
#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7; //实时时钟时钟线引脚 sbit DS1302_IO = P1^6; //实时时钟数据线引脚 sbit DS1302_RST = P1^5; //实时时钟复位线引脚sbit wireless_1 = P3^0;sbit wireless_2 = P3^1;sbit wireless_3 = P3^2;sbit wireless_4 = P3^3; //无线控制sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数sbit Set = P2^0; //模式切换键sbit Up = P2^1; //加法按钮sbit Down = P2^2; //减法按钮sbit out = P2^3; //立刻跳出调整模式按钮sbit DQ = P1^0; //温度传送数据IO口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; //温度值uchar TempBuffer[5],week_value[2];
void show_time(); //液晶显示程序/***********1602液晶显示部分子程序****************///Port Definitions**********************************************************sbit LcdRs= P2^5;sbit LcdRw= P2^6;sbit LcdEn = P2^7;sfr DBPort = 0x80;//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************unsigned char LCD_Wait(void){LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_(); LcdEn=0;return DBPort;}//向LCD写入命令或数据************************************************************#define LCD_COMMAND0 // Command#define LCD_DATA1 // Data#define LCD_CLEAR_SCREEN0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();//注意顺序LcdEn=1;_nop_();//注意顺序LcdEn=0;_nop_();LCD_Wait();}
//设置显示模式************************************************************#define LCD_SHOW0x04 //显示开#define LCD_HIDE0x00 //显示关
#define LCD_CURSOR0x02 //显示光标#define LCD_NO_CURSOR0x00 //无光标
#define LCD_FLASH0x01 //光标闪动#define LCD_NO_FLASH0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode){LCD_Write(LCD_COMMAND, 0x08|DisplayMode);}
//设置输入模式************************************************************#define LCD_AC_UP0x02#define LCD_AC_DOWN0x00 // default
#define LCD_MOVE0x01 // 画面可平移#define LCD_NO_MOVE0x00 //default
void LCD_SetInput(unsigned char InputMode){LCD_Write(LCD_COMMAND, 0x04|InputMode);}
//初始化LCD************************************void LCD_Initial(){LcdEn=0;LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动}
//液晶字符输入的位置************************void GotoXY(unsigned char x, unsigned char y){if(y==0)LCD_Write(LCD_COMMAND,0x80|x);if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));}
//将字符输出到液晶显示void Print(unsigned char *str){while(*str!='\0'){LCD_Write(LCD_DATA,*str);str++;}}
/***********DS1302时钟部分子程序******************/typedef struct __SYSTEMTIME__{unsigned char Second;unsigned char Minute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString[11];unsigned char TimeString[9];}SYSTEMTIME;//定义的时间类型SYSTEMTIME CurrentTime;
#define AM(X)X#define PM(X)(X+12) // 转成24小时制#define DS1302_SECOND0x80 //时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE0x82#define DS1302_HOUR0x84 #define DS1302_WEEK0x8A#define DS1302_DAY0x86#define DS1302_MONTH0x88#define DS1302_YEAR0x8C
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数){ unsigned char i; ACC = d; for(i=8; i>0; i--) { DS1302_IO = ACC0; //相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } }
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数){ unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; //相当于汇编中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; } return(ACC); }
void Write1302(unsigned char ucAddr, unsigned char ucDa)//ucAddr: DS1302地址, ucData: 要写的数据{ DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); // 地址,命令 DS1302InputByte(ucDa); // 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0;}
unsigned char Read1302(unsigned char ucAddr)//读取DS1302某地址的数据{ unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);}
void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组{unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MINUTE);Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_HOUR);Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_DAY);Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_WEEK);Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MONTH);Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);}
void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22 { Time->DateString[0] = '2'; Time->DateString[1] = '0'; Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year%10 + '0';} else { Time->DateString[0] = ' '; Time->DateString[1] = ' '; Time->DateString[2] = ' '; Time->DateString[3] = ' ';}Time->DateString[4] = '/';if(hide_month<2){ Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month%10 + '0';} else { Time->DateString[5] = ' '; Time->DateString[6] = ' '; }Time->DateString[7] = '/';if(hide_day<2){ Time->DateString[8] = Time->Day/10 + '0'; Time->DateString[9] = Time->Day%10 + '0';} else { Time->DateString[8] = ' '; Time->DateString[9] = ' '; }if(hide_week<2){ week_value[0] = Time->Week%10 + '0'; //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示} else { week_value[0] = ' '; } week_value[1] = '\0';
Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符}
void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];{ if(hide_hour<2) { Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour%10 + '0';} else { Time->TimeString[0] = ' '; Time->TimeString[1] = ' ';}Time->TimeString[2] = ':'; if(hide_min<2){ Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute%10 + '0';} else { Time->TimeString[3] = ' '; Time->TimeString[4] = ' '; }Time->TimeString[5] = ':'; if(hide_sec<2) { Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second%10 + '0'; } else { Time->TimeString[6] = ' '; Time->TimeString[7] = ' '; }Time->DateString[8] = '\0';}
void Initial_DS1302(void) //时钟芯片初始化{ unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) //判断时钟芯片是否关闭 {Write1302(0x8e,0x00); //写入允许Write1302(0x8c,0x07); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55Write1302(0x88,0x07);Write1302(0x86,0x25);Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); //禁止写入}
}
/***********ds18b20子程序*************************/
/***********ds18b20延迟子函数(晶振12MHz )*******/
void delay_18B20(unsigned int i){while(i--);}
/**********ds18b20初始化函数**********************/
void Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ复位 delay_18B20(8); //稍做延时 DQ = 0; //单片机将DQ拉低 delay_18B20(80); //精确延时 大于 480us DQ = 1; //拉高总线 delay_18B20(14); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(20);}
/***********ds18b20读一个字节**************/
unsigned char ReadOneChar(void){uchar i=0;uchar dat = 0;for (i=8;i>0;i--) { DQ = 0; // 给脉冲信号 dat>>=1; DQ = 1; // 给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4); } return(dat);}
/*************ds18b20写一个字节****************/
void WriteOneChar(uchar dat){ unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat>>=1; }}
/**************读取ds18b20当前温度************/
void ReadTemp(void){unsigned char a=0;unsigned char b=0;unsigned char t=0;
Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
delay_18B20(100);
a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位temp_value=b<<4;temp_value+=(a&0xf0)>>4; }void temp_to_str() //温度数据转换成液晶字符显示{ TempBuffer[0]=temp_value/10+'0'; //十位 TempBuffer[1]=temp_value%10+'0'; //个位 TempBuffer[2]=0xdf; //温度符号 TempBuffer[3]='C'; TempBuffer[4]='\0';}void Delay1ms(unsigned int count){unsigned int i,j;for(i=0;i<count;i++)for(j=0;j<120;j++);}
/*延时子程序*/void mdelay(uint delay){uint i; for(;delay>0;delay--) {for(i=0;i<62;i++) //1ms延时. {;} }}