📄 iic.c
字号:
#include <msp430xe42x.h>
#include "IIC.h"
#include "hardware.h"
// important
// all the delay are set with MCLK = 4MHZ.
unsigned char RXTXI2C;
//-------------------------------------------------------------------------------
// Start of subroutines to communicate with EEPROM via I2C
//-------------------------------------------------------------------------------
/* This delay is needed for EEPROMs */
void delay(int i)
{
for ( ; i; i--)
{
_NOP();
_NOP();
_NOP();
_NOP();
}
}
//-------------------------------------------------------------------------------
void iic_start(void) // Set up start condition for I2C
{
/* Send a start to the EEPROM */
/* A start is the data bit falling while the clock is high */
P1DIR &= ~SDA;
delay(2); //At least ??? 1.9祍
P1DIR &= ~SCL;
delay(5); //At least 4.7us
P1DIR |= SDA; // Set to output, data low so SDA = 0
delay(5); //At least 4.7us
P1DIR |= SCL; // Set to output, data low so SCL = 0
}
//-------------------------------------------------------------------------------
void iic_stop(void) // Send I2C stop command
{
/* Send a stop to the EEPROM */
/* A stop is the data bit rising while the clock is high */
P1DIR |= SDA; // Set to output, data low so SCA = 0
delay(2);
P1DIR &= ~SCL; // Set to input, SDL = 1 due to pull-up
delay(5);
P1DIR &= ~SDA; // Set to input, SDA = 1 due to pull-up
delay(5);
P1DIR |= SCL;
}
/************************************************************************
*** iic_send ***
************************************************************************/
int iic_send(unsigned char data)
{
int i;
/* Send 8 bits of data */
P1DIR |= SCL;
for (i = 8; i > 0; i--)
{
/* The data can now change without delay */
if (data & 0x80)
P1DIR &= ~SDA;
else
P1DIR |= SDA;
data <<= 1;
/* Pulse the clock high while the data bit is steady */
delay(5); //At least 4.7us
P1DIR &= ~SCL;
delay(5); //At least 4.7us
P1DIR |= SCL;
}
/* Check the acknowledgement from the EEPROM */
/* Pulse the clock high, and see what the device says while the clock is high */
delay(5);
P1DIR &= ~SDA;
delay(5);
P1DIR &= ~SCL;
delay(5);
i = P1IN & SDA;
P1DIR |= SCL;
delay(4);
return i;
}
////////////////////////////////////////////////////////////////////////////////////////////
/************************************************************************
*** iic_receive ***
************************************************************************/
unsigned char iic_receive(int ok)
{
unsigned char data;
int i;
/* Get 8 bits of data */
P1DIR &= ~SDA; //Input
data = 0;
for (i = 8; i > 0; i--)
{
P1DIR &= ~SCL;
delay(5); //At least 4.7us
data <<= 1;
if (P1IN & SDA)
data |= 0x01;
P1DIR |= SCL;
delay(5); //At least 4.7us
}
/* Send the acknowledgement to the EEPROM */
if (ok)
P1DIR |= SDA;
else
P1DIR &= ~SDA;
delay(4);
P1DIR &= ~SCL;
delay(4);
P1DIR |= SCL;
P1DIR &= ~SDA;
return data;
}
/************************************************************************
*** test_SDA ***
************************************************************************/
int test_SDA(void)
{
int i;
iic_stop();
P1DIR &= ~SDA;
delay(4);
for (i = 16; i > 0; i--)
{
delay(5);
if (!(P1IN & SDA))
break;
}
return i;
}
int iicEEPROM_init(void)
{
int i;
/* While idling, the EEPROM clock should be low */
P1DIR |= SCL;
/* If we happen to have restarted in the middle of a read from
the EEPROM/FRAM, we need to regain control of the device. If we
give it enough clocks, and do no acknowledge it we should get out
of any odd conditions. Then we do a stop, and we should be OK. If
the device was mid write when the restart occurred we cannot really
act in a clean way. */
delay(5); //At least 4.7us
for (i = 0; i < 16; i++)
{
P1DIR &= ~SCL;
delay(5); //At least 4.7us
P1DIR |= SCL;
delay(5); //At least 4.7us
}
iic_stop();
return 0;
}
/************************************************************************
*** iic_EEPROM_read ***
************************************************************************/
int iicEEPROM_read(unsigned int addr)
{
int i;
delay(5);
iicEEPROM_init();
for (i = 0; i < MAX_IIC_TRIES; ++i)
{
if (i)
{
/* Read FALSE, retry */
if (test_SDA())
continue;
}
iic_start(); //start
if (iic_send(0xA0 | ((unsigned char)(addr/0x100)*2)) || iic_send(addr))
continue;
iic_start();
if (iic_send(0xA1 | ((unsigned char)(addr/0x100)*2)))
continue;
RXTXI2C = iic_receive(TRUE);
iic_stop();
return TRUE;
}
iic_stop();
return FALSE;
}
/************************************************************************
*** iicEEPROM_write ***
************************************************************************/
int iicEEPROM_write(unsigned int addr, unsigned char dat)
{
int i;
/* If the write spreads across pages in the EEPROM, we need to split the write
into sections. */
//delay(5);
iicEEPROM_init();
for (i = 0; i < MAX_IIC_TRIES; ++i)
{
if (i)
{
/* Write FALSE, retry */
if (test_SDA())
continue;
}
iic_start();
if (iic_send(0xA0 | ((unsigned char)(addr/0x100)*2)) || iic_send(addr))
continue;
if (iic_send(dat)) break;
}
iic_stop();
if (i >= MAX_IIC_TRIES)
return 0;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -