资讯详情

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

/*本程序为八位共阴极且有两个573控制的动态扫描*/ /*此程序为开机记忆,可以每次开机分自动加一。如果加了,说明操作成功*/ /*本程序把24C08的SCL和SDA分别接在的SCL(PC0第22脚)和SDA(PC1第23脚)*/ //24C08的第7脚WP接地 #include <iom16v.h> #include <macros.h>//这里面有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<<TWINT))) //等待中断发生 #define TestAck() TWSR&0xf8 //观察返回状态 #define SetAck TWCR|=(1<<TWEA) //做出ACK应答 #define SetNoAck TWCR&=~(1<<TWEA) //做出Not Ack应答 #define Twi() TWCR=(1<<TWINT)|(1<<TWEN) //启动I2C #define Write8Bit(x) TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN) //写数据到TWDR /*延时子程序*/ 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百科大全!

锐单商城 - 一站式电子元器件采购平台