5324|10

79

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于IIC通信的问题,大牛来指点一下! [复制链接]

目前我用430的硬件IIC通信,采用主发送、从接收方式,就是一个单片机先采用主机方式发送数据,完后处于从接收模式;另一个单片机也如此,不知道这个方法有没有什么问题?
目前遇到的问题是:主发送一次后变为从方式,从接收后变为主方式返回数据,能够发送正确一次,返回数据错误!

大牛们看看问题出在那里?

最新回复

代码如下,大牛们看看:主从机配置代码一样,只是命令码不同 #include"msp430x16x.h" #pragma vector=USART0TX_VECTOR __interrupt void I2C_ISR(void); void IIC_senddat(unsigned char S_count,unsigned char *D); void delay(unsigned int num); void intIIC(void); unsigned char TXdata[10]={0x42,0x50,};//0x0a}; char l=0; void main(void) { WDTCTL=WDTPW+WDTHOLD; P5DIR|=BIT0; // test_led P5OUT&=~BIT0; intIIC(); _EINT(); P5OUT|=BIT0; delay(50); P5OUT&=~BIT0; TXdata[2]=0x81; while(1) { if(TXdata[2]==0x81) { TXdata[2]=0x0a; IIC_senddat(3,TXdata); P5OUT^=BIT0; delay(200); intIIC(); } } } #pragma vector=USART0TX_VECTOR __interrupt void I2C_ISR(void) { switch(I2CIV) { case 6:_NOP(); break; case 10 :// 接收 TXdata[l]=I2CDRB; l++; if(l>2)l=0; break; case 12 :// 发送 I2CDRB=TXdata[l]; l++; if(l>9)l=0; break; default:break; } } // IIC发送数据 void IIC_senddat(unsigned char S_count,unsigned char *D) { I2CNDAT=S_count; U0CTL|=MST; I2CSA=0X0048; // 主机发送目标地址:从地址 I2CTCTL |= I2CSTT+I2CTRX+ I2CSTP; // Initiate transfer - write to slave while((I2CIFG & NACKIFG) == 0x02); for(char k=0;k  详情 回复 发表于 2008-10-17 10:01
点赞 关注

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
从I2C的规范讲, 一条总线上实现多主多从是可以的. 当多个主设备同时存在时, 需要处理总线仲裁的问题.  


对于LZ的情形, 需要在初始化的时候规定好起始时谁主谁从; 第一次通讯结束后需要转换主从角色, 并重新配置I2C控制器. 对于新的从设备不要忘记配置地址, 对于主要配置波特率; 转换期间最好延时一下, 并暂时关闭I2C中断.


其实,可以简单处理是把一个一直做主,  另一个做从, 协议可以参考访问EEPROM的协议. 供你参考. 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
对于1楼朋友提供的“参考访问EEPROM的协议”也考虑过,它是读取时就有数据立即返回,而我的情况是:发送读取命令后,约有30~120秒的时间才有数据返回,间隔时间太长,所以才考虑主从变换的方式。
对于你提到的“需要在初始化的时候规定好起始时谁主谁从; ”那么一开始时使2机都处于从机状态,待有数据发送时转换为主机,另一方再根据接收到的命令做主从转换的抉择,原理上讲似乎可行!不知大牛们觉得如何?
 
 
 

回复

55

帖子

0

TA的资源

一粒金砂(初级)

4
 
还可以考虑加数字IO信号,比如从准备好时送中断过来。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

5
 
从机地址发送是单独发送的吗,还是IIC通信开始就自动发送了?
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

6
 
从机需要自己设置好自己的地址, 会话都是主机发起的,主机在start信号之后送出的就是slave地址。看I2C的规范吧。
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

7
 
你找个示波器查看一下电平,如果俩单片机的程序都自己写的话,你跟踪一变各个状态就知道为什么了。
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

8
 

总线仲裁是关键!就是分配他们的优先级。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

9
 
总线仲裁是关键!就是分配他们的优先级。

这个优先级怎么分配?
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(中级)

10
 
代码如下,大牛们看看:主从机配置代码一样,只是命令码不同

#include"msp430x16x.h"

#pragma vector=USART0TX_VECTOR
__interrupt void I2C_ISR(void);

void IIC_senddat(unsigned char S_count,unsigned char *D);
void delay(unsigned int num);
void intIIC(void);

unsigned char TXdata[10]={0x42,0x50,};//0x0a};
char l=0;
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;
P5DIR|=BIT0; // test_led
P5OUT&=~BIT0;
intIIC();
_EINT();
P5OUT|=BIT0;
delay(50);
P5OUT&=~BIT0;
TXdata[2]=0x81;
while(1)
{
if(TXdata[2]==0x81)
{
TXdata[2]=0x0a;
IIC_senddat(3,TXdata);
P5OUT^=BIT0;

delay(200);
intIIC();
}
}
}
#pragma vector=USART0TX_VECTOR
__interrupt void I2C_ISR(void)
{
switch(I2CIV)
{
case 6:_NOP();
break;
case 10 :// 接收
TXdata[l]=I2CDRB;
l++;
if(l>2)l=0;
break;
case 12 :// 发送
I2CDRB=TXdata[l];
l++;
if(l>9)l=0;
break;
default:break;
}
}
// IIC发送数据
void IIC_senddat(unsigned char S_count,unsigned char *D)
{
I2CNDAT=S_count;
U0CTL|=MST;
I2CSA=0X0048; // 主机发送目标地址:从地址
I2CTCTL |= I2CSTT+I2CTRX+ I2CSTP; // Initiate transfer - write to slave
while((I2CIFG & NACKIFG) == 0x02);

for(char k=0;k {
while ((I2CIFG & TXRDYIFG) == 0);
I2CDRB=TXdata[k];
}
while ((I2CTCTL & I2CSTP) == 0x02); // Wait for Stop Condition
delay(50);
I2CTCTL &= ~I2CTRX;
}
void delay(unsigned int num)
{
unsigned char i;
unsigned int l;
for(l=0;l for(i=0;i<200;i++);
}
void intIIC(void)
{
delay(50);
U0CTL=0;
U0CTL |= SWRST; // Reset USART state machine
U0CTL &= ~CHAR;
I2CIE&=~RXRDYIE;
I2CIFG=0;
P3SEL|=0X0A;
U0CTL|=I2C+SYNC;
U0CTL&=~I2CEN;
I2CTCTL|=I2CSSEL1;
I2COA=0X0050; // 本机地址
I2CIE|=RXRDYIE+OAIFG;
U0CTL|=I2CEN;
delay(50);
}
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

11
 
代码如下,大牛们看看:主从机配置代码一样,只是命令码不同

#include"msp430x16x.h"

#pragma vector=USART0TX_VECTOR
__interrupt void I2C_ISR(void);

void IIC_senddat(unsigned char S_count,unsigned char *D);
void delay(unsigned int num);
void intIIC(void);

unsigned char TXdata[10]={0x42,0x50,};//0x0a};
char l=0;
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;
P5DIR|=BIT0; // test_led
P5OUT&=~BIT0;
intIIC();
_EINT();
P5OUT|=BIT0;
delay(50);
P5OUT&=~BIT0;
TXdata[2]=0x81;
while(1)
{
if(TXdata[2]==0x81)
{
TXdata[2]=0x0a;
IIC_senddat(3,TXdata);
P5OUT^=BIT0;

delay(200);
intIIC();
}
}
}
#pragma vector=USART0TX_VECTOR
__interrupt void I2C_ISR(void)
{
switch(I2CIV)
{
case 6:_NOP();
break;
case 10 :// 接收
TXdata[l]=I2CDRB;
l++;
if(l>2)l=0;
break;
case 12 :// 发送
I2CDRB=TXdata[l];
l++;
if(l>9)l=0;
break;
default:break;
}
}
// IIC发送数据
void IIC_senddat(unsigned char S_count,unsigned char *D)
{
I2CNDAT=S_count;
U0CTL|=MST;
I2CSA=0X0048; // 主机发送目标地址:从地址
I2CTCTL |= I2CSTT+I2CTRX+ I2CSTP; // Initiate transfer - write to slave
while((I2CIFG & NACKIFG) == 0x02);

for(char k=0;k {
while ((I2CIFG & TXRDYIFG) == 0);
I2CDRB=TXdata[k];
}
while ((I2CTCTL & I2CSTP) == 0x02); // Wait for Stop Condition
delay(50);
I2CTCTL &= ~I2CTRX;
}
void delay(unsigned int num)
{
unsigned char i;
unsigned int l;
for(l=0;l for(i=0;i<200;i++);
}
void intIIC(void)
{
delay(50);
U0CTL=0;
U0CTL |= SWRST; // Reset USART state machine
U0CTL &= ~CHAR;
I2CIE&=~RXRDYIE;
I2CIFG=0;
P3SEL|=0X0A;
U0CTL|=I2C+SYNC;
U0CTL&=~I2CEN;
I2CTCTL|=I2CSSEL1;
I2COA=0X0050; // 本机地址
I2CIE|=RXRDYIE+OAIFG;
U0CTL|=I2CEN;
delay(50);
}
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 2/10 下一条
有奖直播 | AI之眼——安森美图像传感器 报名中
直播时间:2025年4月25日(周五)上午10:00-11:30
直播主题:AI之眼——安森美图像传感器
报名观看直播、直播间提问、填写问卷均有机会获得精美礼品!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 2

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表