📄 iic_avr.c
字号:
///////////////////////////////////////////
// IIC_AVR.C
// Function: IIC driver for atmel mega16
// Create : Guobg
// Date : 20060113
// Revision: 0.0
///////////////////////////////////////////
// Modify History
//
///////////////////////////////////////////
#include "IIC_AVR.H"
struct IIC_BUFFER IIC_Buffer_In; // IIC Input Buffer
struct IIC_BUFFER IIC_Buffer_Out; // IIC Output Buffer
//U8 ucIICSLA; // IIC Master Mode Destination Address,R/W
U8 ucIICTimeoutCount; // IIC Time out counter
U8 ucIICMode; // IIC Mode
U8 ucIICError; // IIC Error code
U8 ucIICAddress; // Myself IIC Address
BP_CODE U8 IIC_BaudrateConfig[2][2] =
{
{ IIC_BAUDRATE_TWBR_200K, IIC_BAUDRATE_TWPS_NODIV }
, // Config for 200K
{ IIC_BAUDRATE_TWBR_100K, IIC_BAUDRATE_TWPS_NODIV } // Config for 100K
};
///////////////////////////////////////////
// IIC_Init
// Function: Initlize IIC interface
// Input:
// ucSlaveAddr: SlaveAddr (1--127)
// ucBaudrate: Baudrate index see IIC.H
// Output:
// NONE
///////////////////////////////////////////
void IIC_Init(U8 ucSlaveAddr, U8 ucBaudrate)
{
unsigned char i;
//Initlize baudrate
TWBR = IIC_BaudrateConfig[ucBaudrate][0];
TWSR = IIC_BaudrateConfig[ucBaudrate][1];
//Set IIC Slave address, enable broadcast respond
TWAR = (ucSlaveAddr << 1 | _BV(TWGCE));
ucIICMode = IIC_MODE_SLAVE_RECEIVE; //Default mode
ucIICError = IIC_ERROR_NOERROR;
//Clear IIC buffer
for(i = 0; i < IIC_MAX_BUFFER_LEN; i++)
{
IIC_Buffer_In.IIC_BUFFER_UNION.ucData[i] = 0;
IIC_Buffer_Out.IIC_BUFFER_UNION.ucData[i] = 0;
}
//Clear buffer status
IIC_Buffer_In.ucReadP = 0;
IIC_Buffer_In.ucWriteP = 0;
IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 0; //In Buffer Disable Access
IIC_Buffer_Out.ucReadP = 0;
IIC_Buffer_Out.ucWriteP = 0;
IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1; //Out Buffer Enable Access
// Clear TWINT , enabel TWI ack ,enable TWI port ,enable TWI Interrupt
TWCR = (_BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE));
}
///////////////////////////////////////////
// IIC_handle
// Function: IIC Interrupt handler
// Input:
// NONE
// Output:
// NONE
///////////////////////////////////////////
#ifdef ICC_AVR
void IIC_handler (void)
#endif
#ifdef GCC_AVR
SIGNAL(SIG_2WIRE_SERIAL)
#endif
{
U8 ucTwiStatus;
ucTwiStatus = (TWSR & TW_NO_INFO);
switch(ucTwiStatus)
{
case TW_START: // A START has transmit to IIC bus
case TW_REP_START: //A REPEAT START has transmit to IIC bus
ucIICMode = IIC_MODE_MASTER_TRANSMIT;
IIC_SLA; //Send SLA+R/W to IIC bus
// cbi(TWCR,TWSTA); //Clear TWSTA
TWCR = (_BV(TWEN) | _BV(TWEA) | _BV(TWIE) | _BV(TWINT));
break;
case TW_MT_SLA_ACK:
case TW_MT_DATA_ACK: //Send data to Slave IIC device
if(IIC_Buffer_Out.ucWriteP != IIC_Buffer_Out.ucReadP)
{ // Data transmit not finish
IIC_BUFFER_TO_BUS;
TWCR = (_BV(TWEN) | _BV(TWEA) | _BV(TWIE) | _BV(TWINT));
break;
} else
{
IIC_STOP; //Data transmit finish,Release IIC bus
//Enable user program write a new command to IIC transmit buffer
IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
IIC_Buffer_Out.ucReadP = 0;
IIC_Buffer_Out.ucWriteP = 0;
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
break;
}
case TW_MT_SLA_NACK: //Slave IIC device did not return a NACK during
//address phase
IIC_STOP; //Slave address error,Release IIC bus
//Enable user program write a new command to IIC transmit buffer
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
ucIICError = IIC_ERROR_NOT_ACK_SLA;
IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
IIC_Buffer_Out.ucReadP = 0;
IIC_Buffer_Out.ucWriteP = 0;
break;
case TW_MT_DATA_NACK: //Slave IIC device did not return a NACK during
//data transfer phase
IIC_STOP; //Data transmit error,Release IIC bus
//Enable user program write a new command to IIC transmit buffer
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
ucIICError = IIC_ERROR_NOT_ACK_DATA;
IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
IIC_Buffer_Out.ucReadP = 0;
IIC_Buffer_Out.ucWriteP = 0;
break;
case TW_MT_ARB_LOST:
//Enable user program write a new command to IIC transmit buffer
if(ucIICMode == IIC_MODE_MASTER_TRANSMIT)
{
IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
IIC_Buffer_Out.ucReadP = 0;
IIC_Buffer_Out.ucWriteP = 0;
} else
{
IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 0;
IIC_Buffer_In.ucReadP = 0;
IIC_Buffer_In.ucWriteP = 0;
}
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
ucIICError = IIC_ERROR_ARBITRATION_LOST;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
break;
///////////////////////////////////////////
// Slave Recieve Mode
///////////////////////////////////////////
case TW_SR_SLA_ACK:
case TW_SR_GCALL_ACK:
case TW_SR_ARB_LOST_SLA_ACK:
case TW_SR_ARB_LOST_GCALL_ACK:
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
IIC_Buffer_In.ucWriteP = 0;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWIE) | _BV(TWEA));
break;
case TW_SR_DATA_ACK:
case TW_SR_GCALL_DATA_ACK:
if(IIC_Buffer_In.ucWriteP < IIC_MAX_BUFFER_LEN)
{
IIC_BUS_TO_BUFFER;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWIE) | _BV(TWEA));
} else
{ //Buffer Overlow
// cbi(TWCR,TWEA); //Clear TWEA Disable data ACK and address ACK
TWCR = _BV(TWINT);
ucIICError = IIC_ERROR_BUFFER_OVERLOW;
}
break;
case TW_SR_DATA_NACK:
case TW_SR_GCALL_DATA_NACK:
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
break;
case TW_SR_STOP:
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
// sbi(TWCR,TWEA); //Set TWEA Enable data ACK and address ACK
if(ucIICError == IIC_ERROR_NOERROR)
{
IIC_Buffer_In.ucReadP = 0;
IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 1;
}
break;
///////////////////////////////////////////
// Master Recieve Mode
///////////////////////////////////////////
case TW_MR_SLA_ACK:
ucIICMode = IIC_MODE_MASTER_RECEIVE;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
case TW_MR_DATA_ACK: //Recieve data from slave IIC device
if(IIC_Buffer_In.ucWriteP != IIC_Buffer_In.ucReadP - 1) //ucReadP must initlize
//with Bytes to read before
//Call IICMasrRecieve
{ // Not last byte to recieve
IIC_BUS_TO_BUFFER;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
break;
} else
{ //Last byte has come to IIC Bus
IIC_BUS_TO_BUFFER;
TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWIE));
// cbi(TWCR,TWEA); //Clear TWEA send NACK to finish recieve
break;
}
case TW_MR_SLA_NACK: //Slave IIC device did not return a NACK during
//address phase
IIC_STOP; //Slave address error,Release IIC bus
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
ucIICError = IIC_ERROR_NOT_ACK_SLA;
IIC_Buffer_In.ucReadP = 0;
IIC_Buffer_In.ucWriteP = 0;
break;
case TW_MR_DATA_NACK:
IIC_STOP;
// sbi(TWCR,TWEA); //Set TWEA to enable ACK
if(IIC_Buffer_In.ucReadP == IIC_Buffer_In.ucWriteP)
{ //Data receive success
//Enable user program get command from IIC recieve buffer
IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 1;
ucIICError = IIC_ERROR_NOERROR;
} else
{
ucIICError = IIC_ERROR_NOT_ACK_DATA;
}
IIC_Buffer_In.ucWriteP = 0;
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
break;
//Same as TW_MT_ARB_LOST
// case TW_MR_ARB_LOST:
// ucIICMode=IIC_MODE_SLAVE_RECEIVE;
// ucIICError=IIC_ERROR_ARBITRATION_LOST;
// IIC_Buffer_In.ucReadP=0;
// IIC_Buffer_In.ucWriteP=0;
// break;
///////////////////////////////////////////
// Slave Transmit Mode
///////////////////////////////////////////
case TW_ST_SLA_ACK:
ucIICMode = IIC_MODE_SLAVE_TRANSMIT;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
case TW_ST_DATA_ACK:
if(IIC_Buffer_Out.ucReadP != IIC_Buffer_Out.ucWriteP)
{ // Data transmit not finish
IIC_BUFFER_TO_BUS;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
break;
}
// Buffer Empty!!
case TW_ST_ARB_LOST_SLA_ACK:
case TW_ST_DATA_NACK:
case TW_ST_LAST_DATA:
//Transfer complet
IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
IIC_Buffer_Out.ucReadP = 0;
IIC_Buffer_Out.ucWriteP = 0;
ucIICMode = IIC_MODE_SLAVE_RECEIVE;
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
break;
case TW_BUS_ERROR:
case TW_NO_INFO:
default:
TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
break;
}
// TWCR |= _BV(TWINT); //Write 1 to Clear TWINT
}
///////////////////////////////////////////
//U8 I2C_Send(U8 I2C_Addr, U8* I2C_MsgData , U8 MsgDataLen, U8 s_Timeout )
//其中U8 为 unsigned char。
//参数说明:
//I2C_Addr:发送的目标地址,每个板卡都应该有唯一的I2C通讯地址。
//I2C_MsgData:存放消息数据的缓冲区。
//Msg_DataLen:发送消息的数据长度。
//S_Timeout:发送消息超时的时间,单位为毫秒(ms)。
//返回值:是否发送成功,0:成功;~0:错误代码
///////////////////////////////////////////
U8 I2C_Send(U8 I2C_Addr, U8 *I2C_MsgData, U8 MsgDataLen, U8 s_Timeout)
{
return 0;
}
///////////////////////////////////////////
//U8 I2C_Rcvd(U8 * I2C_MsgData ,U8 * MsgDataLen ,U8 r_Timeout)
//I2C_MsgData:接收消息数据的缓冲区。
//Msg_DataLen:接收消息的数据长度。
//r_Timeout:接收消息超时的时间,单位为毫秒(ms)。
//返回值:是否接收成功,0:成功;~0:错误代码
///////////////////////////////////////////
I8 I2C_Rcvd(U8 *I2C_MsgData, U8 *MsgDataLen, U8 r_Timeout)
{
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -