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;
}

좋은 웹페이지 즐겨찾기