|
由于最近项目用到,特此传上来供童鞋们参考以及共同学习。
//imitate_i2c.h
#ifndef __IMITATE_I2C_H__
#define __IMITATE_I2C_H__
#include<iom64v.h>
#include<macros.h>
#include "TypeDefs.h"
#ifdef __IMITATE_I2C_C
#define IMITATE_I2C
#else
#define IMITATE_I2C extern
#endif
#define INPUT 0
#define OUTPUT 1
#define _BIT0 0x01 //0000 0001
#define _nop_() asm("nop")
#define CHANGE_PIN_DIR(DDRX, BITX,STATUS) /*\
{ \
if(STATUS==0)\
{ \
DDRX&=~BIT(BITX);\
} \
else if(STATUS==1)\
DDRX|=BIT(BITX);\
}*/
//control 24C1024 used port
#define _24C1024_DDR DDRG
#define _24C1024_PORT PORTG
#define _24C1024_PINX PING
#define OSCL 0
#define OSDA 1
#define _24C1024_I2C_PORT_INIT() \
_24C1024_DDR&=~(BIT(OSCL)|BIT(OSDA));\
_24C1024_PORT&=~(BIT(OSCL)|BIT(OSDA))
#define OSCL_HIGH() \
_24C1024_DDR&=~BIT(OSCL)
#define OSCL_LOW() \
_24C1024_DDR|=BIT(OSCL)
#define OSDA_HIGH() \
_24C1024_DDR&=~BIT(OSDA)
#define OSDA_LOW() \
_24C1024_DDR|=BIT(OSDA)
#define _LOW 0
#define _HIGH 1
#define FALSE 0
#define TRUE 1
/////////////////////////////////////////////
// I2C common definition
/////////////////////////////////////////////
#define i2cSetSCL(is_hl) \
{ \
if(is_hl==_HIGH)\
OSCL_HIGH();\
else \
OSCL_LOW();\
}
#define i2cSetSDA(is_hl) \
{ \
if(is_hl==_HIGH) \
OSDA_HIGH(); \
else \
OSDA_LOW(); \
}
#define i2cSCL_PIN_STATUS ((_24C1024_PINX&BIT(OSCL))>>OSCL)
#define i2cSDA_PIN_STATUS ((_24C1024_PINX&BIT(OSDA))>>OSDA)
// type definition
typedef enum _I2cIoTransType
{
I2C_TRANS_READ,
I2C_TRANS_WRITE
}I2cIoTransType;
#define I2C_DEVICE_ADR_WRITE(slave_adr) (slave_adr & ~_BIT0)
#define I2C_DEVICE_ADR_READ(slave_adr) (slave_adr | _BIT0)
#define I2C_ACCESS_DUMMY_TIME 3
#define I2C_ACKNOWLEDGE _LOW
#define I2C_NON_ACKNOWLEDGE _HIGH
//===================================================================================//
//========================== For oprating 24C1024=========================================//
// for i2c
IMITATE_I2C void i2cSetSCL_Chk(BYTE bSet);
IMITATE_I2C void i2cSetSDA_Chk(BYTE bSet);
IMITATE_I2C BYTE i2c_Start(void);
IMITATE_I2C void i2c_Stop(void);
IMITATE_I2C BYTE i2c_ReceiveByte(BYTE bAck);
IMITATE_I2C BYTE i2c_SendByte(BYTE ucVal);
IMITATE_I2C BYTE i2c_AccessStart(BYTE ucSlaveAdr, I2cIoTransType trans_t);
IMITATE_I2C void i2cBurstReadBytes(BYTE ucSlaveAdr, UINT ucSubAdr, BYTE *pBuf, BYTE ucBufLen);
IMITATE_I2C void i2cBurstWriteBytes(BYTE ucSlaveAdr, UINT ucSubAdr, BYTE *pBuf, BYTE ucBufLen);
IMITATE_I2C BYTE i2cReadByte(BYTE ucSlaveAdr, UINT ucSubAdr);
IMITATE_I2C void i2cWriteByte(BYTE ucSlaveAdr, UINT ucSubAdr, BYTE ucVal);
#define MCU_XTAL_CLK_HZ 8000000
#define MCU_XTAL_CLK_KHZ (MCU_XTAL_CLK_HZ / 1000)
#define MCU_XTAL_CLK_MHZ (MCU_XTAL_CLK_KHZ / 1000)
///////////////////////////////////////
// MCU delay definition
///////////////////////////////////////
// 2(status sequence) * 6(S1-S6)
#define MCU_MACHINE_CYCLE 12 // unit: oscillatory cycle
// (MCU_MACHINE_CYCLE / 2) -> decimal fraction
#define MCU_MICROSECOND_NOP_NUM ((MCU_XTAL_CLK_MHZ + (MCU_MACHINE_CYCLE / 2)) / MCU_MACHINE_CYCLE)
#define I2C_CHECK_PIN_TIME 1000 // unit: 1 us
#define I2C_CHECK_PIN_CYCLE 8 // cycle of check pin loopp
#define I2C_CHECK_PIN_DUMMY ((I2C_CHECK_PIN_TIME / I2C_CHECK_PIN_CYCLE) * MCU_MICROSECOND_NOP_NUM)
#if (MCU_MICROSECOND_NOP_NUM <= 1)
#undef MCU_MICROSECOND_NOP_NUM
#define MCU_MICROSECOND_NOP_NUM 1
#define MCU_Delay1us() \
{ \
_nop_(); \
}
#elif (MCU_MICROSECOND_NOP_NUM <= 2)
#define MCU_Delay1us() \
{ \
_nop_(); \
_nop_(); \
}
#elif (MCU_MICROSECOND_NOP_NUM <= 3)
#define MCU_Delay1us() \
{ \
_nop_(); \
_nop_(); \
_nop_(); \
}
#elif (MCU_MICROSECOND_NOP_NUM <= 4)
#define MCU_Delay1us() \
{ \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
}
#elif (MCU_MICROSECOND_NOP_NUM <= 5)
#define MCU_Delay1us() \
{ \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
}
#elif (MCU_MICROSECOND_NOP_NUM <= 6)
#define MCU_Delay1us() \
{ \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
}
#elif (MCU_MICROSECOND_NOP_NUM <= 7)
#define MCU_Delay1us() \
{ \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
}
#else
#define MCU_Delay1us() \
{ \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
}
#endif
#endif
// imitate_i2c.c
void i2c_Delay(void)
{
//MCU_Delay1us();
//MCU_Delay1us();
//MCU_Delay1us();
//MCU_Delay1us();
}
/////////////////////////////////////////
// Set I2C SCL pin high/low.
//
// Arguments: bSet - high/low bit
/////////////////////////////////////////
void i2cSetSCL_Chk(BYTE bSet)
{
BYTE ucDummy; // loop dummy
i2cSetSCL(bSet); // set SCL pin
if (bSet == _HIGH) // if set pin high
{
ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
CHANGE_PIN_DIR(_24C1024_DDR, OSCL, INPUT);
asm("nop");
while ((i2cSCL_PIN_STATUS == _LOW) && (ucDummy--)) ; // check SCL pull high
CHANGE_PIN_DIR(_24C1024_DDR, OSCL, OUTPUT);
} // if
}
/////////////////////////////////////////
// Set I2C SDA pin high/low
//
// Arguments: bSet - high/low bit
/////////////////////////////////////////
void i2cSetSDA_Chk(BYTE bSet)
{
BYTE ucDummy; // loop dummy
i2cSetSDA(bSet);// set SDA pin
if (bSet == _HIGH) // if set pin high
{
ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, INPUT);
asm("nop");
while ((i2cSDA_PIN_STATUS == _LOW) && (ucDummy--)) ; // check SDA pull high
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, OUTPUT);
} // if
}
//////////////////////////////////////////////////////
// I2C start signal.
// <comment>
// SCL ________
// \_________
// SDA _____
// \____________
//
// Return value: None
//////////////////////////////////////////////////////
BYTE i2c_Start(void)
{
BYTE bStatus = TRUE; // success status
i2cSetSDA_Chk(_HIGH);
i2c_Delay();
i2cSetSCL_Chk(_HIGH);
i2c_Delay();
// check pin error
CHANGE_PIN_DIR(_24C1024_DDR, OSCL, INPUT);
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, INPUT);
asm("nop");asm("nop");asm("nop");
if ((i2cSCL_PIN_STATUS == _LOW) || (i2cSDA_PIN_STATUS == _LOW))
{
CHANGE_PIN_DIR(_24C1024_DDR, OSCL, OUTPUT);
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, OUTPUT);
bStatus = FALSE;
}
else // success
{
CHANGE_PIN_DIR(_24C1024_DDR, OSCL, OUTPUT);
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, OUTPUT);
asm("nop");asm("nop");asm("nop");
i2cSetSDA(_LOW);
i2c_Delay();
i2cSetSCL(_LOW);
}
return bStatus;
}
/////////////////////////////////////////
// I2C stop signal.
// <comment>
// ____________
// SCL _______/
// _________
// SDA __________/
/////////////////////////////////////////
void i2c_Stop(void)
{
i2cSetSCL(_LOW);
i2c_Delay();
i2cSetSDA(_LOW);
i2c_Delay();
i2cSetSCL_Chk(_HIGH);
i2c_Delay();
i2cSetSDA_Chk(_HIGH);
i2c_Delay();
}
//////////////////////////////////////////////////////////////////////////
// I2C receive byte from device.
//
// Return value: receive byte
//////////////////////////////////////////////////////////////////////////
BYTE i2c_ReceiveByte(BYTE bAck)
{
BYTE ucReceive = 0;
BYTE ucMask = 0x80;
while(ucMask)
{
i2cSetSDA(_HIGH);
i2cSetSCL_Chk(_HIGH);
i2c_Delay();
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, INPUT);
asm("nop");
if(i2cSDA_PIN_STATUS == _HIGH)
ucReceive |= ucMask;
i2cSetSCL(_LOW);
i2c_Delay();
ucMask >>= 1; // next
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, OUTPUT);
asm("nop");
} // while
if (bAck) // acknowledge
i2cSetSDA_Chk(I2C_ACKNOWLEDGE);
else // non-acknowledge
i2cSetSDA_Chk(I2C_NON_ACKNOWLEDGE);
i2c_Delay();
i2cSetSCL_Chk(_HIGH);
i2c_Delay();
i2cSetSCL(_LOW);
i2c_Delay();
return ucReceive;
}
//////////////////////////////////////////////////////////////////////////
// I2C send byte to device.
//
// Arguments: ucVal - send byte
// Return value: I2C acknowledge bit
// I2C_ACKNOWLEDGE/I2C_NON_ACKNOWLEDGE
//////////////////////////////////////////////////////////////////////////
BYTE i2c_SendByte(BYTE ucVal)
{
BYTE ucMask = 0x80;
BYTE bAck; // acknowledge bit
while(ucMask)
{
if (ucVal & ucMask)
i2cSetSDA_Chk(_HIGH);
else
i2cSetSDA_Chk(_LOW);
i2c_Delay();
i2cSetSCL_Chk(_HIGH); // clock
i2c_Delay();
i2cSetSCL(_LOW);
i2c_Delay();
ucMask >>= 1; // next
} // while
// recieve acknowledge
i2cSetSDA(_HIGH);
i2c_Delay();
i2cSetSCL_Chk(_HIGH);
i2c_Delay();
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, INPUT);
//_24C1024_PORT|=BIT(OSDA);
asm("nop");
bAck = i2cSDA_PIN_STATUS; // recieve acknowlege
i2cSetSCL(_LOW);
i2c_Delay();
CHANGE_PIN_DIR(_24C1024_DDR, OSDA, OUTPUT);
asm("nop");
return (bAck);
}
//////////////////////////////////////////////////////////////////////////
// I2C access start.
//
// Arguments: ucSlaveAdr - slave address
// trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
//////////////////////////////////////////////////////////////////////////
BYTE i2c_AccessStart(BYTE ucSlaveAdr, I2cIoTransType trans_t)
{
BYTE ucDummy; // loop dummy
if (trans_t == I2C_TRANS_READ) // check i2c read or write
ucSlaveAdr = I2C_DEVICE_ADR_READ(ucSlaveAdr); // read
else
ucSlaveAdr = I2C_DEVICE_ADR_WRITE(ucSlaveAdr); // write
ucDummy = I2C_ACCESS_DUMMY_TIME;
while (ucDummy--)
{
if (i2c_Start() == FALSE)
{
uart_send_str("\r\nNot getting start signal\r\n");
continue;
}
//uart_send_str("\r\nAre you ok?\r\n");
if (i2c_SendByte(ucSlaveAdr) == I2C_ACKNOWLEDGE) // check acknowledge
return TRUE;
uart_send_str("\r\n Not be ok!! \r\n");
i2c_Stop();
// Delay1ms(1);
} // while
return FALSE;
}
/////////////////////////////////////////////////////////////////
// I2C read bytes from device.
//
// Arguments: ucSlaveAdr - slave address
// ucSubAdr - sub address
// pBuf - pointer of buffer
// ucBufLen - length of buffer
/////////////////////////////////////////////////////////////////
void i2cBurstReadBytes(BYTE ucSlaveAdr, UINT ucSubAdr, BYTE *pBuf, BYTE ucBufLen)
{
BYTE ucDummy; // loop dummy
ucDummy = I2C_ACCESS_DUMMY_TIME;
while(ucDummy--)
{
if (i2c_AccessStart(ucSlaveAdr, I2C_TRANS_WRITE) == FALSE)
continue;
if (i2c_SendByte(ucSubAdr>>8) == I2C_NON_ACKNOWLEDGE) // check non-acknowledge
continue;
if (i2c_SendByte(ucSubAdr&0xff) == I2C_NON_ACKNOWLEDGE) // check non-acknowledge
continue;
if (i2c_AccessStart(ucSlaveAdr, I2C_TRANS_READ) == FALSE) // read i2c device must resend start signal
continue;
while(ucBufLen--) // loop to burst read
{
*pBuf = i2c_ReceiveByte(ucBufLen); // receive byte
pBuf++; // next byte pointer
} // while
break;
} // while
i2c_Stop();
}
/////////////////////////////////////////////////////////////////
// I2C write bytes to device.
//
// Arguments: ucSlaveAdr - slave address
// ucSubAdr - sub address
// pBuf - pointer of buffer
// ucBufLen - length of buffer
/////////////////////////////////////////////////////////////////
void i2cBurstWriteBytes(BYTE ucSlaveAdr, UINT ucSubAdr, BYTE *pBuf, BYTE ucBufLen)
{
BYTE ucDummy; // loop dummy
ucDummy = I2C_ACCESS_DUMMY_TIME;
while(ucDummy--)
{
if (i2c_AccessStart(ucSlaveAdr, I2C_TRANS_WRITE) == FALSE)
{
uart_send_str("\r\nAccessstart failure\r\n");
continue;
}
if (i2c_SendByte(ucSubAdr>>8) == I2C_NON_ACKNOWLEDGE) // check non-acknowledge
{
uart_send_str("\r\nSend High address failure\r\n");
continue;
}
if (i2c_SendByte(ucSubAdr&0xff) == I2C_NON_ACKNOWLEDGE) // check non-acknowledge
{
uart_send_str("\r\nSend low address failure\r\n");
continue;
}
while(ucBufLen--) // loop of writting data
{
i2c_SendByte(*pBuf); // send byte
pBuf++; // next byte pointer
} // while
break;
} // while
i2c_Stop();
}
/////////////////////////////////////////////////////////////////
// I2C read a byte from device.
//
// Arguments: ucSlaveAdr - slave address
// ucSubAdr - sub address
// Return value: read byte
/////////////////////////////////////////////////////////////////
BYTE i2cReadByte(BYTE ucSlaveAdr, UINT ucSubAdr)
{
BYTE ucBuf=0xFF; // byte buffer
i2cBurstReadBytes(ucSlaveAdr, ucSubAdr, &ucBuf, 1);
return ucBuf;
}
/////////////////////////////////////////////////////////////////
// I2C write a byte from device.
//
// Arguments: ucSlaveAdr - slave address
// ucSubAdr - sub address
// ucVal - write byte
/////////////////////////////////////////////////////////////////
void i2cWriteByte(BYTE ucSlaveAdr, UINT ucSubAdr, BYTE ucVal)
{
i2cBurstWriteBytes(ucSlaveAdr, ucSubAdr, &ucVal, 1);
}
// main.c
void main(void)
{
UINT index=0;
for(index=0;index<256;index++)
{
i2cWriteByte(0xa0,index,index);
Delay_nms(5);
}
while(1)
{
for(index=0;index<256;index++)
{
uart_send_char(i2cReadByte(0xa0,index));
Delay_nms(100);
if(index==255)
while(1);
}
}
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|