gpio 아날로그 iic 드라이브, 코드 예시
4927 단어 버스 프로토콜
간단한 소개
ppio 아날로그 i2c 드라이브, stm8 버전 기반, 이식 편리, 관련 io만 바꾸면 됩니다. 아래에 코드를 직접 첨부합니다
IIC.H
#ifndef __IIC_H__
#define __IIC_H__
#undef EXTERN
#ifdef __IIC_H__
#define EXTERN
#else
#define EXTERN extern
#endif
#include "config.h"
#if 1
#define IIC_SDA_OUT {PE_DDR |= 0x02; PE_CR1 |= 0x02;}
#define IIC_SDA_SET(a) (PE_ODR_ODR1 = a)
#define IIC_SDA_IN {PE_DDR &= 0xFD; PE_CR1 &= 0xFD;}
#define IIC_SDA_GET PE_IDR_IDR1
#define IIC_SCL_OUT {PE_DDR |= 0x01; PE_CR1 |= 0x01;}
#define IIC_SCL_SET(a) (PE_ODR_ODR0 = a)
#endif
extern void I2C_Init( void );
extern unsigned char AS_iIC_wrReg(unsigned char SlaveAddr, unsigned int SubAddr,
unsigned char *dat, unsigned char size);
extern unsigned char AS_iIC_rdReg(unsigned char SlaveAddr, unsigned int SubAddr,
unsigned char *dat, unsigned char size );
#endif
IIC.C
#define __IIC_C__
#include "IIC.h"
#define _ACK 0x00
#define _nACK 0x01
void I2C_Delay( void )
{
unsigned char i = 0,j = 0;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 1; j++);
}
}
void _wrSDA_H( void )
{
IIC_SDA_SET(1);
}
void _wrSDA_L( void )
{
IIC_SDA_SET(0);
}
unsigned char _rdSDA( void )
{
unsigned char u8SDA = IIC_SDA_GET;
return u8SDA;
}
void _wrSCL_H( void )
{
IIC_SCL_SET(1);
}
void _wrSCL_L( void )
{
IIC_SCL_SET(0);
}
void I2C_Init( void )
{
IIC_SDA_OUT;
IIC_SCL_OUT;
_wrSCL_H(); I2C_Delay();
_wrSDA_H(); I2C_Delay();
}
void I2C_Start( void )
{
IIC_SDA_OUT;
_wrSDA_H(); I2C_Delay();
_wrSCL_H(); I2C_Delay();
_wrSDA_L(); I2C_Delay();
_wrSCL_L(); I2C_Delay();
}
void I2C_Stop( void )
{
IIC_SDA_OUT;
_wrSDA_L(); I2C_Delay();
_wrSCL_H(); I2C_Delay();
_wrSDA_H(); I2C_Delay();
}
U8 I2C_GetAck( void )
{
U8 ack = 1;
U8 i = 0;
_wrSCL_L(); I2C_Delay();
_wrSCL_H(); I2C_Delay();
IIC_SDA_IN;
while((1 == ack) && (i < 30))
{
i++;
ack = _rdSDA();
}
_wrSCL_L(); I2C_Delay();
return ack;
}
void I2C_PutAck( U8 ack )
{
IIC_SDA_OUT;
if(ack)
{
_wrSDA_H(); I2C_Delay();
}
else
{
_wrSDA_L(); I2C_Delay();
}
_wrSCL_H(); I2C_Delay();
_wrSCL_L(); I2C_Delay();
}
void I2C_Write(unsigned char dat)
{
unsigned char t = 8;
IIC_SDA_OUT;
do
{
_wrSCL_L();
if(dat & 0x80)
{
_wrSDA_H();
}
else
{
_wrSDA_L();
}
I2C_Delay();
dat <<= 1;
_wrSCL_H();
I2C_Delay();
} while ( --t != 0 );
}
unsigned char I2C_Read( void )
{
unsigned char dat = 0;
unsigned char t = 8;
_wrSCL_L(); I2C_Delay();
IIC_SDA_OUT;
_wrSDA_H(); I2C_Delay();
IIC_SDA_IN;
do
{
_wrSCL_H();
I2C_Delay();
dat <<= 1;
if(_rdSDA())
{
dat |= 0x01;
}
else
{
dat &= 0xFE;
}
_wrSCL_L();
I2C_Delay();
} while ( --t != 0 );
return dat;
}
unsigned char AS_iIC_wrReg(unsigned char SlaveAddr, unsigned int SubAddr,
unsigned char *dat, unsigned char size)
{
SlaveAddr &= 0xFE;
I2C_Start();
I2C_Write(SlaveAddr);
if ( I2C_GetAck() )
{
I2C_Stop();
return 1;
}
I2C_Write((unsigned char)(SubAddr >> 8));
if ( I2C_GetAck() )
{
I2C_Stop();
return 2;
}
I2C_Write((unsigned char)(SubAddr & 0xFF));
if ( I2C_GetAck() )
{
I2C_Stop();
return 3;
}
do
{
I2C_Write(*dat++);
if ( I2C_GetAck() )
{
I2C_Stop();
return 4;
}
} while ( (--size) != 0 );
I2C_Stop();
return 0;
}
unsigned char AS_iIC_rdReg(unsigned char SlaveAddr, unsigned int SubAddr,
unsigned char *dat, unsigned char size )
{
SlaveAddr &= 0xFE;
I2C_Start();
I2C_Write(SlaveAddr);
if ( I2C_GetAck() )
{
I2C_Stop();
return 1;
}
I2C_Write((unsigned char)(SubAddr >> 8));
if ( I2C_GetAck() )
{
I2C_Stop();
return 2;
}
I2C_Write((unsigned char)(SubAddr & 0xFF));
if ( I2C_GetAck() )
{
I2C_Stop();
return 3;
}
//I2C_Stop();
I2C_Start();
SlaveAddr |= 0x01;
I2C_Write(SlaveAddr);
if ( I2C_GetAck() )
{
I2C_Stop();
return 4;
}
for (;;)
{
*dat++ = I2C_Read();
if ( --size == 0 )
{
I2C_PutAck( _nACK );
break;
}
I2C_PutAck( _ACK );
}
I2C_Stop();
return 0;
}