51微控制器控制DS1302,時間顯示在數碼管上

時間 2021-09-10 12:11:59

1樓:匿名使用者

1302.c

#include

#include

uchar bit_ser=;

uchar seven_seg = ;

/***********************時間顯示*****************/

void timer0_init(void)  //t0初始化函式,用於時間的動態顯示

tmod = 0x21;

tl0 = (65536-5000) % 256;

th0 = (65536-5000) / 256;

ea = 1;

et0 = 1;

tr0 = 1;

void timer0_isr(void) interrupt 1  //t0中斷處理函式

char flag;   //flag用於表示調整時閃爍的亮或滅

tr0 = 0;

tl0 = (65536-5000) % 256;

th0 = (65536-5000) / 256;

tr0 = 1;

flag = x / 100 * 0xff; //設定閃爍標誌,如果x大於100則flag為0xff,小於100則為0x00

x++;

if(x > 200)

x = 0;

switch(i)

case 0:

p2 = bit_ser[0];

if(setflag == 3)  //根據setflag的值判斷當前位是否需要閃爍

p0 = flag | seven_seg[dis_buffer[0]];

else

p0 = seven_seg[dis_buffer[0]];

break;

case 1:

p2 = bit_ser[1];

if(setflag == 3)

p0 =flag | seven_seg[dis_buffer[1]];

else

p0 =seven_seg[dis_buffer[1]];

break;

case 2:

p2 = bit_ser[2];

if(setflag == 2)

p0 =flag | seven_seg[dis_buffer[2]];

else

p0 =seven_seg[dis_buffer[2]];

break;

case 3:

p2 = bit_ser[3];

if(setflag == 2)

p0 =flag | seven_seg[dis_buffer[3]];

else

p0 =seven_seg[dis_buffer[3]];

break;

case 4:

p2 = bit_ser[4];

if(setflag == 1)

p0 =flag | seven_seg[dis_buffer[4]];

else

p0 =seven_seg[dis_buffer[4]];

break;

case 5:

p2 = bit_ser[5];

if(setflag == 1)

p0 =flag | seven_seg[dis_buffer[5]];

else

p0 =seven_seg[dis_buffer[5]];

break;

i++;

if(i >= 6)

i = 0;

if(j == 10)

j = 0;

if(setflag == 0)

ds1302_gettime(&time); //如果setflag是0,就從1302中讀出時間,因為setflag不是0時,說明處於調整狀態,不需要讀時間

dis_buffer[5] = time.second % 10; //把當前時間放入顯示緩衝區

dis_buffer[4] = time.second / 10;

dis_buffer[3] = time.minute % 10;

dis_buffer[2] = time.minute / 10;

dis_buffer[1] = time.hour % 10;

dis_buffer[0] = time.hour / 10;

j++;

void main()

initial_ds1302(time);

timer0_init();

while(1)

set_down();

timer_down();

up_down();

down_down();

beepflag_down();

if(setflag == 0 && time.hour == romhour && time.minute == romminute && beepflag == 1) //判斷蜂鳴器是否要響

beep = !beep;

//key.c

#include

#define uchar unsigned char

#define uint unsigned int

uchar i = 0,j = 0,x = 0,setflag,flag_set,flag_timer;   //setflag用來表示調整的位置,flag_set和flag_timer分別表示當前處於調整狀態還是定時狀態

systemtime time=;    //系統時間的初始值2023年6月30日星期三,15時20分0秒

char dis_buffer[6];    //存放顯示資料的緩衝區

sbit beep_flag = p3^2;    //蜂鳴器的介面

sbit key_timer = p3^4;    //定時按鈕

sbit key_set = p3^5;    //調整按鈕

sbit key_up = p3^6;    //增加按鈕

sbit key_down = p3^7;    //減小按鈕

char romhour,romminute,romsec;    //分別存放定時的時,分,秒

bit beepflag;    //標記鬧鐘是否開啟

//延時函式

void delays(uchar x)

while(x) x--;

//設定鍵的處理函式

void set()

setflag ++;

flag_set = 1;

if(setflag >= 4)

setflag = 0;

flag_set = 0;

initial_ds1302(time);

//定時間的處理函式

void timer()

setflag ++;

flag_timer = 1;

if(setflag == 1)

time.hour = romhour;

time.minute = romminute;

time.second = romsec;

else if(setflag >= 4)

setflag = 0;

flag_timer = 0;

romhour = time.hour;

romminute = time.minute;

romsec = time.second;

//增加鍵的處理函式

void up()

switch(setflag)

case 0:

break;

case 1:

time.second ++;

if(time.second >= 60)

time.second = 0;

break;

case 2:

time.minute ++;

if(time.minute >= 60)

time.minute = 0;

break;

case 3:

time.hour ++;

if(time.hour >= 24)

time.hour = 0;

break;

//減小鍵的處理函式

void down()

switch(setflag)

case 0:

break;

case 1:

time.second --;

if(time.second < 0)

time.second = 59;

break;

case 2:

time.minute --;

if(time.minute < 0)

time.minute = 59;

break;

case 3:

time.hour --;

if(time.hour < 0)

time.hour = 23;

break;

//設定鍵的掃描函式

void set_down()

if(key_set == 0 && flag_timer == 0)

delays(100);

if(key_set == 0)

set();

while(!key_set);

//定時鍵的掃描函式

void timer_down()

if(key_timer == 0 && flag_set == 0)

delays(100);

if(key_timer == 0)

timer();

while(!key_timer);

//增加鍵的掃描函式

void up_down()

if(key_up == 0 && setflag != 0)

delays(100);

if(key_up == 0)

up();

while(!key_up);

//減少鍵的處理函式

void down_down()

if(key_down == 0 && setflag != 0)

delays(100);

if(key_down == 0)

down();

while(!key_down);

//定時開關的掃描處理函式

void beepflag_down()

if(beep_flag == 0)

delays(100);

beepflag = !beepflag;

while(!beep_flag);

//ds1302.h

#ifndef _real_timer_ds1302

#define _real_timer_ds1302

#include

sbit  ds1302_clk = p1^1;              //實時時鐘時鐘線引腳

sbit  ds1302_io  = p1^2;              //實時時鐘資料線引腳

sbit  ds1302_rst = p1^3;              //實時時鐘復位線引腳

sbit  acc0 = acc^0;

sbit  acc7 = acc^7;

sbit  beep = p2^7;

typedef struct __systemtime__

systemtime; //定義的時間型別

#define am(x) x

#define pm(x) (x+12)               // 轉成24小時制

#define ds1302_second 0x80          //秒暫存器

#define ds1302_minute 0x82          //分暫存器

#define ds1302_hour 0x84

#define ds1302_week 0x8a

#define ds1302_day 0x86

#define ds1302_month 0x88

#define ds1302_year 0x8c

#define ds1302_ram(x) (0xc0+(x)*2)    //用於計算 ds1302_ram 地址的巨集

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;                  //rst 0->1->0,clk 0->1

unsigned char read1302(unsigned char ucaddr) //讀取ds1302某地址的資料

{ unsigned char ucdata;

ds1302_rst = 0;

ds1302_clk = 0;

ds1302_rst = 1;                      //enable

ds1302inputbyte(ucaddr|0x01);        // 地址,命令

ucdata = ds1302outputbyte();         // 讀1byte資料

ds1302_clk = 1;                      //rst 0->1->0,clk 0->1

ds1302_rst = 0;

return(ucdata);

void ds1302_setprotect(bit flag)        //是否防寫

{ if(flag)

write1302(0x8e,0x80); //wp=1,不能寫入

else

write1302(0x8e,0x00);//wp=0,可以寫入

void ds1302_settime(unsigned char address, unsigned char value)        // 設定時間函式

{ ds1302_setprotect(0);

write1302(address, ((value/10)<<4 | (value%10))); //高4位為十位,低4位為個位

ds1302_setprotect(1);

//獲取時間函式,從ds1302內讀取時間然後存入time內

void ds1302_gettime(systemtime *time)

{ unsigned char readvalue;

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&0x70)>>4)*10 + (readvalue&0x0f);

//利用stime初始化ds1302

void initial_ds1302(systemtime stime)

{ unsigned char second=read1302(ds1302_second);

如果第七為1(表明沒有啟動), 則啟動時鐘

ds1302_settime(ds1302_second,stime.second);  //設定起始時間

ds1302_settime(ds1302_minute,stime.minute);

ds1302_settime(ds1302_hour,stime.hour);

ds1302_settime(ds1302_day,stime.day);

ds1302_settime(ds1302_month,stime.month);

ds1302_settime(ds1302_year,stime.year);

ds1302_settime(ds1302_week,stime.week);

#endif

51微控制器控制數碼管並顯示,51微控制器控制8個數碼管並顯示

啟巖 數碼管段選連線到微控制器p0口,位選連線到p2口org 0000h main call display ajmp main display mov r0,0 mov r1,0x01 mov dptr,tab loop inc r0 mov a,r0 movc a,a dptr mov p0,0...

51微控制器按鍵控制流水燈左移,51微控制器的c語言 左移右移怎麼用?想用來控制流水燈,請幫忙寫個完整的c程式,參考下,埠隨意

按鍵不能用while函式來寫,第八行 if k1 0 按一次執行一次函式內容 開始學習微控制器的同學們寫注意了,在執行程式後,現象不正確的時候,不要首先就找軟體的錯誤,我的經驗是從源頭開始找問題,首先你得確定你的平臺是正確的,你說是按鍵沒效果,先用萬用表測試一下你的引腳的電平,是否被拉低了如果按鍵沒...

51微控制器的ds18b20,51微控制器與DS18B20程式

匯流排拉低,就是由微控制器控制,使dq 0。由於一般dq是結在集電極開路輸出口上,實際上微控制器在dq上輸出的高電平是靠上拉電阻來實現電位變高的。可以理解為,微控制器 不使 dq 0。那麼此時dq 1即是高電平,實際上也就是微控制器放棄了dq的控制,這個高電平僅僅是因為上拉電阻提供的,dq的控制權就...