锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

AVR片内TWI总线(I2C总线协议)

时间:2024-05-02 11:37:09


/*本程序为八位共阴极且有两个573控制的动态扫描*/
/*此程序为开机记忆,可以每次开机分自动加一。如果加了,说明操作成功*/
/*本程序把24C08的SCL和SDA分别接在的SCL(PC0第22脚)和SDA(PC1第23脚)*/
//24C08的第7脚WP接地
#include
#include //这里面有BIT(),所以要包含
#define uchar unsigned char
#define uint unsigned int
#pragma data:code //注code的功能是把后面的数据存在程序存贮器中,不用code就放到了随机存贮器中.
uchar const table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00} ;
/*如果用uchar table[]就放到了数据存贮器中。决不要这样用,这样占用空间多。*/
/*两个573,段码PA3,位码PA4*/
/****************************
I2C 状态定义
MT 主方式传输 MR 主方式接受
***************************/
#define ART 0x08
#define RE_START 0x10
#define MT_A_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK 0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58
#define RD_24C08_add 0xaf
//读24C08的地址,前4位器件固定,后三位看连线(本机全接高),最后1位是1读指令位
#define WD_24C08_add 0xae
//写24C08的地址,前4位器件固定,后三位看连线(本机全接高),最后1位是0写指令位
//上述定义中,MT为主机发送,MR为主机接收
//上述定义中,SLA是对地址操作,DATA是对数据操作
/*常用TWI操作(主模式写和读)*/
#define Start() TWCR=(1< NT)|(1<
#define Stop() TWCR=(1< WSTO)|(1<
#define Wait() while(!(TWCR&(1< #define TestAck() TWSR&0xf8 //观察返回状态
#define SetAck TWCR|=(1< #define SetNoAck TWCR&=~(1< #define Twi() TWCR=(1< #define Write8Bit(x) TWDR=(x);TWCR=(1< /*延时子程序*/
void delay_ms(int time)
{
int i;
for(;time>0;time--)
for(i=0;i<1000;i++);
}

void show(uchar dat,uchar wei)
{
A|=BIT(3);//把PA3设为输出
DDRA|=BIT(4);//把PA4设为输出
DDRB=0XFF;//把PB口设为输出型,全为高
PORTA|=BIT(3);
PORTB=table[dat];
PORTA&=~BIT(3);

PORTB=0XFF;
PORTB&=~BIT(wei);
PORTA|=BIT(4);
PORTA&=~BIT(4);
delay_ms(1);
}
void TWI_init()//初始化TWI总线
{
TWBR=0X20;//TWIA 工作在主机模式下,TWRB的值不小于10,0X20一定大于10
TWCR=0X04;//把TWCR中,TWEN使能打开,所以是0X04
TWSR=0;//只用1分频就可以了,就是不用分频,就用晶振频率
}

/*********************************************
I2C总线写一个字节 返回0:写成功 返回1:写失败
**********************************************/

uchar IIC_write(uchar add,uchar dat)
{
Start();//发送启始位
Wait();//等待
if(TestAck()!=START)//也可写成if(TestAck!=0X80)
return 1;
Write8Bit(WD_24C08_add);//告诉24C08,现在要写操作,也可写成Write8bit(0xA0);
Wait();//等待
if(TestAck()!=MT_SLA_ACK)//也可写成if(TestAck!=0X18)
return 1;
//LSA是对器件的应答
Write8Bit(add);//写入要写入数据的地址
Wait();//等待
if(TestAck()!=MT_DATA_ACK)//也可写成if(TestACK()!=0X28)
return 1;
//DATA是对数据应答
Write8Bit(dat);
Wait();//等待
if(TestAck()!=MT_DATA_ACK)//也可写成if(TestACK()!=0X28)
return 1;
Stop();//送出停止信号
return 0;
}

uchar IIC_rd(uchar add)
{
uchar temp;
Start();//发送启始位
Wait();//等待
if(TestAck()!=START)//也可写成if(TestAck!=0X80)
return 1;
Write8Bit(WD_24C08_add);//告诉24C08,现在要写操作,也可写成Write8bit(0xA0);
Wait();//等待
if(TestAck()!=MT_SLA_ACK)//也可写成if(TestAck!=0X18)
return 1;
//SLA是对器件的应答

Write8Bit(add);//写入要读出数据的地址
Wait();//等待
if(TestAck()!=MT_DATA_ACK)//也可写成if(TestACK()!=0X28)
return 1;
//DATA是对数据应答
Start();//重复发送启始位
Wait();//等待
if(TestAck()!=RE_START)//也可写成if(TestAck!=0X10)
return 1;
Write8Bit(RD_24C08_add);//告诉24C08,现在要读操作,也可写成Write8bit(0xA1);
Wait();//等待
if(TestAck()!=MR_SLA_ACK)//主机接收判断,也可写成if(TestAck!=0X40)
return 1;
Twi(); //须要重新启动
Wait();//等待
if(TestAck()!=MR_DATA_NOACK)
return 1;

temp=TWDR;
Stop();//送出停止信号
return temp;
}
void main()
{
uchar i;
TWI_init();
i=IIC_rd(2);
if(i>9)
i=0;
i++;
IIC_write(2,i);
while(1)
{
show(i,2);
}
}


-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章