Ⅰ 求c51單片機電子鍾程序(c語言)
#include <reg51.h>
#define uchar unsigned char //定義unsigned int為uint
#define uint unsigned int //定義unsigned uchar為uchar
sbit LCD_RS = P2^0 ;
sbit LCD_RW = P2^1 ;
sbit LCD_EN = P2^2 ;
sbit D_SDA = P2^6; //定義74HC164數據線為P2.6埠
sbit D_SCL = P2^7; //定義74HC164數據線為P2.7埠
sbit CLK = P1^3; /*實時時鍾時鍾線引腳 */
sbit IO = P1^4; /*實時時鍾數據線引腳 */
sbit RST = P1^5; /*實時時鍾復位線引腳 */
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
uchar time[8] = {0x50,0x30,0x19,0x30,0x12,0x06,0x06};
//========= 延時函數 ============
//延時時間以1ms為單位
//s決定延時時間長短
void delay_ms(uint s)
{
uint x;
for(s;s>0;s--)
{
x = 200;
while(x--);
}
}
//========= 送出一個位元組給74HC164(實現串並轉換) ==========
void send_out(unsigned char out)//傳送一個位元組8位
{
uchar i;
D_SCL = 0;
for (i=8;i>=1;i--)
{
D_SDA = out&0x80; //送數據到數據口
D_SCL = 1; //時鍾線置1
D_SCL = 0; //送一時鍾
out<<=1; //左移
}
}
//========= 寫命令函數 ==========
void lcd_wcmd(uchar cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
send_out(cmd);
LCD_EN = 1;
LCD_EN = 0 ;
}
//========= 寫數據函數 ==========
void lcd_wdat(uchar dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
send_out(dat);
LCD_EN = 1;
LCD_EN = 0;
}
//========= LCD初始化函數 ==========
void lcd_init()
{
lcd_wcmd(0x38);
delay_ms(1);
lcd_wcmd(0x0c); //顯示開,關游標
delay_ms(1);
lcd_wcmd(0x06); //向右移動游標
delay_ms(1);
lcd_wcmd(0x01); //清除LCD顯示屏
delay_ms(1);
}
//========== 往DS1302寫入1Byte數據 (內部函數) =============
void w_byte(uchar dat)
{
uchar i;
for(i=8; i>0; i--)
{
IO = dat & 0x01;
CLK = 1;
CLK = 0;
dat = dat >> 1;
}
}
//======== 從DS1302讀取1Byte數據 (內部函數) ===================
uchar r_byte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >> 1;
ACC7 = IO;
CLK = 1;
CLK = 0;
}
return(ACC);
}
//========== 指定地址往DS1302寫入1Byte數據 (內部函數) =============
void write_byte(uchar addr, uchar dat)
{
RST = 0;
CLK = 0;
RST = 1;
w_byte(addr);
w_byte(dat);
CLK = 1;
RST = 0;
}
//========== 指定地址往DS1302讀1Byte數據 (內部函數) =============
uchar read_byte(uchar addr)
{
uchar ucData;
RST = 0;
CLK = 0;
RST = 1;
w_byte(addr);
ucData = r_byte();
CLK = 1;
RST = 0;
return(ucData);
}
//============ 設置ds1302日期和時間 =============
void write_ds1302(uchar *p)
{
uchar i;
uchar addr = 0x80;
write_byte(0x8e,0x00); // 控制命令,WP=0,寫操作
for(i =7; i>0; i--)
{
write_byte(addr,*p); // 秒 分 時 日 月 星期 年
p++;
addr +=2;
}
write_byte(0x8e,0x80); // 控制命令,WP=1,防寫
}
//============ 讀ds1302當前日期和時間 =============
void read_ds1302(uchar *p)
{
uchar i;
uchar addr = 0x81;
for (i=0; i<7; i++)
{
*p = read_byte(addr); //格式為: 秒 分 時 日 月 星期 年
addr += 2;
p++;
}
}
//============ 顯示函數 ===================
void lcd_disp()
{
uchar addr = 4;
lcd_wcmd(0x80 + addr);
lcd_wdat(((time[2]>>4)&0x0f)+0x30); //顯示小時
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat((time[2]&0x0f)+0x30);
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(':'); //顯示":"
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(((time[1]>>4)&0x0f)+0x30); //顯示分
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat((time[1]&0x0f)+0x30);
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(':'); //顯示":"
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat(((time[0]>>4)&0x0f)+0x30); //顯示秒
addr++;
lcd_wcmd(0x80 + addr);
lcd_wdat((time[0]&0x0f)+0x30);
addr = 2;
lcd_wcmd(0xc0 + addr); //在第二行顯示年月日和星期
lcd_wdat('2'); //顯示2
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat('0'); //顯示0
addr++;
lcd_wdat(((time[6]>>4)&0x0f)+0x30); //年
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[6]&0x0f)+0x30);
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(' ');
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(((time[4]>>4)&0x0f)+0x30); //顯示月
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[4]&0x0f)+0x30);
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(' ');
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(((time[3]>>4)&0x0f)+0x30); //顯示日
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[3]&0x0f)+0x30);
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat(' ');
addr++;
lcd_wcmd(0xc0 + addr);
lcd_wdat((time[5]&0x0f)+0x30); //顯示星期
}
//=========== 主函數 ===============
void main()
{
lcd_init(); // 初始化LCD
write_ds1302(time);
while(1)
{
read_ds1302(time); //讀DS1302數據
lcd_disp(); //LCD顯示
delay_ms(500); //延時0.5秒
}
}
這是一個電子時鍾,在LCD1602上顯示,時鍾晶元是DS1302
Ⅱ 如何做一個單片機電子時鍾
這個很簡單啊,兩種思路:1,用單片機定時器來做,優點是外圍電路簡單,只需要一個單片機最小系統,和一個顯示模塊(1602液晶比較好);缺點是:定時不是很准,跑的時間長了會有誤差,而且主要是程序,要寫很多,不過程序不是很難。2,用時鍾晶元,一般都用DS1302,還需要單片機最小系統和顯示模塊,優點是:定時准確,誤差很小,在有備用電池的情況下,即使單片機掉電,也可以維持很長時間,程序相對簡單。缺點是:外圍電路比前者相對復雜一點。如果想做個實際的東西拿來用,建議使用第二種方法,如果是想鍛煉自己的編程能力的話,選第一種吧。祝成功!
Ⅲ 51單片機電子鍾
看看這個簡單的模擬實例,供參考
Ⅳ 用51單片機做一個LED顯示的電子鍾
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="ME-400-A clock";
uchar code table1[]=" --:--:-- ";
uchar code table2[]="ALL:00:00:-- ";
uchar code table3[]=" ";
uchar clk_time[3]; //秒,分,時寄存器初始值
sbit T_RST=P2^2;//ds1302-5
sbit T_IO=P2^3;//ds1302-6
sbit T_CLK=P2^4;//ds1302-7
sbit en=P2^5; //參照LCD1602說明檔,使能信號
sbit rw=P2^6; //。。。。。。。。,讀寫信號端(輸入高電頻時為讀,低電為寫)
sbit rs=P2^7; //。。。。。。。。,數據/命令選擇端(H/L)
sbit led=P1^0;
sbit la=P1^1;
sbit wela=P1^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit up=P3^3;
sbit down=P3^4;
sbit set=P3^2;
sbit did=P1^4;
uchar num,clock_ss,clock_sg,clock_fs,clock_fg,clock_ms,clock_mg,b,clock_s,clock_g;
char hour,mie,sei,c,nhour,nmie,shour,smie;
/******************DS1302:寫入操作(上升沿)*********************/
void write_byte(uchar da)
{
uchar i;
ACC=da;
for(i=8;i>0;i--)
{
T_IO=ACC0;
T_CLK=0;
T_CLK=1;
ACC=ACC>>1;
}
}
/******************DS1302:讀取操作(下降沿)*****************/
uchar read_byte(void)
{
uchar i;
for(i=0;i<8;i++)
{
ACC=ACC>>1;
T_CLK = 1;
T_CLK = 0;
ACC7 = T_IO;
}
return(ACC);
}
/******************DS1302:寫入數據(先送地址,再寫數據)***************************/
void write_1302(uchar addr,uchar da)
{
T_RST=0; //停止工作
T_CLK=0; //只有在CLK為低電平時,才能將RST置為高電平,然後才能傳輸數據
T_RST=1; //重新工作
write_byte(addr); //寫入地址
write_byte(da);
T_RST=0;
T_CLK=1;
}
/******************DS1302:讀取數據(先送地址,再讀數據)**************************/
uchar read_1302(uchar addr)
{
uchar temp;
T_RST=0; //停止工作
T_CLK=0;
T_RST=1; //重新工作
write_byte(addr); //寫入地址
temp=read_byte();
T_RST=0;
T_CLK=1; //停止工作
return(temp);
}
/***********************延時程序=a*1ms**************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void fn()
{
did=0;
delay(120);
did=1;
delay(120);
did=0;
delay(120);
did=1;
delay(120);
did=0;
delay(120);
did=1;
delay(120);
did=0;
delay(320);
did=1;
delay(400);
}
void write_com(uchar com)
{
led=1;
wela=1;
P0=0xff;
delay(1);
led=0;
wela=0;
P0=0x00;
la=1;
delay(1);
la=0;
rs=0;
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write_data(uchar date)
{
led=1;
wela=1;
P0=0xff;
delay(1);
led=0;
wela=0;
P0=0x00;
la=1;
delay(1);
la=0;
rs=1;
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void morning()
{ shour=clock_ss*10+clock_sg;
smie=clock_fs*10+clock_fg;
if(b==0)
{
if(nhour==shour)
{
if(smie>=nmie)
{
fn();
}
}
}
}
void init()
{
b=0;
P0=0xff;
delay(5);
led=1;
delay(5);
P0=0xff;
led=0;
la=0;
wela=1;
delay(5);
wela=0;//關ME-400開發板數碼管
nhour=0;
nmie=0;
rw=0;
en=0;
write_com(0x38);//設置液晶
write_com(0x0c);//設游標等
write_com(0x06);//寫一個字元地址指針加1且游標加1
write_com(0x01);//清屏
write_com(0x80);//設置s地址指針
}
void display(uchar add,date)
{
if(b==0)
{
clock_ms=clk_time[0]/ 16; clock_mg=clk_time[0]%16;
led=0;
clock_fs=clk_time[1]/ 16; clock_fg=clk_time[1]%16;
led=0;
clock_ss=clk_time[2]/ 16; clock_sg=clk_time[2]%16;
write_com(0x80+0x44);
write_data(0x30+clock_ss);
write_com(0x80+0x45);
write_data(0x30+clock_sg);
write_com(0x80+0x47);
write_data(0x30+clock_fs);
write_com(0x80+0x48);
write_data(0x30+clock_fg);
write_com(0x80+0x4a);
write_data(0x30+clock_ms);
write_com(0x80+0x4b);
write_data(0x30+clock_mg);
}
if(b!=0)
{
clock_s=date/ 10; clock_g=date%10;
write_com(0x80+0x40+add);
write_data(0x30+clock_s);
write_data(0x30+clock_g);
}
}
void key()
{
uchar clock_s1, clock_s2, clock_f1, clock_f2;
rw=0;
if(set==0)
{
delay(10);
if(set==0)
{
did=0;
delay(10); did=1;
b++;
}
while(!set);
if(b==1)
{
hour=clock_ss*10+clock_sg;
mie=clock_fs*10+clock_fg;
write_com(0x80+0x45);
write_com(0x0f);
}
if(b==2)
{
write_com(0x80+0x48);
}
if(b==3)
{
write_com(0x80+0x40);
for(num=0;num<13;num++)
{
write_data(table2[num]);
}
write_com(0x80+0x45); display(4,nhour);write_com(0x80+0x45);
}
if(b==4)
{
write_com(0x80+0x48);
display(7,nmie); write_com(0x80+0x48);
}
if(b==5)
{
write_com(0x80+0x40);
for(num=0;num<4;num++)
{
write_data(table3[num]);
}
write_com(0x80+0x45);
write_com(0x0c);
b=0;
clock_s1=hour/10;//十進制轉十六進制
clock_s2=hour%10;//十進制轉十六進制
clock_s1=clock_s1&0xff;//十進制轉十六進制
clock_s2=clock_s2&0xff;//十進制轉十六進制
clock_s1<<=4;//十進制轉十六進制
clock_s1=clock_s1|clock_s2;//十進制轉十六進制
clock_f1=mie/10;//十進制轉十六進制
clock_f2=mie%10;//十進制轉十六進制
clock_f1=clock_f1&0xff; //全1出1 與運算
clock_f2=clock_f2&0xff;//十進制轉十六進制
clock_f1<<=4;//十進制轉十六進制
clock_f1=clock_f1|clock_f2;//十進制轉十六進制
write_1302(0x8e,0x00); //WP=0 寫操作
write_1302(0x80,0x00);//寫秒
write_1302(0x82,clock_f1);//寫分
write_1302(0x84,clock_s1);//寫時
write_1302(0x86,0x14);//寫日
write_1302(0x88,0x02);//寫月
write_1302(0x8a,0x06);//寫星期
write_1302(0x8c,0x09);
write_1302(0x8e,0x80); //WP=1 防寫
}
}
if(b!=0)
{
if(up==0)
{
delay(10);
if(up==0)
{
did=0;
delay(10);
did=1;
while(!up);
if(b==1)
{
hour++;
if(hour>=24)
{
delay(1);
hour=0;
}
display(4,hour);
write_com(0x80+0x45);
}
if(b==2)
{
mie++;
if(mie>=60)
{
mie=0;
}
display(7,mie);
write_com(0x80+0x48);
}
if(b==3)
{
nhour++;
if(nhour>=24)
{
delay(1);
nhour=0;
}
display(4,nhour);
write_com(0x80+0x45);
}
if(b==4)
{
nmie++;
if(nmie>=60)
{
nmie=0;
}
display(7,nmie);
write_com(0x80+0x48);
}
}
}
if(down==0)
{
delay(10);
if(down==0)
{
did=0;
delay(10);
did=1;
while(!down);
if(b==1)
{
hour--;
if(hour<0)
{
hour=23;
}
display(4,hour);
write_com(0x80+0x45);
}
if(b==2)
{
mie--;
if(mie<0)
{
mie=59;
}
display(7,mie);
write_com(0x80+0x48);
}
if(b==3)
{
nhour--;
if(nhour<0)
{
nhour=23;
}
display(4,nhour);
write_com(0x80+0x45);
}
if(b==4)
{
nmie--;
if(nmie<0)
{
nmie=59;
}
display(7,nmie);
write_com(0x80+0x48);
}
}
}
}
}
void main()
{
uchar temp=0x80;
uchar i;
init();
for(num=0;num<14;num++)
{
write_data(table[num]);
delay(100);
}
write_com(0x80+0x40); // 設置數據地址指針為0X40
for(num=0;num<15;num++)
{
write_data(table1[num]);
}
/*for(num=0;num<16;num++)
{
write_com(0x18);
delay(20);
}*/
write_1302(0x8e,0x00);
write_1302(0x90,0xa4);
write_1302(0x8e,0x80);
while(1)
{
if(b==0)
{ temp=0x81;
for(i=0;i<3;i++)
{
clk_time[i]=read_1302(temp);
temp+=2;
}
display(0x4b,0x00);
}
morning();
key();
}
}
1602做的時鍾
Ⅳ 單片機電子鍾
願意出錢的找我`~~980100952
Ⅵ 如何用單片機做電子鍾
基本上有兩種方法:
1.使用外部時鍾晶元,如DS1302,DS12C887等
2.只使用MCU內部晶振提供的時間基準。
郭天祥的那個視頻中,兩種都有介紹,可以看下。
視頻網上流傳很多,可方便下載到
Ⅶ 如何用51單片機製作簡易電子鍾
我自己做的一個課程設計,程序運行已經成功了:
匯編程序如下:
ORG0000H
AJMPmain
ORG000BH;定時器0的中斷向量地址
AJMPTIME0;跳轉到真正的定時器程序處
ORG30H
main:
movdptr,#k1;
start:
MOVP0,#00H;中斷預處理程序
MOVP1,#00H
MOVP3,#00H;關所有燈
MOVR0,#00H;軟體計數器預清0
MOVR7,#00H
MOVR6,#00H
MOVTMOD,#00000001B;定時/計數器0工作於方式1
MOVTH0,#3CH
MOVTL0,#0B0H;即數15536
SETBEA;開總中斷允許
SETBET0;開定時/計數器0允許
SETBTR0;定時/計數器0開始運行
LOOP:;判斷時鍾進位程序
MOVA,R1
CJNEA,#60,LOOP1;R1等於60嗎?
MOVR1,#0
INCR2;R1等於60那麼R2加一,R1清0
MOVA,R2
CJNEA,#60,LOOP1;R2等於60嗎?
MOVR2,#0
INCR3;R2等於60那麼R3加一,R2清0
MOVA,R3
CJNEA,#24,LOOP1;R3等於24嗎?
MOVR3,#0
;R3等於24那麼R3清0
LOOP1:
mova,r2;如果分鍾顯示為0,報警
cjnea,#01H,LOOP2
mova,r1
cjnea,#00H,LOOP3
clrp2.0
LOOP3:
mova,r1;如果秒鍾顯示為1,取消報警
cjnea,#05H,LOOP2
setbp2.0
LOOP2:;顯示數據處理
MOVA,R1;取來8位二進制數
MOVB,#100
DIVAB;除以100
MOVA,B;取回余數
MOVB,#10
DIVAB;再除以10
MOVR4,A;商是十位數,存放到R4
MOVR5,B;余數是個位,存放到R5
MOV42H,R4
mOV41H,R5
;R1的BCD碼放入41-42H單元
MOVA,R2;取來8位二進制數
MOVB,#100
DIVAB;除以100
MOVA,B;取回余數
MOVB,#10
DIVAB;再除以10
MOVR4,A;商是十位數,存放到R4
MOVR5,B;余數是個位,存放到R5
MOV44H,R4
MOV43H,R5
;R2的BCD碼放入43-44H單元
MOVA,R3;取來8位二進制數
MOVB,#100
DIVAB;除以100
MOVA,B;取回余數
MOVB,#10
DIVAB;再除以10
MOVR4,A;商是十位數,存放到R4
MOVR5,B;余數是個位,存放到R5
MOV46H,R4
mov45H,R5
;R3的BCD碼放入45-46H單元
L1:
mova,41h
movca,@a+dptr
mov51h,a
mova,42h
movca,@a+dptr
mov52h,a
mova,43h
movca,@a+dptr
mov53h,a
mova,44h
movca,@a+dptr
mov54h,a
mova,45h
movca,@a+dptr
mov55h,a
mova,46h
movca,@a+dptr
mov56h,a;將顯示代碼送入51H--56H
display:;顯示程序
movp0,#0ffH;一
movp0,51H
movP1,#0feH
acalldelay1S
movp1,#0ffH
movp0,#0ffH;二
movp0,52h
movP1,#0fdH
acalldelay1S
movp1,#0ffH
movp0,#0ffH;三
movp0,53h
movP1,#0fbH
acalldelay1S
movp1,#0ffH
movp0,#0ffH;四
movp0,54h
movP1,#0f7H
acalldelay1S
movp1,#0ffH
movp0,#0ffH;五
movp0,55h
movP1,#0efH
acalldelay1S
movp1,#0ffH
movp0,#0ffH;六
movp0,56h
movP1,#0dfH
acalldelay1S
movp1,#0ffH
;將51H-56H數據顯示,
AJMPLOOP;工作處理程序
TIME0:;定時器0的中斷處理程序
INCR7
MOVA,R7
CJNEA,#20,T_RET;R7單元中的值到了20了嗎?
T_L1:
INCR1;到了20那麼R1+1
MOVR7,#0;清軟體計數器
T_RET:;二十分之一秒時的程序
incr6
mova,r6
cjner6,#3,T_over;調節時間的延遲時間
movr6,#0
jbp2.1,T_over1
mova,r2
adda,#1
cjnea,#60,T_tiao1
mova,#0
T_tiao1:
movr2,a
T_over1:
jbp2.2,T_over
mova,r3
adda,#1
cjnea,#24,T_tiao2
mova,#0
T_tiao2:
movr3,a
T_over:
MOVTH0,#3CH
MOVTL0,#0B0H;如果沒到一秒重置定時常數
reti
delay1s:MOV31H,#100
D1:MOV32H,#30
D2:DJNZ32H,D2
DJNZ31H,D1
RET
delay2s:MOV33H,#255
D3:MOV34H,#255
D4:DJNZ34H,D4
DJNZ33H,D3
RET
K1:db3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh
Ⅷ 電子鍾 單片機
見郵箱
Ⅸ 單片機電子鍾
單片機(Single-Chip Microcomputer)是一種集成電路晶元,是採用超大規模集成電路技術把具有數據處理能力的中央處理器CPU、隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統、定時器/計數器等功能(可能還包括顯示驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊矽片上構成的一個小而完善的微型計算機系統
Ⅹ 51單片機做數字電子鍾
這么復雜的東西給這么少分 暈死了 你也太小氣了吧,分多的話還可能幫你動動腦