/********************************************************************************* * Copyright: (C) 2014 Guo Wenxue * All rights reserved. * * Filename: gpio_i2c.c * Description: STM8 GPIOÄ£ÄâI2C´úÂë * * Version: 1.0.0(09/28/2014) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "09/28/2014 10:58:17 PM" * ********************************************************************************/ #include "gpio_i2c.h" #include "timing_delay.h" /* ¿ªÊ¼ÐźţºSCLΪ¸ßµçƽʱ£¬SDAÓÉ¸ßµçÆ½ÏòµÍµçÆ½Ìø±ä£¬¿ªÊ¼´«ËÍÊý¾Ý. */ void gpio_i2c_start(void) { SDA_MODE_OUT; SCL_LOW; TIMDelay_N10us(1); SDA_HIGH; TIMDelay_N10us(1); SCL_HIGH; TIMDelay_N10us(1); SDA_LOW; TIMDelay_N10us(1); SCL_LOW; /* StartÖ®ºóBUS×ÜÏßÒ»°ã±»ÈÏΪ´¦ÓÚÕ¼Ïß״̬ */ TIMDelay_N10us(1); } /* ½áÊøÐźţºSCLΪ¸ßµçƽʱ£¬SDAÓÉµÍµçÆ½Ïò¸ßµçÆ½Ìø±ä£¬½áÊø´«ËÍÊý¾Ý. */ void gpio_i2c_stop(void) { SDA_MODE_OUT; SCL_LOW; TIMDelay_N10us(1); SDA_LOW; TIMDelay_N10us(1); SCL_HIGH; TIMDelay_N10us(1); SDA_HIGH; TIMDelay_N10us(1); } /* ¶ÔÓÚ·´À¡ÓÐЧӦ´ðλACKµÄÒªÇóÊÇ£¬½ÓÊÕÆ÷ÔÚµÚ9¸öʱÖÓÂö³å֮ǰµÄ *µÍµçƽÆÚ¼ä½«SDAÏßÀ­µÍ£¬²¢ÇÒÈ·±£ÔÚ¸ÃʱÖÓµÄ¸ßµçÆ½ÆÚ¼äΪÎȶ¨µÄµÍµçƽ */ void gpio_i2c_send_ack(void) { SDA_MODE_OUT; /* ĬÈÏSCLÊÇµÍµçÆ½£¬ÏÖÔڸıäÊý¾Ý£¬µÍµçƽ±íʾACK */ SDA_LOW; TIMDelay_N10us(1); /* ʱÖÓÏßÀ­¸ß²¢Î¬³ÖSDA״̬ */ SCL_HIGH; TIMDelay_N10us(1); /* »Ö¸´Ê±ÖÓÏßΪµÍµçƽ£¬×ÜÏßæ */ SCL_LOW; TIMDelay_N10us(1); } /* NACK(°ÑÊý¾Ý×ÜÏßµÄµçÆ½À­µÍ¸ß)À´±íʾÊý¾Ý³É¹¦Ê§°Ü */ void gpio_i2c_send_nak(void) { SDA_MODE_OUT; /* ĬÈÏSCLÊÇµÍµçÆ½£¬ÏÖÔڸıäÊý¾Ý£¬¸ßµçƽ±íʾNAK */ SDA_HIGH; TIMDelay_N10us(1); /* ʱÖÓÏßÀ­¸ß²¢Î¬³ÖSDA״̬ */ SCL_HIGH; TIMDelay_N10us(1); /* »Ö¸´Ê±ÖÓÏßΪµÍµçƽ£¬×ÜÏßæ */ SCL_LOW; TIMDelay_N10us(1); } /* I2C ×ÜÏß¶ÁÒ»¸öACKÐźŠ* ·µ»ØÖµ:0 ÊÕµ½ACK 1: ÊÕµ½NAK */ uint8_t gpio_i2c_wait_ack(void) { uint8_t rv; uint8_t times = 200; SDA_MODE_IN; /* ʱÖÓÏßÀ­¸ß */ SCL_HIGH; TIMDelay_N10us(1); do { times --; } while ( (SDA_DAT==1) && (times!=0) ); if( !times ) { /* µÈ´ý ACK ³¬Ê±£¬½ÓÊÕµ½NAK */ rv = I2C_NAK; goto OUT; } /* µÈµ½ACK */ SCL_LOW; TIMDelay_N10us(1); rv = I2C_ACK; OUT: return rv; } /* I2C×ÜÏß·¢ËÍÒ»¸ö×Ö½ÚÊý¾Ý: * ·µ»ØÖµ:0 ·¢Ëͳɹ¦£¬µÈµ½ACK 1: ·¢ËÍʧ°Ü,ÊÕµ½NAK */ uint8_t gpio_i2c_write_byte(uint8_t byte) { int i; uint8_t rv = I2C_ACK; SDA_MODE_OUT; /* SCLΪµÍµçƽʱ,SDAÏß²ÅÄܸı䴫ÊäµÄbit; SCLΪ¸ßµçƽʱ,SDAÏß±£³ÖÎȶ¨ */ for(i=7; i>=0; i--) /* MSB */ { /*MSB: Êä³öÏàӦλµÄµçƽÐźŠ*/ if( byte&(1<