📄 i2c.c.txt
字号:
00001 /*! \file i2c.c \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */
00002 //*****************************************************************************
00003 //
00004 // File Name : 'i2c.c'
00005 // Title : I2C interface using AVR Two-Wire Interface (TWI) hardware
00006 // Author : Pascal Stang - Copyright (C) 2002-2003
00007 // Created : 2002.06.25
00008 // Revised : 2003.03.02
00009 // Version : 0.9
00010 // Target MCU : Atmel AVR series
00011 // Editor Tabs : 4
00012 //
00013 // This code is distributed under the GNU Public License
00014 // which can be found at http://www.gnu.org/licenses/gpl.txt
00015 //
00016 //*****************************************************************************
00017
00018 #include <avr/io.h>
00019 #include <avr/interrupt.h>
00020
00021 #include "i2c.h"
00022
00023 #include "rprintf.h" // include printf function library
00024 #include "uart2.h"
00025
00026 // Standard I2C bit rates are:
00027 // 100KHz for slow speed
00028 // 400KHz for high speed
00029
00030 //#define I2C_DEBUG
00031
00032 // I2C state and address variables
00033 static volatile eI2cStateType I2cState;
00034 static u08 I2cDeviceAddrRW;
00035 // send/transmit buffer (outgoing data)
00036 static u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
00037 static u08 I2cSendDataIndex;
00038 static u08 I2cSendDataLength;
00039 // receive buffer (incoming data)
00040 static u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
00041 static u08 I2cReceiveDataIndex;
00042 static u08 I2cReceiveDataLength;
00043
00044 // function pointer to i2c receive routine
00045 //! I2cSlaveReceive is called when this processor
00046 // is addressed as a slave for writing
00047 static void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData);
00048 //! I2cSlaveTransmit is called when this processor
00049 // is addressed as a slave for reading
00050 static u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData);
00051
00052 // functions
00053 void i2cInit(void)
00054 {
00055 // set pull-up resistors on I2C bus pins
00056 // TODO: should #ifdef these
00057 sbi(PORTC, 0); // i2c SCL on ATmega163,323,16,32,etc
00058 sbi(PORTC, 1); // i2c SDA on ATmega163,323,16,32,etc
00059 sbi(PORTD, 0); // i2c SCL on ATmega128,64
00060 sbi(PORTD, 1); // i2c SDA on ATmega128,64
00061
00062 // clear SlaveReceive and SlaveTransmit handler to null
00063 i2cSlaveReceive = 0;
00064 i2cSlaveTransmit = 0;
00065 // set i2c bit rate to 100KHz
00066 i2cSetBitrate(100);
00067 // enable TWI (two-wire interface)
00068 sbi(TWCR, TWEN);
00069 // set state
00070 I2cState = I2C_IDLE;
00071 // enable TWI interrupt and slave address ACK
00072 sbi(TWCR, TWIE);
00073 sbi(TWCR, TWEA);
00074 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00075 // enable interrupts
00076 sei();
00077 }
00078
00079 void i2cSetBitrate(u16 bitrateKHz)
00080 {
00081 u08 bitrate_div;
00082 // set i2c bitrate
00083 // SCL freq = F_CPU/(16+2*TWBR))
00084 #ifdef TWPS0
00085 // for processors with additional bitrate division (mega128)
00086 // SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
00087 // set TWPS to zero
00088 cbi(TWSR, TWPS0);
00089 cbi(TWSR, TWPS1);
00090 #endif
00091 // calculate bitrate division
00092 bitrate_div = ((F_CPU/1000l)/bitrateKHz);
00093 if(bitrate_div >= 16)
00094 bitrate_div = (bitrate_div-16)/2;
00095 outb(TWBR, bitrate_div);
00096 }
00097
00098 void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
00099 {
00100 // set local device address (used in slave mode only)
00101 outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) );
00102 }
00103
00104 void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData))
00105 {
00106 i2cSlaveReceive = i2cSlaveRx_func;
00107 }
00108
00109 void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData))
00110 {
00111 i2cSlaveTransmit = i2cSlaveTx_func;
00112 }
00113
00114 inline void i2cSendStart(void)
00115 {
00116 // send start condition
00117 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00118 }
00119
00120 inline void i2cSendStop(void)
00121 {
00122 // transmit stop condition
00123 // leave with TWEA on for slave receiving
00124 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00125 }
00126
00127 inline void i2cWaitForComplete(void)
00128 {
00129 // wait for i2c interface to complete operation
00130 while( !(inb(TWCR) & BV(TWINT)) );
00131 }
00132
00133 inline void i2cSendByte(u08 data)
00134 {
00135 // save data to the TWDR
00136 outb(TWDR, data);
00137 // begin send
00138 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00139 }
00140
00141 inline void i2cReceiveByte(u08 ackFlag)
00142 {
00143 // begin receive over i2c
00144 if( ackFlag )
00145 {
00146 // ackFlag = TRUE: ACK the recevied data
00147 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00148 }
00149 else
00150 {
00151 // ackFlag = FALSE: NACK the recevied data
00152 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00153 }
00154 }
00155
00156 inline u08 i2cGetReceivedByte(void)
00157 {
00158 // retieve received data byte from i2c TWDR
00159 return( inb(TWDR) );
00160 }
00161
00162 inline u08 i2cGetStatus(void)
00163 {
00164 // retieve current i2c status from i2c TWSR
00165 return( inb(TWSR) );
00166 }
00167
00168 void i2cMasterSend(u08 deviceAddr, u08 length, u08* data)
00169 {
00170 u08 i;
00171 // wait for interface to be ready
00172 while(I2cState);
00173 // set state
00174 I2cState = I2C_MASTER_TX;
00175 // save data
00176 I2cDeviceAddrRW = (deviceAddr & 0xFE); // RW cleared: write operation
00177 for(i=0; i<length; i++)
00178 I2cSendData[i] = *data++;
00179 I2cSendDataIndex = 0;
00180 I2cSendDataLength = length;
00181 // send start condition
00182 i2cSendStart();
00183 }
00184
00185 void i2cMasterReceive(u08 deviceAddr, u08 length, u08* data)
00186 {
00187 u08 i;
00188 // wait for interface to be ready
00189 while(I2cState);
00190 // set state
00191 I2cState = I2C_MASTER_RX;
00192 // save data
00193 I2cDeviceAddrRW = (deviceAddr|0x01); // RW set: read operation
00194 I2cReceiveDataIndex = 0;
00195 I2cReceiveDataLength = length;
00196 // send start condition
00197 i2cSendStart();
00198 // wait for data
00199 while(I2cState);
00200 // return data
00201 for(i=0; i<length; i++)
00202 *data++ = I2cReceiveData[i];
00203 }
00204
00205 u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
00206 {
00207 u08 retval = I2C_OK;
00208
00209 // disable TWI interrupt
00210 cbi(TWCR, TWIE);
00211
00212 // send start condition
00213 i2cSendStart();
00214 i2cWaitForComplete();
00215
00216 // send device address with write
00217 i2cSendByte( deviceAddr & 0xFE );
00218 i2cWaitForComplete();
00219
00220 // check if device is present and live
00221 if( inb(TWSR) == TW_MT_SLA_ACK)
00222 {
00223 // send data
00224 while(length)
00225 {
00226 i2cSendByte( *data++ );
00227 i2cWaitForComplete();
00228 length--;
00229 }
00230 }
00231 else
00232 {
00233 // device did not ACK it's address,
00234 // data will not be transferred
00235 // return error
00236 retval = I2C_ERROR_NODEV;
00237 }
00238
00239 // transmit stop condition
00240 // leave with TWEA on for slave receiving
00241 i2cSendStop();
00242 while( !(inb(TWCR) & BV(TWSTO)) );
00243
00244 // enable TWI interrupt
00245 sbi(TWCR, TWIE);
00246
00247 return retval;
00248 }
00249
00250 u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data)
00251 {
00252 u08 retval = I2C_OK;
00253
00254 // disable TWI interrupt
00255 cbi(TWCR, TWIE);
00256
00257 // send start condition
00258 i2cSendStart();
00259 i2cWaitForComplete();
00260
00261 // send device address with read
00262 i2cSendByte( deviceAddr | 0x01 );
00263 i2cWaitForComplete();
00264
00265 // check if device is present and live
00266 if( inb(TWSR) == TW_MR_SLA_ACK)
00267 {
00268 // accept receive data and ack it
00269 while(length > 1)
00270 {
00271 i2cReceiveByte(TRUE);
00272 i2cWaitForComplete();
00273 *data++ = i2cGetReceivedByte();
00274 // decrement length
00275 length--;
00276 }
00277
00278 // accept receive data and nack it (last-byte signal)
00279 i2cReceiveByte(FALSE);
00280 i2cWaitForComplete();
00281 *data++ = i2cGetReceivedByte();
00282 }
00283 else
00284 {
00285 // device did not ACK it's address,
00286 // data will not be transferred
00287 // return error
00288 retval = I2C_ERROR_NODEV;
00289 }
00290
00291 // transmit stop condition
00292 // leave with TWEA on for slave receiving
00293 i2cSendStop();
00294
00295 // enable TWI interrupt
00296 sbi(TWCR, TWIE);
00297
00298 return retval;
00299 }
00300 /*
00301 void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata)
00302 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -