⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 Contiki是一个开源
💻 C
字号:
/* * Copyright (c) 2006, Swedish Institute of Computer Science * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  * * @(#)$Id: i2c.c,v 1.2 2007/01/12 13:41:57 bg- Exp $ *//* * Small and portable implementation of a bit-banging I2C bus master. * * The code should port really easily to platforms other than the * msp430 but has some hardcoded constants in it. * * More info at: *   http://i2c-bus.org/ *   http://www.esacademy.com/faq/i2c/ */#include <stdio.h>#include <io.h>#include <contiki.h>#include <dev/spi.h>#include <dev/leds.h>#include "dev/i2c.h"/* * On the Tmote sky access to I2C/SPI/UART0 must always be exclusive. */void     i2c_enable(void);void     i2c_disable(void);int      i2c_start(void);unsigned i2c_read(int send_ack);int      i2c_write(unsigned);void     i2c_stop(void);#define I2C_PxDIR   P3DIR#define I2C_PxIN    P3IN#define I2C_PxOUT   P3OUT#define I2C_PxSEL   P3SEL/* * SDA == P3.1 * SCL == P3.3 */#define SDA       1#define SCL       3#define SDA_0()   (I2C_PxDIR |=  BV(SDA))		/* SDA Output */#define SDA_1()   (I2C_PxDIR &= ~BV(SDA))		/* SDA Input */#define SDA_IS_1  (I2C_PxIN & BV(SDA))#define SCL_0()   (I2C_PxDIR |=  BV(SCL))		/* SCL Output */#define SCL_1()   (I2C_PxDIR &= ~BV(SCL))		/* SCL Input */#define SCL_IS_1  (I2C_PxIN & BV(SCL))/* * Should avoid infinite looping while waiting for SCL_IS_1. xxx/bg */#define SCL_WAIT_FOR_1() do{}while (!SCL_IS_1)#define delay_4_7us() do{ _NOP(); _NOP(); _NOP(); _NOP(); \                          _NOP(); _NOP(); _NOP(); _NOP(); \                          _NOP(); _NOP(); _NOP(); _NOP(); }while(0)#define delay_4us()   do{ _NOP(); _NOP(); _NOP(); _NOP(); \                          _NOP(); _NOP(); _NOP(); _NOP(); \                          _NOP(); _NOP(); }while(0)static unsigned char old_pxsel, old_pxout, old_pxdir;/* * Grab SDA and SCL pins for exclusive use but remember old * configuration so that it may be restored when we are done. */voidi2c_enable(void){  unsigned char sda_scl = BV(SDA)|BV(SCL);  old_pxsel = I2C_PxSEL & sda_scl;  old_pxout = I2C_PxOUT & sda_scl;  old_pxdir = I2C_PxDIR & sda_scl;  spi_busy = 1;  I2C_PxSEL &= ~sda_scl;  I2C_PxOUT &= ~sda_scl;  I2C_PxDIR |=  BV(SCL);		/* SCL Output */  I2C_PxDIR &= ~BV(SDA);		/* SDA Input */}/* * Restore bus to what it was before i2c_enable. * */voidi2c_disable(void){  unsigned char not_sda_scl = ~(BV(SDA)|BV(SCL));  I2C_PxDIR = (I2C_PxDIR & not_sda_scl) | old_pxdir;  I2C_PxOUT = (I2C_PxOUT & not_sda_scl) | old_pxout;  I2C_PxSEL = (I2C_PxSEL & not_sda_scl) | old_pxsel;  spi_busy = 0;}inti2c_start(void){  SDA_1();  SCL_1();#if 1  SCL_WAIT_FOR_1();#else  {    unsigned long n;    for (n = 0; n < 100000 && !SCL_IS_1; n++)      ;    if (!SCL_IS_1)      return -1;  }#endif  delay_4_7us();  SDA_0();  delay_4us();  SCL_0();  return 0;}voidi2c_stop(void){  SDA_0();  delay_4us();  SCL_1();  SCL_WAIT_FOR_1();  SDA_1();}/* * Return true if we received an ACK. */inti2c_write(unsigned _c){  unsigned char c = _c;  unsigned long n;  int i;  int ret;  for (i = 0; i < 8; i++, c <<= 1) {    if (c & 0x80)      SDA_1();    else      SDA_0();    SCL_1();    SCL_WAIT_FOR_1();    SCL_0();  }  SDA_1();  SCL_1();  ret = 0;		   /* Loop waiting for an ACK to arrive. */  for (n = 0; n < 250000; n++) {    if (!SDA_IS_1) {      ret = 1;      break;    }  }  SCL_WAIT_FOR_1();		/* clock stretching? */  SCL_0();  return ret;}unsignedi2c_read(int send_ack){  int i;  unsigned char c = 0x00;  SDA_1();  for (i = 0; i < 8; i++) {    c <<= 1;    SCL_1();    SCL_WAIT_FOR_1();    if (SDA_IS_1)      c |= 0x1;    SCL_0();  }  if (send_ack)    SDA_0();  SCL_1();  SCL_WAIT_FOR_1();  SCL_0();  return c;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -