📄 i2c.c
字号:
#include <avr/io.h>
#include <avr/twi.h>
#include <string.h>
#include <avr/signal.h>
#include "type.h"
#define TW_WRITE 0
#define TW_READ 1
#define max 3
void TWI_init( void ) //i2c初始化
{
DDRD|=0X01;
TWBR = 0x01; //设置波特率
TWSR &= 0xfc;//设置预分频因子为4,则SCL频率为409600Hz
}
uchar twi_write_byte(uchar sla,uchar address,uchar write_data )
{
uchar twst,n=0x0,rv=0x01;
restart:
if(n++>=max)
goto error;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://有可能出现
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = sla | TW_WRITE;//发送SLA+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
/* TWDR = address>>8;//传输地址高8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
} */
TWDR = address;//传输地址低8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = write_data;
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
default:
goto error;
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号
return rv;
error:
rv=0x00;
goto quit;
}
uchar twi_write_str(uchar sla,uchar address,uchar *p,uchar len )
{
uchar i,twst,n=0x0,rv=0x01;
restart:
if(n++>=max)
goto error;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://有可能出现
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = sla | TW_WRITE;//发送SLA+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
/* TWDR = address>>8;//传输地址高8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
} */
TWDR = address;//传输地址低8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
for(i=0;i<len;i++)
{
TWDR = *p;
p++;
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
default:
goto error;
}
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号
return rv;
error:
rv=0x00;
goto quit;
}
uchar twi_read_byte( uchar sla,uchar address)
{
uchar twst,n=0x0,rv=0x1;
restart:
if(n++>=max)
goto error;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://有可能出现
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = sla | TW_WRITE;//发送SLA+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
/* TWDR = address>>8;//传输地址高8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}*/
TWDR = address;//传输地址低8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送(重新)开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://正确的状态
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = sla | TW_READ;//发送SLA+R
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MR_SLA_ACK:
break;
case TW_MR_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MR_ARB_LOST:
goto begin;
default:
goto error;
}
TWCR = _BV(TWINT) | _BV(TWEN) ;//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MR_DATA_NACK:
rv = TWDR;
break;
default:
goto error;
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号
return rv;
error:
rv=0x00;
goto quit;
}
uchar twi_read_str( uchar sla,uchar address,uchar *p,uchar len)
{
uchar i,twst,n=0x0,rv=0x1;
restart:
if(n++>=max)
goto error;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://有可能出现
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = sla | TW_WRITE;//发送SLA+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
/* TWDR = address>>8;//传输地址高8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}*/
TWDR = address;//传输地址低8位
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送(重新)开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://正确的状态
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = sla | TW_READ;//发送SLA+R
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MR_SLA_ACK:
break;
case TW_MR_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MR_ARB_LOST:
goto begin;
default:
goto error;
}
for(i=0;i<len;i++)
{
if(i==(len-1))
{
TWCR = _BV(TWINT) | _BV(TWEN) ;//清TWINT,开始传输(无应答)
}
else
{
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) ;//清TWINT,开始传输(有应答)
}
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MR_DATA_NACK:
case TW_MR_DATA_ACK:
*p = TWDR;
p++;
break;
default:
goto error;
}
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号
return rv;
error:
rv=0x00;
goto quit;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -