
unit PCF8574
{
	public const int32 Addr = 0x27;
	
	link bit SDA_DIR;
	link bit SDA_IN;
	link bit SDA_OUT;
	
	link bit SCL_DIR;
	link bit SCL_OUT;
	
	uint8 t;
	
	uint8 addr;
	
	//--------------------------------------------
	//[i] function_void OS_init;
	public void OS_init()
	{
		SDA_DIR = 1;
		SDA_OUT = 1;
		
		SCL_DIR = 1;
		SCL_OUT = 1;
		
		addr = (uint8)(uint16)(uint)Addr;
		if( addr == 0 ) {
			addr = 0x3F;
			uint8 d = get_data();
			if( t == 200 ) {
				addr = 0x27;
			}
		}
	}
	//--------------------------------------------
	//дһֽ
	void set_data( uint8 data )
	{
		start_iic();
		write_byte( addr << 1 );
		write_byte( data );
		end_iic();
	}
	//--------------------------------------------
	//ȡһֽ
	uint8 get_data()
	{
		start_iic();
		write_byte( (addr << 1) + 1 );
		uint8 data = read_byte();
		NoAck();
		end_iic();
		return data;
	}
	//---------------------------------------------------
	//ʼIICͨ
	void start_iic()
	{
		SDA_OUT = 1;
		SCL_OUT = 1;
		delay_1us();
		SDA_OUT = 0;
		delay_1us();
		SCL_OUT = 0;
		delay_1us();
	}
	//IICͨ
	void end_iic()
	{
		SDA_OUT = 0;
		SCL_OUT = 1;
		delay_1us();
		SDA_OUT = 1;
		delay_1us();
		SCL_OUT = 1;
		delay_1us();
	}
	//ȴӦź
	void wait()
	{
		t = 0;
		SDA_input_mode();
		SCL_OUT = 1;
		while( SDA_IN == 1 && t < 200 ) { t + 1; delay_1us(); }
		SCL_OUT = 0;
		delay_1us();
		SDA_output_mode();
	}
	//дһֽ
	void write_byte( uint8 data )
	{
		loop( 8 ) {
			SDA_OUT = data.7(bit);
			data << 1;
			delay_1us();
			SCL_OUT = 1;
			delay_1us();
			SCL_OUT = 0;
			delay_1us();
		}
		wait();
	}
	//һֽ
	uint8 read_byte()
	{
		uint8 data;
		SDA_input_mode();
		loop( 8 ) {
			data << 1;
			data.0(bit) = SDA_IN;
			SCL_OUT = 1;
			delay_1us();
			SCL_OUT = 0;
			delay_1us();
		}
		SDA_output_mode();
		return data;
	}
	//ͷӦ
	void NoAck()
	{
		//SDA_OUT = 0;		//Ӧ
		SDA_OUT = 1;		//Ӧ
		delay_1us();
		SCL_OUT = 1;
		delay_1us();
		SCL_OUT = 0;
		delay_1us();
	}
	//SDAתģʽ
	void SDA_input_mode()
	{
		SDA_OUT = 1;
		SDA_DIR = 0;
	}
	//SDAתģʽ
	void SDA_output_mode()
	{
		SDA_DIR = 1;
	}
	//ʱ1΢
	void delay_1us()
	{
		loop( 2 ) {}
	}
}







