本帖最后由 micro_听海 于 2012-11-24 19:58 编辑
这几天一直在搞AVR的twi(twi就是i2c)双机通信程序,使用的是两块arduino开发板。因为最总要这个通信程序最总是要放在winavr的编译环境中,所以没有使用arduino自带的库函数。但是这没关系,因为arduino IDE和winavr编译器的内核都是开源gcc,所以在arduino ide上同样可以使用winavr的语言,赞ARDUINO!
硬件上就是arduino的SCL(A5引脚)和SDA(A4引脚)互联,当然还有GND。
下面上程序
先上发送端
#define uchar unsigned char
#define STATUS (TWSR&0xf8)
#define SLA_W 0x32
#define SLA_R 0x33
#define SLAVER_ADDRESS 0x32
#define START 0x08
#define RE_START 0x10
#define MT_SLA_WRITE_ACK 0x18
#define MT_SLA_READ_ACK 0x40
#define MT_DATA_ACK 0x28
#define MT_READ_ACK 0x58
void Start(void)//主机向从机发送i2c起始信号
{
TWCR=(1<
while(!(TWCR&(1<
}
void Stop(void)//主机发送i2c停止信号
{
TWCR=(1<
}
void Load(uchar i)//主机发送一个字节数据或地址
{
TWDR=i;
TWCR=(1<
while(!(TWCR&(1<
}
uchar SendByte(uchar data)//主机以广播方式向从机发送一个字节数据data
{
Start();//开始
Load(0);//发送广播地址0
Load(data);//发送数据
Stop();//停止
return 1;//发送成功,返回1;
}
void Init_Io(void)//io口初始化函数
{
DDRC&=~((1<<4)&(1<<5)&(1<<2));
PORTC|= (1<<4)|(1<<5)|(1<<2);//使能scl,sda引脚内部上拉电阻
TWCR=(1<
TWBR=32;//波特率 200k
}
uchar temp;
void setup( )
{
Init_Io();
Serial.begin(9600);
}
void loop( )
{
for(temp=0;temp<10;temp++)
{
SendByte(temp); //向从机发送0到9的数据
delay(8);
}
}
接收端程序
#define uchar unsigned char
#define STATUS (TWSR&0xf8)
#define SLA_W 0x32
#define SLA_R 0x33
#define TWI_ADDRESS 0x32
#define START 0x08
#define RE_START 0x10
#define MT_SLA_WRITE_ACK 0x18
#define MT_SLA_READ_ACK 0x40
#define MT_DATA_ACK 0x28
#define MT_READ_ACK 0x58
#define TW_SR_DATA_ACK 0x80
void Init_Io(void)
{
DDRC&=~((1<<4)&(1<<5)&(1<<2));
PORTC|= (1<<4)|(1<<5)|(1<<2);
TWAR=TWI_ADDRESS|(1<
TWCR=(1<
asm("CLI");//关闭全局中断,采用轮询方式接受数据
}
void setup( )
{
Init_Io();
Serial.begin(9600);
}
void loop( )
{
uchar temp1,temp2;
TWCR=(1<
while((TWCR&(1<
temp1=STATUS;
temp2=TWDR;
if(temp1==0x90)
{
Serial.println(temp2,DEC);//打印接收数据
}
}
上述程序已被验证,打开接受端arduino自带的串口监控器可以看到0到9的不断重复数据。
程序中没用到的宏可自行删除,不影响最后结果。