您的位置 首页 培训

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

*本程序为八位共阴极数码管且有两个573控制的动态扫描**此程序为开机记忆,可以每次开机分自动加一。如果加了,说明操作成功**本程序

/*本程序为八位共阴极数码管且有两个573操控的动态扫描*/

/*此程序为开机回忆,能够每次开机分主动加一。假如加了,阐明操作成功*/
/*本程序把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的功用是把后边的数据存在程序存贮器中,不必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 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位器材固定,后三位看连线(本机全接高),最终1位是1读指令位
#define WD_24C08_add 0xae
//写24C08的地址,前4位器材固定,后三位看连线(本机全接高),最终1位是0写指令位
//上述界说中,MT为主机发送,MR为主机接纳
//上述界说中,SLA是对地址操作,DATA是对数据操作
/*常用TWI操作(主形式写和读)*/
#define Start() TWCR=(1<#define Stop() TWCR=(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)
{
DDRA|=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(ucharadd,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(ucharadd)
{
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);
}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/peixun/254080.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部