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

📄 avr_twi.h

📁 门禁系统源代码 VC++
💻 H
字号:

#ifndef _TWI_H
#define _TWI_H

#define SLA_W				0xFE
#define SLA_R				0x01

#define RW_SUC				0
#define ERR_START			1
#define ERR_SLA_W			2
#define ERR_SLA_R			3
#define ERR_REPEAT			4
#define ERR_H_ADDR			5
#define ERR_L_ADDR			6
#define ERR_READ			7
#define ERR_WRITE			8

#define CYCLE_TRY			200


#define TWI_SCL	240000
//
//	TWI_SCL = F_CPU / (16 + 2*TWBR * 4^TWPS)
//
//	TWBR = (F_CPU - 16*TWI_SCL) / (2*TWI_SCL * 4^TWPS)


unsigned char TWI_Start(void)
{
	TWCR = 0x00;
	TWBR = F_CPU/(8*TWI_SCL) - 2;
	TWAR = 0x00;

	TWCR = (1<<TWEN) | (1<<TWINT) | (1<<TWSTA);	
	loop_until_bit_is_set( TWCR, TWINT );

	return (TWSR&0xF8);
}

unsigned char TWI_Repeat(void)
{
	TWCR = (1<<TWEN) | (1<<TWINT) | (1<<TWSTA);
	loop_until_bit_is_set( TWCR, TWINT );

	return (TWSR&0xF8);
}

unsigned char TWI_SLA_W(unsigned char uc_data)
{
	TWDR = uc_data;

	TWCR = (1<<TWEN) | (1<<TWINT);
	loop_until_bit_is_set( TWCR, TWINT );

	return (TWSR&0xF8);
}

unsigned char TWI_SLA_R(void)
{
	TWCR = (1<<TWEN) | (1<<TWINT) | (1<<TWEA);
	loop_until_bit_is_set( TWCR, TWINT );
	
	return (TWSR&0xF8);
}

void TWI_Stop(void)
{
	TWCR = (1<<TWEN) | (1<<TWINT) | (1<<TWSTO);
}

unsigned char I2C_eeprom_read(
unsigned char uc_device_address, 
unsigned int  ui_data_address)
{
	if( TWI_Start() != 0x08 ) 									// 发送 START 信号
	{	
		TWI_Stop();
		return ERR_START;
	}

	if( TWI_SLA_W( uc_device_address & SLA_W ) != 0x18 ) 		// 发送 SLA_W 信号
	{
		TWI_Stop();
		return ERR_SLA_W;
	}

	if( TWI_SLA_W ( ui_data_address/256 ) != 0x28 ) 			// 发送16位 I2C E2PROM 高8位地址
	{
		TWI_Stop();
		return ERR_H_ADDR;
	}

	if( TWI_SLA_W( ui_data_address%256 ) != 0x28 ) 				// 发送16位 I2C E2PROM 低8位地址
	{
		TWI_Stop();
		return ERR_L_ADDR;
	}

	if( TWI_Repeat() != 0x10 ) 									// 重新发送 REPEATED START 信号
	{
		TWI_Stop();
		return ERR_REPEAT;
	}

	if( TWI_SLA_W( uc_device_address | SLA_R ) != 0x40 ) 		// 发送 SLA_R 信号
	{
		TWI_Stop();
		return ERR_SLA_R;
	}

	return RW_SUC;
}

unsigned char I2C_eeprom_write(
unsigned char uc_device_address, 
unsigned int  ui_data_address,
unsigned char uc_write_len,
volatile unsigned char *puc_write_buff )
{
	unsigned char uc_cycle=0;

	if( TWI_Start() != 0x08 ) 									// 发送 START 信号
	{	
		TWI_Stop();
		return ERR_START;
	}

	if( TWI_SLA_W( uc_device_address & SLA_W ) != 0x18 ) 		// 发送 SLA_W 信号
	{
		TWI_Stop();
		return ERR_SLA_W;
	}

	if( TWI_SLA_W ( ui_data_address/256 ) != 0x28 ) 			// 发送16位 I2C E2PROM 高8位地址
	{
		TWI_Stop();
		return ERR_H_ADDR;
	}

	if( TWI_SLA_W( ui_data_address%256 ) != 0x28 ) 				// 发送16位 I2C E2PROM 低8位地址
	{
		TWI_Stop();
		return ERR_L_ADDR;
	}

	while( uc_write_len ) 									// 发送数据
	{
		uc_cycle=0;
		re_write:
		if( uc_cycle++ >= CYCLE_TRY ) goto error;

		if( TWI_SLA_W( *puc_write_buff ) == 0x28 )
		{
			++puc_write_buff;
			--uc_write_len;
		}
		else
		{
			goto re_write;			
		}
	}

	TWI_Stop();
	return RW_SUC;

	error:
	return ERR_WRITE;
}

unsigned char RTC_Read(unsigned char uc_device_address, unsigned char uc_data_address)
{
	if( TWI_Start() != 0x08 ) 									// 发送 START 信号
	{	
		TWI_Stop();
		return ERR_START;
	}

	if( TWI_SLA_W( uc_device_address & SLA_W ) != 0x18 ) 		// 发送 SLA_W 信号
	{
		TWI_Stop();
		return ERR_SLA_W;
	}

	if( TWI_SLA_W( uc_data_address ) != 0x28 )					// 操作PCF8563的首位地址
	{
		TWI_Stop();
		return 9;
	}

	if( TWI_Repeat() != 0x10 ) 									// 重新发送 REPEATED START 信号
	{
		TWI_Stop();
		return ERR_REPEAT;
	}

	if( TWI_SLA_W( uc_device_address | SLA_R ) != 0x40 ) 		// 发送 SLA_R 信号
	{
		TWI_Stop();
		return ERR_SLA_R;
	}

	return RW_SUC; 
}

unsigned char RTC_Write(
unsigned char uc_device_address,
unsigned char uc_data_address,
unsigned char uc_write_len,
volatile unsigned char *puc_write_buff)
{
	unsigned char uc_cycle;

	if( TWI_Start() != 0x08 ) 									// 发送 START 信号
	{	
		TWI_Stop();
		return ERR_START;
	}

	if( TWI_SLA_W( uc_device_address & SLA_W ) != 0x18 ) 		// 发送 SLA_W 信号
	{
		TWI_Stop();
		return ERR_SLA_W;
	}

	if( TWI_SLA_W( uc_data_address ) != 0x28 )					// 操作PCF8563的首位地址
	{
		TWI_Stop();
		return 9;
	}

	while( uc_write_len ) 									// 发送数据
	{
		uc_cycle=0;
		re_write:
		if( uc_cycle++ >= CYCLE_TRY ) goto error;

		if( TWI_SLA_W( *puc_write_buff ) == 0x28 )
		{
			++puc_write_buff;
			--uc_write_len;
		}
		else
		{
			goto re_write;			
		}
	}

	TWI_Stop();
	return RW_SUC;

	error:
	return ERR_WRITE;
}

#endif

⌨️ 快捷键说明

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