#define I2C0SCL_PERIPH (SYSCTL_PERIPH_GPIOB)
#define I2C0SCL_PORT (GPIO_PORTB_BASE)
#define I2C0SCL_PIN (GPIO_PIN_2)
#define I2C0SDA_PERIPH (SYSCTL_PERIPH_GPIOB)
#define I2C0SDA_PORT (GPIO_PORTB_BASE)
#define I2C0SDA_PIN (GPIO_PIN_3)
/*--------------------------------------------------------------------
函数功能: 机器周期延时
输入说明:
返回 值 :
说 明:
44.4M j=100时是360us
j=10时是40us
j=2时是12us
不用j时。是4.8us,读写也正确
--------------------------------------------------------------------*/
void DelayNop(unsigned int n)
{
uint i,j;
for (i = 0; i<n; i++)
{
//for(j=0; j<2; j++)
WDR();
}
}
/*--------------------------------------------------------------------
函数功能:
输入说明:
返回 值 :
说 明:
--------------------------------------------------------------------*/
void I2CStart(void)
{
//SETBIT(I2C_DIR2,SDA2); // Set SDA to output
//SETBIT(I2C_DIR2,SCL2); // Set SCL to output
SysCtlPeripheralEnable(I2C0SDA_PERIPH);
GPIOPinTypeGPIOOutput(I2C0SDA_PORT, I2C0SDA_PIN);
GPIOPadConfigSet(I2C0SDA_PORT, I2C0SDA_PIN, GPIO_STRENGTH_4MA,
GPIO_PIN_TYPE_STD_WPU);
SysCtlPeripheralEnable(I2C0SCL_PERIPH);
GPIOPinTypeGPIOOutput(I2C0SCL_PORT, I2C0SCL_PIN);
GPIOPadConfigSet(I2C0SCL_PORT, I2C0SCL_PIN, GPIO_STRENGTH_4MA,
GPIO_PIN_TYPE_STD_WPU);
//SETBIT(I2C_PORT2,SDA2); // Set SDA High
//SETBIT(I2C_PORT2,SCL2); // Set SCL High
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, I2C0SDA_PIN);
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, I2C0SCL_PIN);
DelayNop(40);
//SDA从高电平到低电平至少时间
///1.8V~2.5V 4us
///4.5V~5.5V 0.6us
//CLEARBIT(I2C_PORT2,SDA2); // Clear SDA
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, 0);
DelayNop(20);
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
DelayNop(40);
//SCL时钟低电平至少时间
///1.8V~2.5V 4.7us
///4.5V~5.5V 1.2us
//SCL时钟高电平至少时间
///1.8V~2.5V 4us
///4.5V~5.5V 0.6us
}
/*--------------------------------------------------------------------
函数功能:
输入说明:
返回 值 :
说 明:
--------------------------------------------------------------------*/
void I2CStop(void)
{
//SETBIT(I2C_DIR2,SDA2); // Set SDA to output
//SETBIT(I2C_DIR2,SCL2); // Set SCL to output
//SysCtlPeripheralEnable(I2C0SDA_PERIPH);
//GPIOPinTypeGPIOOutput(I2C0SDA_PORT, I2C0SDA_PIN);
//SysCtlPeripheralEnable(I2C0SCL_PERIPH);
//GPIOPinTypeGPIOOutput(I2C0SCL_PORT, I2C0SCL_PIN);
//CLEARBIT(I2C_PORT2,SDA2); // Clear SDA
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, 0);
DelayNop(10);
//SETBIT(I2C_PORT2,SCL2); // Set SCL High
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, I2C0SCL_PIN);
DelayNop(20);
//SETBIT(I2C_PORT2,SDA2); // Set SDA High
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, I2C0SDA_PIN);
DelayNop(40);
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL
//GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
//nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();
//nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();
}
/*--------------------------------------------------------------------
函数功能: 写完8个位后,第9位就是I2C应答信号为低
输入说明:
返回 值 :
说 明:
--------------------------------------------------------------------*/
unsigned char I2CRecAck(void)
{
unsigned char Ackn = 0; // Temp RAM for Ackn flag
//CLEARBIT(I2C_DIR2,SDA2); // Set SDA to input
//CLEARBIT(I2C_PORT2,SCL2);
SysCtlPeripheralEnable(I2C0SDA_PERIPH);
GPIOPinTypeGPIOInput(I2C0SDA_PORT, I2C0SDA_PIN);
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
DelayNop(20);
//SETBIT(I2C_PORT2,SCL2); // Clock the ACK bit
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, I2C0SCL_PIN);
DelayNop(2);
//if ( CHECKBIT( I2C_IN2,SDA2 ) ) Ackn = 1; // Check the ACK bit on SDA
if (GPIOPinRead(I2C0SDA_PORT, I2C0SDA_PIN)) Ackn = 1;
DelayNop(38);
SysCtlPeripheralEnable(I2C0SDA_PERIPH);
GPIOPinTypeGPIOOutput(I2C0SDA_PORT, I2C0SDA_PIN);
//CLEARBIT(I2C_PORT2,SCL2); // Clear the clock
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, I2C0SDA_PIN);// Set SDA to out
DelayNop(120);
return Ackn; // Return our ACK bit
}
/*--------------------------------------------------------------------
函数功能:
输入说明:
返回 值 :
说 明:
--------------------------------------------------------------------*/
void I2CAck(void)
{
//SETBIT(I2C_DIR2,SDA2); // Set SDA to output
//SETBIT(I2C_DIR2,SCL2); // Set SCL to output
//SysCtlPeripheralEnable(I2C0SDA_PERIPH);
//GPIOPinTypeGPIOOutput(I2C0SDA_PORT, I2C0SDA_PIN);
//SysCtlPeripheralEnable(I2C0SCL_PERIPH);
//GPIOPinTypeGPIOOutput(I2C0SCL_PORT, I2C0SCL_PIN);
//nop();
//CLEARBIT(I2C_PORT2,SDA2); // Clear SDA
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, 0);
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
//SETBIT(I2C_PORT2,SCL2); // Set SCL High
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, I2C0SCL_PIN);
DelayNop(40);
//CLEARBIT(I2C_PORT2,SCL2);
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
}
/*--------------------------------------------------------------------
函数功能: I2C不应答
输入说明:
返回 值 :
说 明:
--------------------------------------------------------------------*/
void I2CNoAck(void)
{
//SETBIT(I2C_PORT2,SDA2); // Set SDA High
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, I2C0SDA_PIN);
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
DelayNop(20);
//SETBIT(I2C_PORT2,SCL2); // Set SCL High
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, I2C0SCL_PIN);
DelayNop(40);
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
DelayNop(20);
}
/*--------------------------------------------------------------------
函数功能:
输入说明:
返回 值 :
说 明:
--------------------------------------------------------------------*/
void I2CSendByte(unsigned char byte)
{
unsigned char i;
//SETBIT(I2C_DIR2,SDA2); // Set SDA to output
//SETBIT(I2C_DIR2,SCL2); // Set SCL to output
for (i = 0; i < 8; i++) // Loop for our 8 bits
{
if((byte & 0x80) == 0x80)
//SETBIT(I2C_PORT2, SDA2); // Set I2C SDA PIN
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, I2C0SDA_PIN);
else
//CLEARBIT(I2C_PORT2,SDA2); // Clear I2C SDA PIN
GPIOPinWrite(I2C0SDA_PORT, I2C0SDA_PIN, 0);
DelayNop(20);
//CLEARBIT(I2C_PORT2,SCL2);
//GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
//SETBIT(I2C_PORT2,SCL2); // Set SCL High, Clock data
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, I2C0SCL_PIN);
DelayNop(40);
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL 不能换位置
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
DelayNop(20);
byte = byte << 1; // Shift data in buffer right one
}
}
/*--------------------------------------------------------------------
函数功能:
输入说明:
返回 值 :
说 明:
--------------------------------------------------------------------*/
unsigned char I2CReceiveByte(void)
{
unsigned char i,buff = 0;
//SETBIT(I2C_DIR2,SDA2); // Set SDA to output
//CLEARBIT(I2C_DIR2,SDA2); // Set SDA to input
SysCtlPeripheralEnable(I2C0SDA_PERIPH);
GPIOPinTypeGPIOInput(I2C0SDA_PORT, I2C0SDA_PIN);
for (i = 0; i < 8; i++)
{
buff = buff << 1;
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
DelayNop(40);
//SETBIT(I2C_PORT2,SCL2); // Set SCL High,Clock bit out
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, I2C0SCL_PIN);
//nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop(); // Read data on SDA pin
//if (CHECKBIT(I2C_IN2,SDA2))
if (GPIOPinRead(I2C0SDA_PORT, I2C0SDA_PIN))
buff = buff | 0x01;
//CLEARBIT(I2C_PORT2,SCL2); // Clear SCL
GPIOPinWrite(I2C0SCL_PORT, I2C0SCL_PIN, 0);
}
SysCtlPeripheralEnable(I2C0SDA_PERIPH);
GPIOPinTypeGPIOOutput(I2C0SDA_PORT, I2C0SDA_PIN);
GPIOPadConfigSet(I2C0SDA_PORT, I2C0SDA_PIN, GPIO_STRENGTH_4MA,
GPIO_PIN_TYPE_STD_WPU);
return buff; // Return our I2C byte
}
/**************24XX读写主函数*****************************************
DataBuff 为读写数据输入/输出缓冲区的首址
ByteQuantity 为要读写数据的字节数量
Address 为EEPROM的片内地址
ControlByte 为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,
表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;
EEPROM_Type 为枚举变量,需为M2401至M24256中的一种,分别对应24C01至24C256;
函数返回值: 位变量,1=次操作失效,0=操作成功;
ErrorCount 为允许最大次数,若出现ErrorCount次操作失效后,则函数中止操作,并返回1
SDA和SCL由用户自定义,这里暂定义为P0^0和P0^1;
其余的用户不用管,只要把只子程序放在你的程序中并调用它就可以了;
jiao注:器件型号,页大小。
24C01C 16 字节
24C02C 16 字节
24LC04B 16 字节
24LC08B 16 字节
24LC16B 16 字节
24LC32A 32 字节
24LC64 32 字节
24C256页写容量:64字节
*******************************************************************************/
unsigned char RW24XX(unsigned char *DataBuff, unsigned int ByteQuantity, unsigned int Address,unsigned char ControlByte)
{
unsigned char j,i=3;
unsigned char errorflag=1;
while(i--)
{
I2CStart();
I2CSendByte(ControlByte&0xfe);
if(I2CRecAck()== 1)
{
UARTprintf("I2CRecAck error\r\n");
continue;
}
//if(EEPROM_Type>M2416)
//{
// I2CSendByte((unsigned char)(Address>>8));
// if(I2CRecAck()== 1) continue;
//}
I2CSendByte((unsigned char)Address);
if(I2CRecAck()==1) continue;
if((ControlByte&0x01)== 0)
{
j=ByteQuantity;
errorflag=0; //********clr errorflag
while(j--)
{
I2CSendByte(*DataBuff++);
if(I2CRecAck()== 0) continue;
errorflag=1;
//Delay_E(1000);
break;
}
if(errorflag==1) continue;
break;
}
else
{
I2CStart();
I2CSendByte(ControlByte);
if(I2CRecAck()== 1) continue;
while(--ByteQuantity)
{
*DataBuff++=I2CReceiveByte();
I2CAck();
}
*DataBuff=I2CReceiveByte(); //read last byte data
I2CNoAck();
errorflag=0;
break;
}
}
I2CStop();
if((ControlByte&0x01)== 0)
{
for (i=0; i<80; i++)
{
DelayNop(40);//一定要.要不然在写后马上又读会不成功
}
}
return(errorflag);
}
文章评论(0条评论)
登录后参与讨论