Analog I2C communication control ds1307 read/write hardware clock
# Include "Global. H "# include" drv_ds1307.h "# define i2c_clk_port gpiob # define extends gpio_pin_4 # define implements gpiob # define implements writable # define scl_high () gpio_init (i2c_clk_port, small, small) # define scl_low () gpio_init (i2c_clk_port, i2c_clk_pin, timeout) # define sda_high () gpio_init (i2c_sda_port, i2c_sda_pin, timeout W) # define sda_low () gpio_init (i2c_sda_port, i2c_sda_pin, timeout) # define sdam () (gpio_readinputdata (i2c_sda_port) & 0x20 )? 1:0 # define set_scl_out () gpio_init (i2c_clk_port, container, container) # define set_sda_out () gpio_init (container, container, container) # define container () gpio_init (gpioa, container, container) extern uint8_t encode (uint8_t writeaddr, uint8_t writedata); extern uint8_t ds1307_readbyte (uint8_t readaddr); extern void ds1307_writedata (); N void ds1307_readdata (); extern void init_timer (); extern void write_time (); uint8_t g_u8readdata [8]; /*************************************** **************************************** // function: i2c_int // Description: simulate I2C and ds1307 port initialization // Param: // return: // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/static void i2c_int (void) {set_sd A_out (); set_scl_out ();} /*************************************** **************************************** // function: delay_5us // Description: the latency of the latency function is about 16 us // Param: // return: FCPU 16 MHz // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/static void delay_5us (void) {uint8_t I; for (I = 5; I> 0; I --);} /******************************** **************************************** * ****** // Function: i2c_start // Description: I2C start signal transmission when the SCL is high, SDA changes from high to low // Param: // return: // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/static void i2c_start (void) {// SDA 1-> 0 while SCL high sda_high (); scl_high (); delay_5us (); sda_low (); delay_5us (); scl_low ();} /************************ **************************************** * ************** // Function: i2c_stop // Description: I2C stop transmission signal when the SCL is high, SDA changes from low to high // Param: // return: // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/static void i2c_stop (void) {// SDA 0-> 1 while SCL high sda_low (); scl_high (); delay_5us (); sda_high (); delay_5us ();} /***************************** **************************************** * ******** // Function: i2c_sendack // Description: The host sends a response signal to the slave machine // Param: Response Signal 1: SDA high (no response) 0: SDA low (response) // return: // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/static void i2c_sendack (uint8_t ACK) {If (ACK = 0) {sda_low () ;}else {sda_high () ;}scl_high (); delay_5us (); scl_low (); delay_5u S ();} /*************************************** **************************************** // function: i2c_sendbyte // Description: simulate I2C communication to send 8-Bit Data // Param: The sent 8 is the data value // return: return response signal 0 indicates there is a response 1 indicates no response // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/static uint8_t i2c_sendbyte (uint8_t sendbyte) {static uint8_t I, revack; sda_low (); for (I = 0; I <8; I ++) {scl_low (); If (sendbyte & 0x80) // write data {sda_high () ;}else {sda_low () ;} delay_5us (); sendbyte <= 1; scl_high (); delay_5us ();} scl_low (); sda_high (); delay_5us (); set_sda_in (); scl_high (); ASM ("NOP"); ASM ("NOP"); revack = (uint8_t) sdam (); delay_5us (); scl_low (); set_sda_out (); delay_5us (); return revack ;} /*************************************** ******************************** * ****** // Function: i2c_recvbyte // Description: simulate I2C communication to read 8-bit data from the slave machine // Param: // return: the returned 8 is the data value // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/static uint8_t i2c_recvbyte () {uint8_t I; uint8_t recvdata = 0; sda_high (); // latch the data port befor reading set_sda_in (); for (I = 0; I <8; I ++) {recvdata <= 1; scl_high (); ASM ("NOP"); SM ("NOP"); If (sdam () {recvdata | = 0x01;} else {recvdata & = 0xfe;} delay_5us (); scl_low (); delay_5us ();} set_sda_out (); Return recvdata ;} /*************************************** **************************************** // function: ds1307_writebyte // Description: Write 1 byte of data to the specified address through analog I2C communication // Param: writeaddr: data to be written writedata; write address // return: 1: successfully written 0: write error // Author: huangzhigang 2014-0410 ************ **************************************** * ************************/Uint8_t ds1307_writebyte (uint8_t writeaddr, uint8_t writedata) {i2c_start (); If (i2c_sendbyte (0xd0) // device ADDR + write (operation) {return 0;} If (i2c_sendbyte (writeaddr )) {return 0;} If (i2c_sendbyte (writedata) {return 0;} i2c_stop (); return 1 ;} /*************************************** ************************************** ** // Function: ds1307_readbyte // Description: reads 1 byte of data from the specified address through analog I2C communication // Param: readaddr: Read address // return: revdata: read 8-Bit Data // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/uint8_t ds1307_readbyte (uint8_t readaddr) {uint8_t revdata; i2c_start (); i2c_sendbyte (0xd0); // device ADDR + write (operation) i2c_sendbyte (readaddr); i2c_start (); i2c_se Ndbyte (0xd1); // device ADDR + write (operation) revdata = i2c_recvbyte (); i2c_sendack (1); i2c_stop (); Return revdata ;} /*************************************** **************************************** // function: ds1307_writedata // Description: simulate I2C communication and write 8 bytes of data from 0x00 ~ 0x07 // Param: pwritedata: pointer pointing to the address of the array to be written // return: // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/void ds1307_writedata () {uint8_t I; uint8_t * pwritedata; pwritedata = (uint8_t *) & ictimerbuf; i2c_start (); i2c_sendbyte (0xd0); // device ADDR + write (Operation) i2c_sendbyte (0x00); for (I = 0; I <8; I ++) {i2c_sendbyte (* pwritedata ++);} I2C _ Stop ();} /*************************************** **************************************** // function: ds1307_readdata // Description: reads 8 bytes of data from 0x00 ~ 0x07 // Param: preaddata: pointer to the array that stores the data // return: // Author: huangzhigang 2014-0410 ************************************ **************************************** * **/void ds1307_readdata () {uint8_t I; uint8_t * preaddata; preaddata = (uint8_t *) & ictimerbuf; i2c_start (); i2c_sendbyte (0xd0); // device ADDR + write (Operation) i2c_sendbyte (0x00); i2c_start (); i2c_sendbyte (0xd1); // device ADDR + write (Opera Tion) for (I = 0; I <7; I ++) {// * preaddata ++ = i2c_recvbyte (); * preaddata = i2c_recvbyte (); preaddata ++; if (I <6) i2c_sendack (0); // Dio low level indicates ack responds to else i2c_sendack (1) ;}i2c_stop ();} /*************************************** **************************************** // function: init_timer // Description: Initialize the clock upon power-on and read the clock // Param: // return: judge whether 0x00 address bit7 is 1 to 1 indicates that the clock chip powers down. // Author: huangzhigang 2014-0422 *** **************************************** * **********************************/Void init_timer () {i2c_int (); ds1307_readdata (); If (ictimerbuf. timersec & 0x80) {ds1307_readdata (); If (ictimerbuf. timersec & 0x80) {ictimerbuf. timersec = 0x00; ictimerbuf. timermin = 0x00; ictimerbuf. timerhour = 0x12; ictimerbuf. timerweek = 0x02; ictimerbuf. timerday = 0x15; ictimerbuf. timermonth = 0x04; ictimerbuf. timeryear = 0 X14; ds1307_writedata () ;}} ictimer. timersec = (ictimerbuf. timersec/16) * 10 + (ictimerbuf. timersec % 16); ictimer. timermin = (ictimerbuf. timermin/16) * 10 + (ictimerbuf. timermin % 16); ictimer. timerhour = (ictimerbuf. timerhour & 0x1f)/16) * 10 + (ictimerbuf. timerhour & 0x1f) % 16); ictimer. timerweek = (ictimerbuf. timerweek/16) * 10 + (ictimerbuf. timerweek % 16); ictimer. timerday = (ictimerbuf. timerday/16) * 10 + (Ictimerbuf. timerday % 16); ictimer. timermonth = (ictimerbuf. timermonth/16) * 10 + (ictimerbuf. timermonth % 16); ictimer. timeryear = (ictimerbuf. timeryear/16) * 10 + (ictimerbuf. timeryear % 16); // update the system time parameter g_u8timesettinghourvalue = ictimer. timerhour; g_u8timesettingminutesvalue = ictimer. timermin; g_u8timesettingampmvalue = (ictimerbuf. timerhour & 0x20 )? 1:0 ;} /*************************************** **************************************** // function: write_time // Description: If the clock is set, write it to the clock // Param: // return: // Author: huangzhigang 2014-0422 ************************************ **************************************** * **/void write_time () {If (g_u8timechangeflag) // If the clock {g_u8timechangeflag = 0; ictimerbuf. timersec = (ictimer. timersec/10) * 16 + (ictimer. timersec % 10); ictimerbuf. timermin = (ictimer. timermin/10) * 16 + (ictimer. timermin % 10); ictimerbuf. timerhour = (ictimer. timerhour/10) * 16 + (ictimer. timerhour % 10); ictimerbuf. timerweek = (ictimer. timerweek/10) * 16 + (ictimer. timerweek % 10); ictimerbuf. timerday = (ictimer. timerday/10) * 16 + (ictimer. timerday % 10); ictimerbuf. timermonth = (ictimer. timermonth/10) * 16 + (ictimer. timermonth % 10); ictimerbuf. timeryear = (ictimer. timeryear/10) * 16 + (ictimer. timeryear % 10); // converts the time to 12. If (g_u8timesettingampmvalue % 2) // 1 indicates PM {ictimerbuf. timerhour | = 0x60;} else // 0 indicates am {ictimerbuf. timerhour | = 0x40;} // after the conversion, write the time into the chip ds1307_writedata ();}}