📄 clock.c
字号:
#include <AT89S8253.H>
#include <stdio.h>
#define SDA P1_2
#define SCL P1_3
#define DS1307W 0xD0
#define DS1307R 0xD1
#define i2c_start SDA=1; SCL=1; SDA=0; delay(0); SCL=0
#define i2c_clock_pulse SCL=1; delay(0); SCL=0
#define i2c_stop delay(1); SCL=1; delay(0); SDA=1
#define DS1307run result = send_i2c(0x00);
#define DS1307stop result = send_i2c(0x80);
// subroutines
void delay(unsigned long);
unsigned char read_i2c(); // read a byte from I2C bus
unsigned char send_i2c(unsigned char x); // send data(byte) to I2C bus
unsigned char read_i2c_bit(); // read a bit of I2C bus
unsigned char idata address;
void tlcd_wc(unsigned char); // write control word to TEXT LCD
void tlcd_wd(unsigned char); // write data word to TEXT LCD
// variables
unsigned char idata address;
unsigned char data LCDCont = 0x00; //00100000, [CS1] [CS2] [write] [command]
unsigned char cTimeTenHour; //ten hour
unsigned char cTimeHour; //Hour
unsigned char cTimeTenMinute; // ten minute
unsigned char cTimeMinute; //Minute
unsigned char cTimeTenSecond; // ten second
unsigned char cTimeSecond; // Second
unsigned char cTimeDayOfWeek;
unsigned char cTimeTenDate;
unsigned char cTimeDate;
unsigned char cTimeTenMonth;
unsigned char cTimeMonth;
unsigned char cTimeTenYear;
unsigned char cTimeYear;
// Constant
unsigned char code day1[] = {'M','o','n' };
unsigned char code day2[] = {'T','u','e' };
unsigned char code day3[] = {'W','e','d' };
unsigned char code day4[] = {'T','h','u' };
unsigned char code day5[] = {'F','r','i' };
unsigned char code day6[] = {'S','a','t' };
unsigned char code day7[] = {'S','u','n' };
void main()
{
int iTemp ; // Temporary integer varible
unsigned char cTemp; //temporary variable (8-bits)
unsigned char result; //a return bit from subroutine
//=== initialize =====================
address = 0xF6;
// Sound buzzer
// test program for BUZZER
for(iTemp=0; iTemp<50; iTemp++)
{
P2_7=0; //BUZZER
delay(100);
P2_7=1;
delay(100);
} /* end of "test program for BUZZER" */
// test i2c bus DS1307
i2c_start;
result = send_i2c(DS1307W);
result = send_i2c(0x00); //start address 00H
/// select one followed line
//DS1307run; //data for 00H, turn-on DS1307 oscillator
//DS1307stop;//data for 00H, turn-off DS1307 oscillator
result = send_i2c(0x55); //data for 00H - second
result = send_i2c(0x59); //data for 01H - minute
result = send_i2c(0x23); //data for 02H - hour
result = send_i2c(0x05); //data for 03H - day of week
result = send_i2c(0x09); //data for 04H - date
result = send_i2c(0x11); //data for 05H - month
result = send_i2c(0x07); //data for 06H - year
result = send_i2c(0x10); //data for 06H
i2c_stop;
/* test i2c bus DS1307 */
/* init Text mode LCD */
tlcd_wc(0x0E); // TEXT LCD ON 0000 1111, [1] [display on] [cursor on] [blinking off]
tlcd_wc(0x38); // 2lines and 5x7 0011 1000, 001[8bit],[2 lines][5x7]xx
//================================---------------------------------------------
while(1)
{
delay(200000);
P2_7 = !P2_7; // sound buzzer
// read real time clock data from DS1307
i2c_start;
result = send_i2c(DS1307W);
result = send_i2c(0x00); // set read-back register from 0x00
i2c_stop;
delay(0);
i2c_start;
result = send_i2c(DS1307R);
cTemp = read_i2c(); // DS1307 0H00
cTimeSecond = cTemp & 0x0F | 0x30;
cTimeTenSecond = cTemp >> 4;
cTimeTenSecond = cTimeTenSecond & 0x07 | 0x30;
cTemp = read_i2c(); // DS1307 0H01
cTimeMinute = cTemp & 0x0F | 0x30;
cTimeTenMinute = cTemp >> 4;
cTimeTenMinute = cTimeTenMinute & 0x07 | 0x30;
cTemp = read_i2c(); // DS1307 0H02 - 10 Hour and Hours
cTimeHour = cTemp & 0x0F | 0x30 ;
cTimeTenHour = cTemp >> 4 ;
cTimeTenHour = cTimeTenHour & 0x03 | 0x30 ;
cTemp = read_i2c(); // DS1307 0H03 - Day of week
cTimeDayOfWeek = cTemp | 0x30 ;
cTemp = read_i2c(); // DS1307 0H04 - 10 Date and Date
cTimeDate = cTemp & 0x0F | 0x30 ;
cTimeTenDate = cTemp >>4 ;
cTimeTenDate = cTimeTenDate & 0x03 | 0x30 ;
cTemp = read_i2c(); // DS1307 0H05 - 10 Month and Month
cTimeMonth = cTemp & 0x0F | 0x30 ;
cTimeTenMonth = cTemp >> 4 ;
cTimeTenMonth = cTimeTenMonth & 1 | 0x30 ;
cTemp = read_i2c(); // DS1307 0H06 - 10 Year and Year
cTimeYear = cTemp & 0x0F | 0x30 ;
cTimeTenYear = cTemp >> 4 ;
cTimeTenYear = cTimeTenYear & 0x0F | 0x30 ;
cTemp = read_i2c(); // DS1307 0H07 - Control
//mData[7] = cTemp;
i2c_stop;
// Display date and time on TEXT LCD ============================================================
tlcd_wc(0x01); delay(500); // CLEAR display 00000001, 0000000[clear display]
tlcd_wc(0x02); delay(500); //00000010, 000000[return home]0,
switch(cTimeDayOfWeek)
{
case '1' : tlcd_wd(day1[0]); tlcd_wd(day1[1]); tlcd_wd(day1[2]); break;
case '2' : tlcd_wd(day2[0]); tlcd_wd(day2[1]); tlcd_wd(day2[2]); break;
case '3' : tlcd_wd(day3[0]); tlcd_wd(day3[1]); tlcd_wd(day3[2]); break;
case '4' : tlcd_wd(day4[0]); tlcd_wd(day4[1]); tlcd_wd(day4[2]); break;
case '5' : tlcd_wd(day5[0]); tlcd_wd(day5[1]); tlcd_wd(day5[2]); break;
case '6' : tlcd_wd(day6[0]); tlcd_wd(day6[1]); tlcd_wd(day6[2]); break;
case '0' : tlcd_wd(day7[0]); tlcd_wd(day7[1]); tlcd_wd(day7[2]);
}
tlcd_wd(0x20) ;
if (cTimeTenMonth == '0')
tlcd_wd(0x20);
else tlcd_wd(cTimeTenMonth) ;
tlcd_wd(cTimeMonth) ;
tlcd_wd(0x2F) ;
tlcd_wd(cTimeTenDate) ;
tlcd_wd(cTimeDate) ;
tlcd_wd(0x2F) ;
tlcd_wd(cTimeTenYear) ;
tlcd_wd(cTimeYear) ;
tlcd_wc(0xC0); // point to second line
tlcd_wd(0x20) ; // display 4 space
tlcd_wd(0x20) ;
tlcd_wd(0x20) ;
tlcd_wd(0x20) ;
tlcd_wd(cTimeTenHour);
tlcd_wd(cTimeHour);
tlcd_wd(0x3A) ; // ':'
tlcd_wd(cTimeTenMinute);
tlcd_wd(cTimeMinute);
tlcd_wd(0x3A); // ':'
tlcd_wd(cTimeTenSecond);
tlcd_wd(cTimeSecond);
/* end "display date and time on TEXT LCD" */
} //stop while loop
}//end of main
///=== INTERRUPT SUBROUTINE ===== start here =======================
///=================================================================
///==== end INTERRRUPT SUBROUTINE ========
////== SUBROUTINE start here ===========================================
////====================================================================
/* Delay program */
void delay(unsigned long value)
{
while(value>0) value--;
}
/* send byte to i2c bus */
unsigned char send_i2c(unsigned char x)
{
bit ret;
if (x & 0x80) SDA = 1; //?xxx xxxx - send MSB
else SDA =0;
i2c_clock_pulse;
if (x & 0x40) SDA = 1; //x?xx xxxx
else SDA =0;
i2c_clock_pulse;
if (x & 0x20) SDA = 1; //xx?x xxxx
else SDA =0;
i2c_clock_pulse;
if (x & 0x10) SDA = 1; //xxx? xxxx
else SDA =0;
i2c_clock_pulse;
if (x & 0x08) SDA = 1; //xxx ?xxxx
else SDA =0;
i2c_clock_pulse;
if (x & 0x04) SDA = 1; //xxxx x?xx
else SDA =0;
i2c_clock_pulse;
if (x & 0x02) SDA = 1; //xxxx xx?x
else SDA =0;
i2c_clock_pulse;
if (x & 0x01) SDA = 1; //xxxx xxx? - send LSB
else SDA =0;
i2c_clock_pulse;
delay(0);
SDA=1; // set SDA=1, ready for read
SCL=1; //clock for bit9
delay(0);
ret = SDA;
SCL=0;
return (ret);
}
/* end of "send byte to i2c bus" */
/* read a byte from I2C bus */
unsigned char read_i2c()
{
unsigned char result=0x00;
SDA=1;
if (read_i2c_bit()==1) result = result | 0x80;
if (read_i2c_bit()==1) result = result | 0x40;
if (read_i2c_bit()==1) result = result | 0x20;
if (read_i2c_bit()==1) result = result | 0x10;
if (read_i2c_bit()==1) result = result | 0x08;
if (read_i2c_bit()==1) result = result | 0x04;
if (read_i2c_bit()==1) result = result | 0x02;
if (read_i2c_bit()==1) result = result | 0x01;
SDA=0;
delay(0);
i2c_clock_pulse;
return (result);
}
/* end of "read a byte from I2C bus" */
/* read a bit from I2C bus */
unsigned char read_i2c_bit() //
{
bit ret;
SCL=1;
delay(0);
if (SDA==1) ret=1;
else ret=0;
SCL=0;
delay(1);
return(ret);
}
/* end of "read a bit from I2C bus" */
/* write command word to TEXT LCD*/
void tlcd_wc(unsigned char cTempdata)
{
//TR0=0; //temperoray stop timer0 (dot matrix LED)
P0 = (LCDCont & 0x0F)|0x00; //CONTROL WORD=0000xxxx, [CS2] [CS1] [write] [command],
P2 = (address & 0xF0)|0x0E; //latch LCDCont to U20
P2 = address; //unselect U20
P0 = cTempdata;
P2 = (address & 0xF0)|0x0C; //select (pulse trigger) TEXT LCD
P2 = address;
//TR0=1; //resume dot matrix LED scanning
delay(10); // for LCD requirement 46us
}
/* write data to TEXT LCD */
void tlcd_wd(unsigned char cTempdata)
{
//TR0=0; //temperoray stop timer0 (dot matrix LED)
P0 = (LCDCont & 0x0F) | 0x10; //0001xxxx, [CS2] [CS1] [write] [data]
P2 = (address & 0xF0) | 0x0E; // latch LCDCont to U20
P2 = address; // unselect U20
P0= cTempdata;
P2 = (address & 0xF0) | 0x0C; //select TEXT LCD
P2 = address; // unselect (pulse trigger)TEXT LCD
//TR0=1; //resume dot matrix LED scanning
delay(10); // for LCD requirement 46us
}
// program end/////////////////// no use
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -