1. 求單片機簡易數字鍾的課程設計 :要求自製一個單片機最小系統,包括串口下載、復位電路,採用內部定時器計
下面的程序配合這個電路運行就是對的
這個是完整的程序,電路圖如下
#include<reg52.h>
//定義共陽極字型碼0123456789-
unsignedcharcodedispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsignedchartime[]={0,0,0,0};//用來儲存分秒
unsignedchardate[]={0,0,0,0};//用來儲存日時
unsignedcharyear[]={0,0,0,0};//用來儲存年月
typedefstruct__SYSTEMTIME__
{
unsignedcharSecond;
unsignedcharMinute;
unsignedcharHour;
unsignedcharWeek;
unsignedcharDay;
unsignedcharMonth;
unsignedcharYear;
unsignedcharDateString[9];
unsignedcharTimeString[9];
}SYSTEMTIME; //定義的時間類型
SYSTEMTIMEtime1;
sbitDS1302_CLK=P1^6;//實時時鍾時鍾線引腳
sbitDS1302_IO=P1^7;//實時時鍾數據線引腳
sbitDS1302_RST=P1^5;//實時時鍾復位線引腳
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitP10=P1^0;
sbitP11=P1^1;
sbitP12=P1^2;
sbitP13=P1^3;
sbitP14=P1^4;
//#defineAM(X) X
//#definePM(X) (X+12) //轉成24小時制
#defineDS1302_SECOND 0x80//秒寄存器
#defineDS1302_MINUTE 0x82//分寄存器
#defineDS1302_HOUR 0x84
#defineDS1302_WEEK 0x8A
#defineDS1302_DAY 0x86
#defineDS1302_MONTH 0x88
#defineDS1302_YEAR 0x8C
#defineDS1302_RAM(X) (0xC0+(X)*2) //用於計算DS1302_RAM地址的宏
voidDS1302InputByte(unsignedchard) //實時時鍾寫入一位元組(內部函數)
{
unsignedchari;
ACC=d;
for(i=8;i>0;i--)
{
DS1302_IO=ACC0; //相當於匯編中的RRC
DS1302_CLK=1;
DS1302_CLK=0;//發一個高跳變到低的脈沖
ACC=ACC>>1;
}
}
unsignedcharDS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數)
{
unsignedchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1; //相當於匯編中的RRC
ACC7=DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;//發一個高跳變到低的脈沖
}
return(ACC);
}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa) //ucAddr:DS1302地址,ucData:要寫的數據
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr); //地址,命令
DS1302InputByte(ucDa); //寫1Byte數據
DS1302_CLK=1;
DS1302_RST=0;//RST0->1->0,CLK0->1
}
unsignedcharRead1302(unsignedcharucAddr) //讀取DS1302某地址的數據
{
unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;//enable
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//讀1Byte數據
DS1302_CLK=1;//RST0->1->0,CLK0->1
DS1302_RST=0;
return(ucData);
}
voidDS1302_SetProtect(bitflag)//是否防寫
{
if(flag)
Write1302(0x8E,0x10);//WP=1,不能寫入
else
Write1302(0x8E,0x00);//WP=0,可以寫入
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//設置時間函數
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));//高4位為十位,低4位為個位
}
voidDS1302_GetTime(SYSTEMTIME*Time)
{
unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//轉換成10進制的秒
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&0xf0)>>4)*10+(ReadValue&0x0F);
}
voidInitial_DS1302(void)
{
unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80)//如果第七為1(表明沒有啟動),則啟動時鍾
DS1302_SetTime(DS1302_SECOND,0);
}
voiddelay(unsignedchari)//延時子程序
{
unsignedcharj;
while((i--)!=0)
{
for(j=625;j>0;j--);
}
}
/*unsignedcharbutton_time(n,x,y)//時鍾調整子程序
unsignedcharn,x,y;
{
if(P1^7==0)
{
delay(50);
if(P1^7==0)
{
n++;
if(n==x)
n=0;
while(P1^7==0);
}
}
if(P1^1==0)
{
delay(50);
if(P1^1==0)
{
if(n==0)
n=y;
else
n--;
while(P1^1==0);
}
}
returnn;
}
*/
/*unsignedcharbutton_date(n,x,y)//日期調整子程序
unsignedcharn,x,y;
{
if(P1^7==0)
{
delay(50);
if(P1^7==0)
{
n++;
if(n==x)
n=1;
while(P1^7==0);
}
}
if(P1^1==0)
{
delay(50);
if(P1^1==0)
{
if(n==1)
n=y;
else
n--;
while(P1^1==0);
}
}
returnn;
}*/
voiddisplay1(minute10,minute1,second10,second1) //顯示第一頁分秒子程序
//unsignedcharsecond10,second1,minute10,minute1;
{
P2=0x08;
P0=dispcode[second1];//顯示秒的個位
delay(1);
P2=0x04;
P0=dispcode[second10]; //顯示秒的十位
delay(1);
P2=0x02;
P0=dispcode[minute1]; //顯示分的個位
delay(1);
P2=0x01;
P0=dispcode[minute10];//顯示分的十位
delay(1);
}
voiddisplay2(data10,data1,hour10,hour1) //顯示第二頁天時子程序
//unsignedchardata10,data1,hour10,hour1;
{
P2=0xf8;
P0=dispcode[data1];//顯示天的個位
delay(1);
P2=0xf4;
P0=dispcode[data10]; //顯示天的十位
delay(1);
P2=0xf2;
P0=dispcode[hour1]; //顯示時的個位
delay(1);
P2=0xf1;
P0=dispcode[hour10];//顯示時的十位
delay(1);
}
voiddisplay3(year10,year1,month10,month1) //顯示第三頁年月子程序
//unsignedcharyear10,year1,month10,month1;
{
P2=0xf2;
P0=dispcode[month1];//顯示月的個位
delay(1);
P2=0xf1;
P0=dispcode[month10]; //顯示月的十位
delay(1);
P2=0xf8;
P0=dispcode[year1]; //顯示月的個位
delay(1);
P2=0xf4;
P0=dispcode[year10];//顯示月的十位
delay(1);
}
voidmain()
{
unsignedcharflag=0;
Initial_DS1302(); //初始化DS1302這個時鍾晶元,
P10=0;//點亮測試燈
while(1)
{
DS1302_GetTime(&time1); //讀取時間參數
time[3]=(time1.Second)%10; //把秒的個位數據存入time[3]
time[2]=(time1.Second)/10; //把秒的十位數據存入time[2]
time[1]=(time1.Minute)%10; //把分的個位數據存入time[1]
time[0]=(time1.Minute)/10; //把分的十位數據存入time[0]
date[3]=(time1.Day)%10;
date[2]=(time1.Day)/10;
date[1]=(time1.Hour)%10;
date[0]=(time1.Hour)/10;
year[3]=(time1.Year)%10;
year[2]=(time1.Year)/10;
year[1]=(time1.Month)%10;
year[0]=(time1.Month)/10;
//display1(time[0],time[1],time[2],time[3]);
if(P11==0)
{
delay(50);
if(P11==0)
{
flag++;
if(flag>2)//flag:1顯示第二頁日時;2顯示第三頁年月0:顯示第一頁分秒
{
flag=0;
}
}
while(P11==0);
}
/*if(P1^6==0) //如果按下TimeSet鍵一下,開始顯示日期,再按一下進入日期跟時鍾的調節模式
{
delay(50);
if(P1^6==0)
{
flag++;
if(flag>6)
{
flag=0;
}
}
while(P1^6==0);
}*/
switch(flag)
{
case0:display1(time[0],time[1],time[2],time[3]); //調用子函數display,把存入數組time的數據給顯示出來
break;
case1:display2(date[0],date[1],date[2],date[3]); //調用子函數display,把存入數組date的數據給顯示出來
break;
case2:display3(year[0],year[1],year[2],year[3]);
break;
/* case3:time1.Month=button_date(time1.Month,13,12); //調整月
DS1302_SetTime(0x88,time1.Month);
display(10,10,date[2],date[3]);
break;
case4:time1.Day=button_date(time1.Day,32,31); //調整日
DS1302_SetTime(0x86,time1.Day);
display(10,10,date[4],date[5]);
break;
case5:time1.Minute=button_time(time1.Minute,60,59); //調整分
DS1302_SetTime(0x82,time1.Minute);
display(time[2],time[3],10,10);
break;
case6:time1.Second=button_time(time1.Second,60,59); //調整秒
DS1302_SetTime(0x80,time1.Second);
display(10,10,time[4],time[5]);
break;*/
}
}
}
2. 單片機89c51的電子時鍾課程設計
#include <reg52.h>
#include<stddef.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_FLAG
#define LCD1602_PORT P0
sbit lcd1602_rs=P2^0;
sbit lcd1602_e=P2^2;
sbit lcd1602_rw=P2^1;
sbit lcd1602_busy=P0^7;
sbit key_ch=P3^5;
sbit key_add=P3^6;
sbit key_minus=P3^7;
uchar i,sec,min,h,date,month,flag;
uint year;
uchar *chgstr[7]={" ","sec","min","hour","date","min","year"};
uchar j,k,m,n,o,p;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar timestr[10],datestr[10];
void init();
void delay(uint);
void time_display();
void date_display();
void control();
void time();
/*
************************************
* 函數名稱:lcd1602_CheckBusy()
* 函數功能:狀態查詢
************************************
*/
void lcd1602_CheckBusy()
{
do
{
lcd1602_busy=1;
lcd1602_rs=0;
lcd1602_rw=1;
lcd1602_e=0;
lcd1602_e=1;
}
while(lcd1602_busy);
}
/*
***************************************
* 函數名稱: lcd1602_WriteCmd()
* 函數功能:寫命令
* 入口參數:命令字
* 出口參數:無
***************************************
*/
void lcd1602_WriteCmd(const uchar cmd)
{
lcd1602_CheckBusy();
lcd1602_rs=0;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=cmd;
lcd1602_e=0;
}
/*
*******************************************
* 函數名稱:lcd1602_WriteData()
* 函數功能:寫數據
* 入口參數:c--待寫數據
* 出口參數:無
*********************************************
*/
void lcd1602_WriteData(const uchar c)
{
lcd1602_CheckBusy();
lcd1602_rs=1;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=c;
lcd1602_e=0;
}
/*
***********************************************
* 函數名稱:lcd1602_Init()
* 函數功能:初始化LCD
* 入口參數:無
* 出口參數:無
***********************************************
*/
void lcd1602_Init()
{
lcd1602_WriteCmd(0x38); //顯示模式為8位2行5*7點陣
lcd1602_WriteCmd(0x0c); //display enable,flag enable,flash enable,
lcd1602_WriteCmd(0x06); //flag move to right,screen don't move
lcd1602_WriteCmd(0x01); //clear screen
}
/*
************************************************
* 函數名稱:lcd1602_Display()
* 函數功能: 字元顯示
* 入口參數:ptr--字元或字元串指針
* 出口參數:無
* 說 明:用戶可通過以下方式來調用:
* 1)lcd1602_Display("Hello,world!");
* 2) INT8U 存儲類型 txt[]="要顯示的字元串";
* 或者 INT8U 存儲類型 txt[]={'t','x','t',..,'