example_280xi2c_eeprom.c
来自「DSP2808例程。TMS320F2808DSP的各个模块的应用例程」· C语言 代码 · 共 687 行 · 第 1/2 页
C
687 行
// Stop I2C when suspended
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}
Uint16 I2CA_WriteData(struct I2CMSG *msg)
{
Uint16 i;
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
if (I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}
// Setup slave address
I2caRegs.I2CSAR = msg->SlaveAddress;
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
// Setup number of bytes to send
// MsgBuffer + Address
I2caRegs.I2CCNT = msg->NumOfBytes+2;
// Setup data to send
I2caRegs.I2CDXR = msg->MemoryHighAddr;
I2caRegs.I2CDXR = msg->MemoryLowAddr;
// for (i=0; i<msg->NumOfBytes-2; i++)
for (i=0; i<msg->NumOfBytes; i++)
{
I2caRegs.I2CDXR = *(msg->MsgBuffer+i);
}
// Send start as master transmitter
I2caRegs.I2CMDR.all = 0x6E20;
return I2C_SUCCESS;
}
Uint16 I2CA_ReadData(struct I2CMSG *msg)
{
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
if (I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}
I2caRegs.I2CSAR = msg->SlaveAddress;
if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP)
{
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR = msg->MemoryHighAddr;
I2caRegs.I2CDXR = msg->MemoryLowAddr;
I2caRegs.I2CMDR.all = 0x2620; // Send data to setup EEPROM address
}
else if(msg->MsgStatus == I2C_MSGSTAT_RESTART)
{
I2caRegs.I2CCNT = msg->NumOfBytes; // Setup how many bytes to expect
I2caRegs.I2CMDR.all = 0x2C20; // Send restart as master receiver
}
return I2C_SUCCESS;
}
interrupt void i2c_int1a_isr(void) // I2C-A
{
Uint16 IntSource, i;
// Read interrupt source
IntSource = I2caRegs.I2CISRC.all;
// Interrupt source = stop condition detected
if(IntSource == I2C_SCD_ISRC)
{
// If completed message was writing data, reset msg to inactive state
if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_WRITE_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
}
else
{
// If a message receives a NACK during the address setup portion of the
// EEPROM read, the code further below included in the register access ready
// interrupt source code will generate a stop condition. After the stop
// condition is received (here), set the message status to try again.
// User may want to limit the number of retries before generating an error.
if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
}
// If completed message was reading EEPROM data, reset msg to inactive state
// and read data from FIFO.
else if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_READ_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
for(i=0; i < I2C_NUMBYTES; i++)
{
CurrentMsgPtr->MsgBuffer[i] = I2caRegs.I2CDRR;
}
{
// Check recieved data
for(i=0; i < I2C_NUMBYTES; i++)
{
if(I2cMsgIn1.MsgBuffer[i] == I2cMsgOut1.MsgBuffer[i])
{
PassCount++;
}
else
{
FailCount++;
}
}
if(PassCount == I2C_NUMBYTES)
{
pass();
}
else
{
fail();
}
}
}
}
} // end of stop condition detected
// Interrupt source = Register Access Ready
// This interrupt is used to determine when the EEPROM address setup portion of the
// read data communication is complete. Since no stop bit is commanded, this flag
// tells us when the message has been sent instead of the SCD flag. If a NACK is
// received, clear the NACK bit and command a stop. Otherwise, move on to the read
// data portion of the communication.
else if(IntSource == I2C_ARDY_ISRC)
{
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CMDR.bit.STP = 1;
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
}
else if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_RESTART;
}
} // end of register access ready
else
{
// Generate some error due to invalid interrupt source
asm(" ESTOP0");
}
// Enable future I2C (PIE Group 8) interrupts
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}
void pass()
{
asm(" ESTOP0");
for(;;);
}
void fail()
{
asm(" ESTOP0");
for(;;);
}
void CH452_I2c_Start()
{
//#ifdef USE_KEY
// DISABLE_INTERRUPT; //禁止键盘中断,防止开始时被CH452中断而进入中断服务程序中的START
//#endif
CH452_SDA_SET; /*发送起始条件的数据信号*/
//CH452_SDA_D_OUT; /* 设置SDA为输出方向 */
CH452_SCL_SET;
//DELAY_1US;
DELAY_1US();
CH452_SDA_CLR; /*发送起始信号*/
//DELAY_1US;
DELAY_1US();
CH452_SCL_CLR; /*钳住I2C总线,准备发送或接收数据 */
//DELAY_1US;
DELAY_1US();
}
void CH452_I2c_Stop()
{
CH452_SDA_CLR;
//CH452_SDA_D_OUT; /* 设置SDA为输出方向 */
//DELAY_1US;
DELAY_1US();
CH452_SCL_SET;
//DELAY_1US;
DELAY_1US();
CH452_SDA_SET; /*发送I2C总线结束信号*/
//DELAY_1US;
DELAY_1US();
//CH452_SDA_D_IN; /* 设置SDA为输入方向 */
//#ifdef USE_KEY
// ENABLE_INTERRUPT;
//#endif
}
void CH452_Write(unsigned char command) //写命令
{
CH452_I2c_Start(); /*启动总线*/
#ifdef ENABLE_2_CH452 // 若有两个CH452并连
CH452_I2c_WrByte(((unsigned char)(command>>7)&0x3E)|0x40); // CH452的ADDR=0时
#else
CH452_I2c_WrByte(((unsigned char)(command>>7)&0x3E)|0x60); // CH452的ADDR=1时(默认)
#endif
//
// DELAY_1US();
//CH452_SDA_SET;
//DELAY_1US;
// DELAY_1US();
//CH452_SCL_SET;
//DELAY_1US;
// DELAY_1US();
//CH452_SCL_CLR;
//DELAY_1US;
DELAY_1US();
//
CH452_I2c_WrByte((unsigned char)command); /*发送数据*/
CH452_I2c_Stop(); /*结束总线*/
}
unsigned char CH452_Read() //读取按键
{
unsigned char key;
CH452_I2c_Start(); /*启动总线*/
CH452_I2c_WrByte(0x6F); // 若有两个CH452并连,当ADDR=0时,此值为0x4F
key=CH452_I2c_RdByte(); /*读取数据*/
CH452_I2c_Stop(); /*结束总线*/
return(key);
}
void CH452_I2c_WrByte(unsigned char c) //写一个字节数据
{
unsigned char i;
//CH452_SDA_D_OUT; /* 设置SDA为输出方向 */
for(i=0;i!=8;i++) // 输出8位数据
{
if(c&0x80) {CH452_SDA_SET;}
else {CH452_SDA_CLR;}
//DELAY_1US;
DELAY_1US();
CH452_SCL_SET;
c<<=1;
//DELAY_1US;
DELAY_1US();
CH452_SCL_CLR;
DELAY_1US();
}
//CH452_SDA_D_IN; /* 设置SDA为输入方向 */
CH452_SDA_SET;
//DELAY_1US;
DELAY_1US();
CH452_SCL_SET; // 接收应答
//DELAY_1US;
DELAY_1US();
CH452_SCL_CLR;
//DELAY_1US;
DELAY_1US();
}
unsigned char CH452_I2c_RdByte() //读一个字节数据
{
unsigned char c,i;
//CH452_SDA_D_IN; /* 设置SDA为输入方向 */
CH452_SDA_SET;
DELAY_1US();
c=0;
for(i=0;i!=8;i++) // 输入8位数据
{
CH452_SCL_SET;
//DELAY_1US;
DELAY_1US();
c<<=1;
if(CH452_SDA_IN) c|=0x01; // 输入1位
CH452_SCL_CLR;
//DELAY_1US;
DELAY_1US();
}
CH452_SDA_SET;
DELAY_1US();
CH452_SCL_SET; // 发出无效应答
//DELAY_1US;
DELAY_1US();
CH452_SCL_CLR;
//DELAY_1US;
DELAY_1US();
return(c);
}
void InitI2CGpio()
{
EALLOW;
GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0; // Enable pullup on GPIO34
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0; // GPIO32 = GPIO32
GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1; // GPIO32 = output
GpioDataRegs.GPBSET.bit.GPIO32 = 1;
GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0; // Enable pullup on GPIO34
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0; // GPIO33 = GPIO33
GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1; // GPIO33 = input
GpioDataRegs.GPBSET.bit.GPIO33 = 1; //
EDIS;
}
//===========================================================================
// No more.
//===========================================================================
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?