AVR片内TWI总线(I2C总线协议)
/*此程序为开机记忆,可以每次开机分自动加一。如果加了,说明操作成功*/
/*本程序把24C08的SCL和SDA分别接在MCU的SCL(PC0第22脚)和SDA(PC1第23脚)*/
//24C08的第7脚WP接地
#include
#include
#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 SetAck 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);
}
}
AVR片内TWI总线I2C总线协 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)