?? i2c.c
字號(hào):
#include <reg52.h>
#include <intrins.h>
#include "sysdef.h"
#include "i2c.h"
/*
***************************************************************************************************
*
* I2C BUS: BEGIN
*
***************************************************************************************************
*/
#define set_sda(x) (I2C_SDA=x)
#define set_scl(x) (I2C_SCL=x)
#define get_sda() (I2C_SDA)
static void i2c_delay(UINT16 us)
{
while(us--);
}
static void i2c_start(I2C_CONFIG *pConfig)
{
i2c_delay(pConfig->tBUF); //Release I2C bus
set_sda(1);
i2c_delay(pConfig->tR);
set_scl(1);
i2c_delay(pConfig->tR + pConfig->tSU_STA);
set_sda(0);
i2c_delay(pConfig->tF + pConfig->tHD_STA);
set_scl(0);
i2c_delay(pConfig->tF);
}
static void i2c_stop(I2C_CONFIG *pConfig)
{
set_sda(0);
i2c_delay(pConfig->tF);
set_scl(1);
i2c_delay(pConfig->tR + pConfig->tSU_STO);
set_sda(1);
i2c_delay(pConfig->tR);
}
static BOOL i2c_putc(I2C_CONFIG *pConfig, UINT8 value)
{
UINT8 i;
UINT8 mask = 0x80;
UINT8 retry = 0;
BOOL bAck;
//Transfer a byte data(MSB)
for(i = 0; i < 8; i++){
i2c_delay(pConfig->tLOW);
if(value & mask){
set_sda(1);
}else{
set_sda(0);
}
i2c_delay(pConfig->tSU_DAT);
set_scl(1);
i2c_delay(pConfig->tR + pConfig->tHIGH);
set_scl(0);
i2c_delay(pConfig->tF + pConfig->tHD_DAT);
mask >>= 1;
}
//Receive the ACK bit
i2c_delay(pConfig->tLOW);
set_sda(1);
i2c_delay(pConfig->tR + pConfig->tSU_DAT);
set_scl(1);
i2c_delay(pConfig->tR);
bAck = FALSE; //NACK
retry = 0;
do{
i2c_delay(pConfig->tACK);
if(!get_sda()){
bAck = TRUE; //ACK
break;
}
}while(++retry < 5);
set_scl(0);
i2c_delay(pConfig->tF + pConfig->tLOW);
return bAck;
}
static UINT8 i2c_getc(I2C_CONFIG *pConfig, BOOL bAck)
{
UINT8 i;
UINT8 value = 0;
UINT8 mask = 0x80;
//Receive a byte data(MSB)
for(i = 0; i < 8; i++){
i2c_delay(pConfig->tLOW);
set_scl(1);
i2c_delay(pConfig->tR + pConfig->tHIGH);
if(get_sda()){
value |= mask;
}
set_scl(0);
i2c_delay(pConfig->tF + pConfig->tHD_DAT);
mask >>= 1;
}
//Transfer the ACK bit or not
i2c_delay(pConfig->tLOW);
if(bAck){
set_sda(0); //ACK
}else{
set_sda(1); //NACK
}
i2c_delay(pConfig->tSU_DAT);
set_scl(1);
i2c_delay(pConfig->tR + pConfig->tHIGH);
set_scl(0);
i2c_delay(pConfig->tF + pConfig->tLOW);
set_sda(1);
i2c_delay(pConfig->tR);
return value;
}
static BOOL i2c_select_device(I2C_CONFIG *pConfig, UINT8 uDevAddr, UINT8 *pSubAddr, UINT8 subAddrLen)
{
i2c_start(pConfig);
if(!i2c_putc(pConfig, uDevAddr & 0xfe)) return FALSE;
while(subAddrLen--){
if(!i2c_putc(pConfig, *pSubAddr++)) return FALSE;
}
return TRUE;
}
BOOL i2c_write(I2C_CONFIG *pConfig, UINT8 uDevAddr, UINT8 *pSubAddr, UINT8 subAddrLen, UINT8 *pData, UINT16 dataLen)
{
BOOL status = FALSE;
//OS_ENTER_CRITICAL();
if(!i2c_select_device(pConfig, uDevAddr, pSubAddr, subAddrLen)) goto exitCatch;
while(dataLen--){
if(!i2c_putc(pConfig, *pData++)) goto exitCatch;
}
status = TRUE;
exitCatch:
i2c_stop(pConfig);
//OS_EXIT_CRITICAL();
return status;
}
BOOL i2c_read(I2C_CONFIG *pConfig, UINT8 uDevAddr, UINT8 *pSubAddr, UINT8 subAddrLen, UINT8 *pData, UINT16 dataLen)
{
BOOL status = FALSE;
//OS_ENTER_CRITICAL();
if(subAddrLen){
if(!i2c_select_device(pConfig, uDevAddr, pSubAddr, subAddrLen)) goto exitCatch;
}
i2c_start(pConfig);
if(!i2c_putc(pConfig, uDevAddr | 0x01)) goto exitCatch;
while(dataLen--){
*pData++ = i2c_getc(pConfig, dataLen ? TRUE : FALSE); //Transfer the ACK bit(NOT ACK when last byte)
}
status = TRUE;
exitCatch:
i2c_stop(pConfig);
//OS_EXIT_CRITICAL();
return status;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -