⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpi2c.c

📁 atmel avr software i2c communication source
💻 C
字号:
// For I2C Interface 2005-09-12 Added by LeeJJ
#include "gpi2c.h"
#include "uart.h"
#include "main.h"
//#include "i2c_twi.h"

#define _DELAY_NUM		5

#define I2C_INTERVAL 0
unsigned char ucNack=0;
unsigned char ucHibyte=0;
unsigned char ucLobyte=0;
	
void nops(unsigned char num)
{
	unsigned char i;
	for(i=0 ; i<num ; i++)	{
		nop();
	}
}

void  delay_i2c(void)
{
	u32 i;
	for(i=0;i<10;i++);
}

void gpi2c_init(void)
{
	I2C_DDR  |= (SCL_SET) | (SDA_SET);	// Set SCL, SDA to output
	I2C_PORT |= (SCL_SET) | (SDA_SET);	// Set SCL, SDA High
}

void gpi2c_start(void)
{
	I2C_DDR  |= 0x03;	// Set SCL, SDA to output
	I2C_PORT |= 0x03;	// Set SCL, SDA High
 	_delay_us(1);
	//_delay_ms(10);
	I2C_PORT &= 0xFD;	// Clear SDA
 	_delay_us(1);
 	//_delay_ms(10);
 	I2C_PORT &= 0xFE;	// Clear SCL
}

void gpi2c_stop(void)
{
	I2C_DDR  |= 0x02;	// Set SDA to output
	I2C_PORT &= 0xFC;	// Clear SCL, SDA Low
 	_delay_us(1);

	I2C_PORT |= 0x01;	// Set SCL High
 	_delay_us(1);
	I2C_PORT |= 0x02;	// Set SDA High
 	I2C_DDR  &= 0xFD;	// Set SDA to Input
}

void gpi2c_clock(void)
{
	I2C_PORT |= 0x01;	// Set SCL High
 	_delay_us(2);	// Small Delay
	I2C_PORT &= 0xFE;	// Clear SCL Low
	_delay_us(2);
}

unsigned char gpi2c_ackn(void)
{
	unsigned char ackn = 0;	// Temp RAM for Ackn flag

	I2C_DDR &= 0xFD;		// Set SDA to input
	I2C_PORT &= 0xFE;		// Clear SCL Low

	I2C_PORT |= 0x01;		// Clock the ACK bit
	nops(10);
	
	//loop_until_bit_is_clear(PIND, PD1);
	//ackn=0;
	if((I2C_INPUT & 0x02) == 0x02)	
	{
		ackn=1;	// Check the ACK bit on SDA
		cbi(PORTE,PE0);
	}
	else
	{
			ackn=0;
			sbi(PORTE,PE0);
	}
	nops(10);

	I2C_PORT &= 0xFE;		// Clear SCL Low

	I2C_DDR  |= 0x02;		// Set SDA to output
	//UART1_SendByte(ackn);
	return ackn;		// Return our ACK bit
}

void write_gpi2c_byte(unsigned char byte)
{
	unsigned char i;

	I2C_DDR  |= 0x02;		// Set SDA to output
	I2C_PORT &= 0xFE;		// Clear SCL Low

	for (i=0; i<8 ; i++)
	{
		if((byte & 0x80)==0x80)	I2C_PORT |= 0x02;	// Set SDA High
		else					I2C_PORT &= 0xFD;	// Clear SDA Low
		nops(20);

		I2C_PORT |= 0x01;		// Set SCL High, Clock data
		byte = byte << 1;	// Shift data in buffer right one
	 	//nops(1);			// Small Delay
	 	_delay_us(10);
	 	if(i==0)		nops(20);
		I2C_PORT &= 0xFE;		// Clear SCL
	}
	I2C_DDR  &= 0xFD;		// Set SDA to Input

	//nops(45);			// Small Delay
	_delay_us(15);
	//_delay_ms(4);
	if(gpi2c_ackn()==1)	ucNack=1;
	
}

unsigned char read_gpi2c_byte(unsigned char ch)
{
	unsigned char i, buff=0;

	I2C_DDR  &= 0xFD;	// Set SDA to input
	nop();

	for(i=0; i<8; i++)
	{
		buff <<= 1;

		I2C_PORT |= 0x01;	// Set SCL High, Clock bit out
	 	nops(3);		// Small Delay

		// Read data on SDA pin
		if ((I2C_INPUT & 0x02)==0x02) {
			buff |= 0x01;
		}
		I2C_PORT &= 0xFE;	// Clear SCL
	 	nops(3);		// Small Delay
	}

	nops(80);			// Long Delay

	I2C_DDR  |= 0x02;	// Set SDA to Output
	if(ch==0)	// Ack
	{
		I2C_PORT &= 0xFD;	// Clear SDA Low
		gpi2c_clock();
	}
	else		// No Ack
	{
		I2C_PORT |= 0x02;	// Clear SDA High
		gpi2c_clock();
		nops(4);		// Small Delay
		I2C_PORT &= 0xFD;	// Clear SDA Low
	}
	return buff;
}

void read_gpi2c_word(unsigned char add)
{
	unsigned int temp;

	ucHibyte=0;
	ucLobyte=0;

	gpi2c_start();
	write_gpi2c_byte(0x16);
	_delay_us(40);

	write_gpi2c_byte(add);
	_delay_us(100);

	gpi2c_start();
	write_gpi2c_byte(0x17);
	_delay_us(70);

	ucLobyte=read_gpi2c_byte(0);
	_delay_us(40);

	ucHibyte=read_gpi2c_byte(1);
	_delay_us(40);

	gpi2c_stop();

	if (ucNack==1)	
		;//UART_Puts("\n\rNo Ack!!!");
	else	{
		temp = (ucHibyte<<8) + ucLobyte;
		//UART_Puts("\n\rRead Word[%02X] = %02X %02X, <%f>\n\r", add, ucLobyte, ucHibyte, (float)temp);
	}
	ucNack=0;
}

void write_gpi2c_word(unsigned char add)
{
	gpi2c_start();
	write_gpi2c_byte(0x16);
	_delay_us(40);

	write_gpi2c_byte(add);
	_delay_us(100);

	if(add==0)	write_gpi2c_byte(0x06);
	else		write_gpi2c_byte(0x0a);
	_delay_us(70);

	write_gpi2c_byte(0x00);
	_delay_us(70);

	gpi2c_stop();
}

void write_gpi2c_4byte(u32 command_long )
{
	unsigned char i;
	gpi2c_start();
	_delay_us(7);
	
	I2C_DDR  |= 0x02;		// Set SDA to output
	I2C_PORT &= 0xFE;		// Clear SCL Low


	command_long = command_long << 10;
	
	for (i=0; i<22 ; i++)
	{
		if((command_long & 0x8000)==0x8000)	I2C_PORT |= 0x02;	// Set SDA High
		else					I2C_PORT &= 0xFD;	// Clear SDA Low
		nops(1);

		I2C_PORT |= 0x01;		// Set SCL High, Clock data
		command_long = command_long << 1;	// Shift data in buffer right one
	 	nops(1);			// Small Delay
	 	if(i==0)		nops(2);
		PORTD &= 0xFE;		// Clear SCL
	}
	I2C_DDR  &= 0xFD;		// Set SDA to Input

	nops(45);			// Small Delay
	
	_delay_us(7);
	gpi2c_stop();
	_delay_us(70);
	//if(gpi2c_ackn()==1)	ucNack=1;
}

void plli2c_init(void)
{
	PLL_DDR  |= (PLL_SCK_SET) | (PLL_SDA_SET);	// Set SCL, SDA to output
	PLL_SERIAL |= (PLL_SCK_SET) | (PLL_SDA_SET);	// Set SCL, SDA High
}


void pll_write(u32 data1)
{
		u08 i;

		SCL_L;
		SDA_L;
		nops(_DELAY_NUM);
				
		data1 = data1 << 11;
		for (i = 0; i < 21; i++)
		{
			if(data1&0x10000000)   SDA_H;
			else     SDA_L;
			//SCL_L;
			nops(_DELAY_NUM);
			SCL_L;
			nops(_DELAY_NUM);
			//d = d << 1;	/* increase scl high time */
			SCL_H;
			nops(_DELAY_NUM);
			data1 = data1 << 1;
		}

		//SCL_L;
		nops(_DELAY_NUM);
		SCL_H;
		SDA_H;
		_delay_us(5);
}

void pll_cont_write(u08 data1, u08 data2, u08 data3)
{
		u08 i;

		SCL_L;
		SDA_L;
		nops(_DELAY_NUM);
		//_delay_us(10);		
		data1 = data1 << 3;
		for (i = 0; i < 5; i++)
		{
			if(data1&0x80)   SDA_H;
			else     SDA_L;
			//SCL_L;
			nops(_DELAY_NUM);
			//_delay_us(1);
			SCL_H;
			nops(_DELAY_NUM);
			//_delay_us(1);
			//d = d << 1;	/* increase scl high time */
			SCL_L;
			//_delay_us(5);
			nops(_DELAY_NUM);
			
			data1 = data1 << 1;
		}
		
		for (i = 0; i < 8; i++)
		{
			if(data2&0x80)   SDA_H;
			else     SDA_L;
			//SCL_L;
			nops(_DELAY_NUM);
			//_delay_us(1);
			SCL_H;
			nops(_DELAY_NUM);
			//_delay_us(1);
			//d = d << 1;	/* increase scl high time */
			SCL_L;
			//_delay_us(5);
			nops(_DELAY_NUM);
			
			data2 = data2 << 1;
		}
		
		for (i = 0; i < 8; i++)
		{
			if(data3&0x80)   SDA_H;
			else     SDA_L;
			//SCL_L;
			nops(_DELAY_NUM);
			//_delay_us(1);
			SCL_H;
			nops(_DELAY_NUM);
			//_delay_us(1);
			//d = d << 1;	/* increase scl high time */
			SCL_L;
			//_delay_us(5);
			nops(_DELAY_NUM);
			
			data3 = data3 << 1;
		}
		
		
		//SCL_L;
		//_delay_us(80);
		nops(_DELAY_NUM);
		SCL_L;
		SDA_L;
		_delay_us(10);
		//_delay_us(5);
}


void load_pll(u08 control, u08 data3, u08 data2, u08 data1)
{
 		u08 i;
		
		SCL_L;
		SDA_L;
		nops(_DELAY_NUM);
		
 		data3 = data3 << 5;
 		for (i = 0; i < 3; i++)
		{
			if(data3&0x80)   SDA_H;
			else     SDA_L;
			nops(_DELAY_NUM);
			SCL_H;
			nops(_DELAY_NUM);
			SCL_L;
			nops(_DELAY_NUM);
			
			data3 = data3 << 1;
		}
 		
 		for (i = 0; i < 8; i++)
		{
			if(data2&0x80)   SDA_H;
			else     SDA_L;
			nops(_DELAY_NUM);
			SCL_H;
			nops(_DELAY_NUM);
			SCL_L;

			nops(_DELAY_NUM);
			data2 = data2 << 1;
		}
		
		for (i = 0; i < 8; i++)
		{
			if(data1&0x80)   SDA_H;
			else     SDA_L;
			nops(_DELAY_NUM);
			SCL_H;
			nops(_DELAY_NUM);
			SCL_L;
			nops(_DELAY_NUM);
			data1 = data1 << 1;
		}
 		
 		/** control 2bit **/
 		control = control << 6;
		for (i = 0; i < 2; i++)
		{
			if(control&0x80)   SDA_H;
			else     SDA_L;
			nops(_DELAY_NUM);
			SCL_H;
			nops(_DELAY_NUM);
			SCL_L;
			nops(_DELAY_NUM);
			control = control << 1;
		}
		nops(_DELAY_NUM);
		SCL_L;
		SDA_L;
		_delay_us(3);
		
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -