[资料分享]
CC2541 I2C EEPROM例程 AT24C512
-
- #include "hal_types.h"
- #include "hal_defs.h"
- #include "ioCC254x_bitdef.h"
- #include <ioCC2541.h>
- #include "i2c.h"
-
- uint8 buf [20] = {8,2,3,4,5};
- uint8 bufr [20] = {0,0,0,0,0};
- void eeprom_test(void)
- {
- uint16 i;
-
- eepromInit(0x50);
- for(i=0;i<40;i++)
- {
- buf[i] = 255-i;
- }
- eepromWrite(0,buf,40);
-
- for(i=0;i<40;i++)
- {
- bufr[i] = 0;
- }
- for(i=0;i<65500;i++);
- eepromRead(0,bufr,20);
- }
- int main( void )
- {
- uint8 i;
- /****************************************************************************
- * Clock setup
- * See basic software example "clk_xosc_cc254x"
- */
-
- // Set system clock source to HS XOSC, with no pre-scaling.
- CLKCONCMD = (CLKCONCMD & ~(CLKCON_OSC | CLKCON_CLKSPD)) | CLKCON_CLKSPD_32M;
- // Wait until clock source has changed
- while (CLKCONSTA & CLKCON_OSC);
- eeprom_test();
- while(1)
- {
-
- }
- }
-
- /* ------------------------------------------------------------------------------------------------
- * Includes
- * ------------------------------------------------------------------------------------------------
- */
- #include "i2c.h"
-
- /* ------------------------------------------------------------------------------------------------
- * Constants
- * ------------------------------------------------------------------------------------------------
- */
- #define I2C_ENS1 BV(6)
- #define I2C_STA BV(5)
- #define I2C_STO BV(4)
- #define I2C_SI BV(3)
- #define I2C_AA BV(2)
- #define I2C_MST_RD_BIT BV(0) // Master RD/WRn bit to be OR'ed with Slave address.
-
- #define I2C_CLOCK_MASK 0x83
-
- #define I2C_PXIFG P2IFG
- #define I2C_IF P2IF
- #define I2C_IE BV(1)
-
- /* ------------------------------------------------------------------------------------------------
- * Typedefs
- * ------------------------------------------------------------------------------------------------
- */
-
- typedef enum
- {
- // HAL_I2C_MASTER mode statuses.
- mstStarted = 0x08,
- mstRepStart = 0x10,
- mstAddrAckW = 0x18,
- mstAddrNackW = 0x20,
- mstDataAckW = 0x28,
- mstDataNackW = 0x30,
- mstLostArb = 0x38,
- mstAddrAckR = 0x40,
- mstAddrNackR = 0x48,
- mstDataAckR = 0x50,
- mstDataNackR = 0x58,
- } i2cStatus_t;
-
- /* ------------------------------------------------------------------------------------------------
- * Macros
- * ------------------------------------------------------------------------------------------------
- */
-
- #define I2C_WRAPPER_DISABLE() st( I2CWC = 0x00; )
- #define I2C_CLOCK_RATE(x) st( I2CCFG &= ~I2C_CLOCK_MASK; \
- I2CCFG |= x; )
- #define I2C_SET_NACK() st( I2CCFG &= ~I2C_AA; )
- #define I2C_SET_ACK() st( I2CCFG |= I2C_AA; )
-
- // Enable I2C bus
- #define I2C_ENABLE() st( I2CCFG |= (I2C_ENS1); )
- #define I2C_DISABLE() st( I2CCFG &= ~(I2C_ENS1); )
-
- // Must clear SI before setting STA and then STA must be manually cleared.
- #define I2C_STRT() st ( \
- I2CCFG &= ~I2C_SI; \
- I2CCFG |= I2C_STA; \
- while ((I2CCFG & I2C_SI) == 0); \
- I2CCFG &= ~I2C_STA; \
- )
-
- // Must set STO before clearing SI.
- #define I2C_STOP() st ( \
- I2CCFG |= I2C_STO; \
- I2CCFG &= ~I2C_SI; \
- while ((I2CCFG & I2C_STO) != 0); \
- )
-
- // Stop clock-stretching and then read when it arrives.
- #define I2C_READ(_X_) st ( \
- I2CCFG &= ~I2C_SI; \
- while ((I2CCFG & I2C_SI) == 0); \
- (_X_) = I2CDATA; \
- )
-
- // First write new data and then stop clock-stretching.
- #define I2C_WRITE(_X_) st ( \
- I2CDATA = (_X_); \
- I2CCFG &= ~I2C_SI; \
- while ((I2CCFG & I2C_SI) == 0); \
- )
-
-
- /* ------------------------------------------------------------------------------------------------
- * Local Variables
- * ------------------------------------------------------------------------------------------------
- */
- static uint8 i2cAddr; // Target Slave address pre-shifted up by one leaving RD/WRn LSB as zero.
-
-
-
- /**************************************************************************************************
- * @fn i2cMstStrt
- *
- * @brief Attempt to send an I2C bus START and Slave Address as an I2C bus Master.
- *
- * input parameters
- *
- * @param RD_WRn - The LSB of the Slave Address as Read/~Write.
- *
- * @return The I2C status of the START request or of the Slave Address Ack.
- */
- static uint8 i2cMstStrt(uint8 RD_WRn)
- {
- I2C_STRT();
-
- if (I2CSTAT == mstStarted) /* A start condition has been transmitted */
- {
- I2C_WRITE(i2cAddr | RD_WRn);
- }
-
- return I2CSTAT;
- }
- /**************************************************************************************************
- * @fn HalI2CInit
- *
- * @brief Initialize the I2C bus as a Master.
- *
- * input parameters
- *
- * @param address - I2C slave address.
- * @param clockRate - I2C clock rate.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- */
- void eepromInit(uint8 address)
- {
- i2cAddr = address << 1;
-
- I2C_WRAPPER_DISABLE();
- I2CADDR = 0; // no multi master support at this time
- I2C_CLOCK_RATE(i2cClock_123KHZ);
- I2C_ENABLE();
- }
-
- /**************************************************************************************************
- * @fn HalI2CRead
- *
- * @brief Read from the I2C bus as a Master.
- *
- * input parameters
- *
- * @param len - Number of bytes to read.
- * @param pBuf - Pointer to the data buffer to put read bytes.
- *
- * output parameters
- *
- * None.
- *
- * @return The number of bytes successfully read.
- */
- bool eepromRead(uint16 addr, uint8 *pBuf, uint16 len)
- {
- uint8 cnt = 0;
- eepromWrite(0,(uint8 *)(&addr),0);
- if (i2cMstStrt(I2C_MST_RD_BIT) != mstAddrAckR)
- {
- len = 0;
- }
-
- // All bytes are ACK'd except for the last one which is NACK'd. If only
- // 1 byte is being read, a single NACK will be sent. Thus, we only want
- // to enable ACK if more than 1 byte is going to be read.
- if (len > 1)
- {
- I2C_SET_ACK();
- }
-
- while (len > 0)
- {
- // slave devices require NACK to be sent after reading last byte
- if (len == 1)
- {
- I2C_SET_NACK();
- }
-
- // read a byte from the I2C interface
- I2C_READ(*pBuf++);
- cnt++;
- len--;
-
- if (I2CSTAT != mstDataAckR)
- {
- if (I2CSTAT != mstDataNackR)
- {
- // something went wrong, so don't count last byte
- cnt--;
- }
- break;
- }
- }
- I2C_STOP();
-
- return cnt;
- }
-
- /**************************************************************************************************
- * @fn HalI2CWrite
- *
- * @brief Write to the I2C bus as a Master.
- *
- * input parameters
- *
- * @param len - Number of bytes to write.
- * @param pBuf - Pointer to the data buffer to write.
- *
- * output parameters
- *
- * None.
- *
- * @return The number of bytes successfully written.
- */
- uint8 eepromWrite(uint16 addr, uint8 *pBuf, uint16 len)
- {
- if (i2cMstStrt(0) != mstAddrAckW)
- {
- len = 0;
- }
-
- I2C_WRITE(addr>>8);
- I2C_WRITE(addr);
- // for (uint8 cnt = 0; cnt < 2; cnt++)
- // {
- // I2C_WRITE(0);
- //
- // if (I2CSTAT != mstDataAckW)
- // {
- // if (I2CSTAT == mstDataNackW)
- // {
- // len = cnt + 1;
- // }
- // else
- // {
- // len = cnt;
- // }
- // break;
- // }
- // }
-
- for (uint8 cnt = 0; cnt < len; cnt++)
- {
- I2C_WRITE(*pBuf++);
-
- if (I2CSTAT != mstDataAckW)
- {
- if (I2CSTAT == mstDataNackW)
- {
- len = cnt + 1;
- }
- else
- {
- len = cnt;
- }
- break;
- }
- }
-
- I2C_STOP();
-
- return len;
- }
-
本帖最后由 littleshrimp 于 2015-12-8 14:34 编辑
暂无评论,赶紧抢沙发吧