📄 avr_twi.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 + -