新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > AVR片內(nèi)TWI總線(I2C總線協(xié)議)

AVR片內(nèi)TWI總線(I2C總線協(xié)議)

作者: 時(shí)間:2016-12-02 來源:網(wǎng)絡(luò) 收藏
/*本程序?yàn)榘宋还碴帢O數(shù)碼管且有兩個(gè)573控制的動(dòng)態(tài)掃描*/

/*此程序?yàn)殚_機(jī)記憶,可以每次開機(jī)分自動(dòng)加一。如果加了,說明操作成功*/
/*本程序把24C08的SCL和SDA分別接在MCU的SCL(PC0第22腳)和SDA(PC1第23腳)*/
//24C08的第7腳WP接地
#include
#include //這里面有BIT(),所以要包含
#define uchar unsigned char
#define uint unsigned int
#pragmadata:code //注code的功能是把后面的數(shù)據(jù)存在程序存貯器中,不用code就放到了隨機(jī)存貯器中.
uchar const table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00} ;
/*如果用uchar table[]就放到了數(shù)據(jù)存貯器中。決不要這樣用,這樣占用空間多。*/
/*兩個(gè)573,段碼PA3,位碼PA4*/
/****************************
I2C 狀態(tài)定義
MT 主方式傳輸 MR 主方式接受
***************************/
#define START 0x08
#define RE_START 0x10
#define MT_SLA_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位器件固定,后三位看連線(本機(jī)全接高),最后1位是1讀指令位
#define WD_24C08_add 0xae
//寫24C08的地址,前4位器件固定,后三位看連線(本機(jī)全接高),最后1位是0寫指令位
//上述定義中,MT為主機(jī)發(fā)送,MR為主機(jī)接收
//上述定義中,SLA是對(duì)地址操作,DATA是對(duì)數(shù)據(jù)操作
/*常用TWI操作(主模式寫和讀)*/
#define Start() TWCR=(1<#define Stop() TWCR=(1<#define Wait() while(!(TWCR&(1<#define TestAck() TWSR&0xf8 //觀察返回狀態(tài)
#define SetAck TWCR|=(1<#define SetNoAck TWCR&=~(1<#define Twi() TWCR=(1<#define Write8Bit(x) TWDR=(x);TWCR=(1</*延時(shí)子程序*/
void delay_ms(int time)
{
int i;
for(;time>0;time--)
for(i=0;i<1000;i++);
}

void show(uchar dat,uchar wei)
{
DDRA|=BIT(3);//把PA3設(shè)為輸出
DDRA|=BIT(4);//把PA4設(shè)為輸出
DDRB=0XFF;//把PB口設(shè)為輸出型,全為高
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 工作在主機(jī)模式下,TWRB的值不小于10,0X20一定大于10
TWCR=0X04;//把TWCR中,TWEN使能打開,所以是0X04
TWSR=0;//只用1分頻就可以了,就是不用分頻,就用晶振頻率
}

本文引用地址:http://butianyuan.cn/article/201612/324679.htm

/*********************************************
I2C總線寫一個(gè)字節(jié) 返回0:寫成功 返回1:寫失敗
**********************************************/

uchar IIC_write(ucharadd,uchar dat)
{
Start();//發(fā)送啟始位
Wait();//等待
if(TestAck()!=START)//也可寫成if(TestAck!=0X80)
return 1;
Write8Bit(WD_24C08_add);//告訴24C08,現(xiàn)在要寫操作,也可寫成Write8bit(0xA0);
Wait();//等待
if(TestAck()!=MT_SLA_ACK)//也可寫成if(TestAck!=0X18)
return 1;
//LSA是對(duì)器件的應(yīng)答
Write8Bit(add);//寫入要寫入數(shù)據(jù)的地址
Wait();//等待
if(TestAck()!=MT_DATA_ACK)//也可寫成if(TestACK()!=0X28)
return 1;
//DATA是對(duì)數(shù)據(jù)應(yīng)答
Write8Bit(dat);
Wait();//等待
if(TestAck()!=MT_DATA_ACK)//也可寫成if(TestACK()!=0X28)
return 1;
Stop();//送出停止信號(hào)
return 0;
}

uchar IIC_rd(ucharadd)
{
uchar temp;
Start();//發(fā)送啟始位
Wait();//等待
if(TestAck()!=START)//也可寫成if(TestAck!=0X80)
return 1;
Write8Bit(WD_24C08_add);//告訴24C08,現(xiàn)在要寫操作,也可寫成Write8bit(0xA0);
Wait();//等待
if(TestAck()!=MT_SLA_ACK)//也可寫成if(TestAck!=0X18)
return 1;
//SLA是對(duì)器件的應(yīng)答

Write8Bit(add);//寫入要讀出數(shù)據(jù)的地址
Wait();//等待
if(TestAck()!=MT_DATA_ACK)//也可寫成if(TestACK()!=0X28)
return 1;
//DATA是對(duì)數(shù)據(jù)應(yīng)答
Start();//重復(fù)發(fā)送啟始位
Wait();//等待
if(TestAck()!=RE_START)//也可寫成if(TestAck!=0X10)
return 1;
Write8Bit(RD_24C08_add);//告訴24C08,現(xiàn)在要讀操作,也可寫成Write8bit(0xA1);
Wait();//等待
if(TestAck()!=MR_SLA_ACK)//主機(jī)接收判斷,也可寫成if(TestAck!=0X40)
return 1;
Twi(); //須要重新啟動(dòng)
Wait();//等待
if(TestAck()!=MR_DATA_NOACK)
return 1;

temp=TWDR;
Stop();//送出停止信號(hào)
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);
}
}



評(píng)論


技術(shù)專區(qū)

關(guān)閉