上传一个自己编写的I2C双机通信程序
本帖最后由 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。
下面上程序
先上发送端
#defineucharunsigned char
#defineSTATUS(TWSR&0xf8)
#defineSLA_W 0x32
#defineSLA_R 0x33
#defineSLAVER_ADDRESS 0x32
#defineSTART 0x08
#defineRE_START 0x10
#defineMT_SLA_WRITE_ACK 0x18
#defineMT_SLA_READ_ACK 0x40
#defineMT_DATA_ACK 0x28
#defineMT_READ_ACK 0x58
void Start(void)//主机向从机发送i2c起始信号
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//开始发送
while(!(TWCR&(1<<TWINT)));//等待发送结束
}
void Stop(void)//主机发送i2c停止信号
{
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
void Load(uchar i)//主机发送一个字节数据或地址
{
TWDR=i;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
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<<TWEA)|(1<<TWEN); //主机模式,使能TWI
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);
}
}
接收端程序
#defineucharunsigned char
#defineSTATUS(TWSR&0xf8)
#defineSLA_W 0x32
#defineSLA_R 0x33
#defineTWI_ADDRESS 0x32
#defineSTART 0x08
#defineRE_START 0x10
#defineMT_SLA_WRITE_ACK 0x18
#defineMT_SLA_READ_ACK 0x40
#defineMT_DATA_ACK 0x28
#defineMT_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<<TWGCE);//设置从机地址
TWCR=(1<<TWEA) | (1<<TWEN)|(1<<TWIE);
asm("CLI");//关闭全局中断,采用轮询方式接受数据
}
void setup( )
{
Init_Io();
Serial.begin(9600);
}
void loop( )
{
uchar temp1,temp2;
TWCR=(1<<TWINT)|(1<<TWEA) | (1<<TWEN); //启动一次接收
while((TWCR&(1<<TWINT))==0); //等待有效数据被接收
temp1=STATUS;
temp2=TWDR;
if(temp1==0x90)
{
Serial.println(temp2,DEC);//打印接收数据
}
}
上述程序已被验证,打开接受端arduino自带的串口监控器可以看到0到9的不断重复数据。
程序中没用到的宏可自行删除,不影响最后结果。 高手。。。是不是arduino仅仅应用了一些宏,让我们编程的时候容易理解。 zcbzjx 发表于 2012-11-25 00:19 static/image/common/back.gif
高手。。。是不是arduino仅仅应用了一些宏,让我们编程的时候容易理解。
是这样的,不仅如此,而且arduino把一些常用的函数封装成库,使用起来简单,方便 看不懂,看上去好高深的样子 AVR不懂,请问TWCR是不是要学AVR? ttyp 发表于 2012-11-25 16:35 static/image/common/back.gif
AVR不懂,请问TWCR是不是要学AVR?
arduino开发板其实就搭载了AVR中的atmega328系列单片机,可以说arduino和AVR是同宗同源。
TWCR是atmega328单片机中关于I2C总线的寄存器。 micro_听海 发表于 2012-11-25 17:37 static/image/common/back.gif
arduino开发板其实就搭载了AVR中的atmega328系列单片机,可以说arduino和AVR是同宗同源。
TWCR是atmega3 ...
我是想了解一下,最近好多高深一点的程序都看不懂 ttyp 发表于 2012-11-25 17:48 static/image/common/back.gif
我是想了解一下,最近好多高深一点的程序都看不懂
不是必须的,因为ARDUINO虽然是AVR单片机的分支(或者叫做某一子分类),但是由于主要编程环境还是C语言,很多硬件相关的都被透明化了 (例如大学时候教的单片机编程都是用汇编 单片机初始化,状态管理,堆栈,寄存器操作等等 你用C语言直接就由编译器帮你弄好了)
如果有AVR基础会更好(精通AVR和C 玩ARDUINO简直就是如虎添翼),没有也能做出不错的程序;
编程不在于程序语言,那只是个工具,在于你的算法(这才是灵魂) 看完
http://wangxuetai2007.blog.163.com/blog/static/4373082220113710274912/
才看懂LZ的程序:lol有些收获 请问怎么连线? 111111 发表于 2013-6-22 19:17 static/image/common/back.gif
请问怎么连线?
l两个arduino的SCL(A5引脚),SDA(A4引脚),GND互联 micro_听海 发表于 2013-6-23 08:58 static/image/common/back.gif
l两个arduino的SCL(A5引脚),SDA(A4引脚),GND互联
嗯,试过了,不通,把程序加载上,串口什么都没有,怎么回事?
页:
[1]