7579|19

11

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

MSP430 I2C通讯的疑问 [复制链接]

5芯积分
本帖最后由 尘埃未定 于 2014-12-12 23:20 编辑

大家好:
        我最近在做亮片MSP430之间的I2C通讯,一个做主机从从机读取数据,使用MSP430自带的P1.6,P1.7口分别做SCL和SDA,使用MSP430自带的I2C接口功能,能够完成通讯,但是如果主机使用IO口模拟I2C通讯,发现作为从机的MSP430对地址没有应答,奇怪的是竟然连主机产生的最后一个SCL脉冲也消失了;但是如果主机向从机写数据,从机对地址就有相应,求高手解答,谢谢!

1.jpg (1.4 MB, 下载次数: 0)

从机无响应

从机无响应

2.jpg (1.15 MB, 下载次数: 2)

从机有响应

从机有响应

最佳答案

查看完整内容

代码没看完 提一下 楼主有注意过上拉电阻的阻值没 还有总线的速度,降下来试试看

最新回复

请问你用的硬件I2C的程序还在吗,在的话能发给我一份麽,我找了好几个版本都卡在while (UCB0CTL1 & UCTXSTT);找不出问题。。。  详情 回复 发表于 2017-5-4 17:38
 
点赞 关注

回复
举报

755

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
I2C总线在空闲的时候应该为高的吧?你量一下硬件I2C的波形看看。

点评

请版主看第一个图,地址发送完毕后,SDA是被从机拉低了,但是响应位的SCL却丢失了一个脉冲,这个脉冲程序中我是有的。在请看第二个图,地址不变,我将最后一位读指令换成写指令,从机就有了响应,下图比上图多一个脉  详情 回复 发表于 2014-12-13 23:52
 
 

回复

3471

帖子

13

TA的资源

五彩晶圆(高级)

板凳
 
时钟默认应该为高电平。从机没响应,可能是你没有在适当的时候释放数据线~~~~~~
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(中级)

4
 
楼主竟然可以使用硬件I2C,为什么还要使用模拟。主机模拟I2C程序应该有问题吧,可以贴上来看看
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

5
 
这个程序之前用在ADS1100上没有问题,将主函数略加修改用在SHT21和CPS131气压传感器上也没有问题,但是不知为何在做I2C从机的MSP430上却不行,波形上在地址的响应上少了一个脉冲,但是程序中SCL是产生了9个,而地址这里却只出现了8个脉冲,如果我将地址有意写错,SCL丢失的脉冲就出来了,知识SDA维持在高电平而已。不明白用在ADS1100上的程序为什么用在MSP430上就不对,如果我在程序中添加一个脉冲这里就对了,但是程序中的脉冲个数始终和波形的脉冲个数对不上。ADS1100和MSP430的从机地址都是0x48。
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

6
 
deweyled 发表于 2014-12-12 23:32
I2C总线在空闲的时候应该为高的吧?你量一下硬件I2C的波形看看。
请版主看第一个图,地址发送完毕后,SDA是被从机拉低了,但是响应位的SCL却丢失了一个脉冲,这个脉冲程序中我是有的。在请看第二个图,地址不变,我将最后一位读指令换成写指令,从机就有了响应,下图比上图多一个脉冲。
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

7
 
程序如下:
#include

#define SCL_H  SCL_IN
#define SCL_L  SCLPullDown()
#define SDA_H  SDA_IN
#define SDA_L  SDAPullDown()

#define SCL_OUT  P1DIR |= BIT6
#define SDA_OUT  P1DIR |= BIT7
#define SDA_IN   P1DIR &= ~BIT7
#define SCL_IN   P1DIR &= ~BIT6

#define SDA_VAL  P1IN & BIT7
#define SCL_VAL  P1IN & BIT6

#define ACK  0X00
#define NACK 0X01
#define ADSADDRESS 0X01


void InitializeClock();
void Start();
void Stop();
unsigned char WriteByte(unsigned char command);
unsigned char ReadByte();
unsigned char CheckACK();
void MACK();
void NMACK();
void Write1();
void Write0();
void SDAPullDown();
void SCLPullDown();

void UartRegCfg();
void UartGpioCfg();
void UartInit();
void UARTPutChar(unsigned char cTX);
void UARTPutstring( char *str);



void main(void) {

        volatile float voltage = 0;
        volatile unsigned char MSB, LSB, parameters;
        volatile unsigned int msb, lsb;
        volatile char VOL[4];
        volatile unsigned int vol;
        UartInit();
        WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer
        InitializeClock();
        while(1) {
                Start();
                if(WriteByte(0X91) == ACK) {
                        MSB =ReadByte();
                        MACK();
                        LSB = ReadByte();
                        NMACK();
                        Stop();
                }
                _delay_cycles(800000);
        }
}

void InitializeClock(){
        BCSCTL1 = CALBC1_8MHZ;
        DCOCTL = CALDCO_8MHZ;
}


void Start() {

        SDA_H;
        _delay_cycles(100);
        SCL_H;
        _delay_cycles(100);
        SDA_L;
        _delay_cycles(100);
        SCL_L;
        _delay_cycles(100);

}

void Stop() {


        SDA_L;
        _delay_cycles(100);
        SCL_H;
        _delay_cycles(100);
        SDA_H;
        _delay_cycles(100);
        SCL_L;
        _delay_cycles(100);
}

unsigned char WriteByte(unsigned char command) {

        unsigned char temp, count, ACKFlag;

        for (count = 8; count > 0; count--) {
                temp = command & 0x80;
                if (temp)
                        Write1();
                else
                        Write0();
                command <<= 1;
        }
        ACKFlag = CheckACK();
        return ACKFlag;
}

unsigned char CheckACK() {

        unsigned char flag;

        SDA_IN;

        SCL_L;
        _delay_cycles(100);
        SCL_H;
        _delay_cycles(100);
        flag = SDA_VAL;
        SCL_L;
        _delay_cycles(100);
        if(flag != 0)
                return NACK;
        else
                return ACK;

}



unsigned char ReadByte() {

        unsigned char count, flag;
        unsigned char data = 0;

        SDA_IN;
        SCL_L;

        for(count = 8; count > 0; count--) {

                _delay_cycles(100);
                SCL_H;
                _delay_cycles(100);
                flag = SDA_VAL;
                SCL_L;
                if(flag) {
                        data |= 1;
                }
                if(count == 1) {
                        SDA_OUT;
                        break;
                }
                data <<= 1;
        }
        return data;
}

/*****************************************************************
【函数名称】Mack
【功    能】完成IIC的主机应答操作
【参    数】无
【返回值  】无
*****************************************************************/
void MACK(void)
{
    SDA_L;
    __delay_cycles(100);//_NOP(); _NOP();
    SCL_L;
    _delay_cycles(100);
    SCL_H;
    __delay_cycles(100);//Delay();
    SCL_L;
    __delay_cycles(100);//_NOP(); _NOP();
}

/*****************************************************************
【函数名称】MNack
【功    能】完成IIC的主机无应答操作
【参    数】无
【返回值  】无
*****************************************************************/
void NMACK(void)
{
    SDA_H;
    __delay_cycles(100);//_NOP(); _NOP();
    SCL_H;
    __delay_cycles(100);//Delay();
    SCL_L;
    __delay_cycles(100);//_NOP(); _NOP();
}

void Write1(){


        SDA_H;
        _delay_cycles(100);
        SCL_H;
        _delay_cycles(100);
        SCL_L;

}

void Write0(){

        SDA_L;
        _delay_cycles(100);
        SCL_H;
        _delay_cycles(100);
        SCL_L;
}

void SDAPullDown() {

        SDA_OUT;
        P1OUT &= ~BIT6;
}

void SCLPullDown() {

        SCL_OUT;
        P1OUT &= ~BIT7;
}






点评

代码很详细,但是不说代码是从机还是主机的代码,让看的人来判断,纯粹是增加别人的阅读负担。I2C时序那么关键,代码却缺少相关部分的注释,没那个耐心仔细看下去帮你分析。等你完善了上面这些内容再考虑看你的代码  详情 回复 发表于 2014-12-16 10:25
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

8
 
出问题的地方是 if(WriteByte(0X91) == ACK) ,但是检查了半天,怎么也看不出哪里不对,把程序放到ADS1100上用也没问题。
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

9
 
有人知道问题出在哪里吗?
 
 
 

回复

755

帖子

0

TA的资源

五彩晶圆(初级)

10
 
根据你的描述,这个模拟的I2CMaster是可以正常访问 ADS1100和其他一些Slave的,那是不是应该查查你的430实现的I2Cslave是不是有问题?

点评

这个应该不是吧,因为使用430自带的I2C接口做主机读取这个430的从机就没问题,他们之间就差这个地址的响应脉冲,甚是奇怪  详情 回复 发表于 2014-12-14 20:12
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

11
 
deweyled 发表于 2014-12-14 14:56
根据你的描述,这个模拟的I2CMaster是可以正常访问 ADS1100和其他一些Slave的,那是不是应该查查你的430实现的I2Cslave是不是有问题?
这个应该不是吧,因为使用430自带的I2C接口做主机读取这个430的从机就没问题,他们之间就差这个地址的响应脉冲,甚是奇怪
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

12
 
到现在也没有解决,请问各位有没有什么建议?
 
 
 

回复

1193

帖子

0

TA的资源

纯净的硅(高级)

13
 
第一幅图,缺乏ACK/NACK位
作为I2C通信,你只发一个地址,然后不发数据有啥用呢?
I2C协议中,时钟由主机控制,总线空闲的时候你把时钟拉低了,那么从机即使有响应也无法发送过来。如果从机处于忙碌中无法响应主机的数据请求,那么从机会主动把时钟线拉低,,主机无法发送完整的时钟信号,于是I2C传输会暂停,这确保了I2C数据的完整性。
 
 
 

回复

1193

帖子

0

TA的资源

纯净的硅(高级)

14
 
尘埃未定 发表于 2014-12-13 23:56
程序如下:
#include  

#define SCL_H  SCL_IN
#define SCL_L  SCLPullDown()
#define SDA_H  SDA_IN
#define SDA_L  SDAPullDown()

#define SCL_OUT  P1DIR |= BIT6
#define SDA_OUT  P1DIR |= BIT7
#define SDA_IN   P1DIR &= ~BIT7
#define SCL_IN   P1DIR &= ~BIT6

#define SDA_VAL  P1IN & BIT7
#define SCL_VAL  P1IN & BIT6

#define ACK  0X00
#define NACK 0X01
#define ADSADDRESS 0X01


void InitializeClock();
void Start();
void Stop();
unsigned char WriteByte(unsigned char command);
unsigned char ReadByte();
unsigned char CheckACK();
void MACK();
void NMACK();
void Write1();
void Write0();
void SDAPullDown();
void SCLPullDown();

void UartRegCfg();
void UartGpioCfg();
void UartInit();
void UARTPutChar(unsigned char cTX);
void UARTPutstring( char *str);



void main(void) {

        volatile float voltage = 0;
        volatile unsigned char MSB, LSB, parameters;
        volatile unsigned int msb, lsb;
        volatile char VOL[4];
        volatile unsigned int vol;
        UartInit();
        WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer
        InitializeClock();
        while(1) {
                Start();
                if(WriteByte(0X91) == ACK) {
                        MSB =ReadByte();
                        MACK();
                        LSB = ReadByte();
                        NMACK();
                        Stop();
                }
                _delay_cycles(800000);
        }
}

void InitializeClock(){
        BCSCTL1 = CALBC1_8MHZ;
        DCOCTL = CALDCO_8MHZ;
}


void Start() {

        SDA_H;
        _delay_cycles(100);
        SCL_H;
        _delay_cycles(100);
        SDA_L;
        _delay_cycles(100);
        SCL_L;
        _delay_cycles(100);

}

void Stop() {


        SDA_L;
        _delay_cycles(100);
        SCL_H;
        _delay_cycles(100);
        SDA_H;
        _delay_cycles(100);
        SCL_L;
        _delay_cycles(100);
}

unsigned char WriteByte(unsigned char command) {

        unsigned char temp, count, ACKFlag;

        for (count = 8; count > 0; count--) {
                temp = command & 0x80;
                if (temp)
                        Write1();
                else
                        Write0();
                command
代码很详细,但是不说代码是从机还是主机的代码,让看的人来判断,纯粹是增加别人的阅读负担。I2C时序那么关键,代码却缺少相关部分的注释,没那个耐心仔细看下去帮你分析。等你完善了上面这些内容再考虑看你的代码。
 
 
 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

15
 
代码没看完
提一下
楼主有注意过上拉电阻的阻值没
还有总线的速度,降下来试试看

点评

上拉电阻为4.7k,总线速度降低后可以响应了,感谢!  详情 回复 发表于 2014-12-17 11:21
 
个人签名

So TM what......?

 

 

回复

85

帖子

1

TA的资源

一粒金砂(中级)

16
 
我没仔细看你的程序,之前我在写SPI和IIC的时候遇到些问题,我也是用示波器查看波形,从机也是没有反应,我把我的心得发给你看下!

IIC写字节:第八个下降沿脉冲后,(可以再次将数据线拉高,即释放数据线,该步骤可以省略),SDA的IO口改为输入,ACK应答信号传递,将数据线拉低(反应速度很快),第九个下降沿脉冲后,数据线再次释放。至此,完成一次单字节数据写入过程。
IIC读字节:之前为写入“读地址操作”,第八个下降沿脉冲后,数据线拉高,释放数据线,SDA的IO口改为输入,ACK应答信号传递,第九个下降沿脉冲后,第一个数据位已经接收到!!此时将数据线改为默认设置——输出。然后进入“读字节”函数,SDA的IO口改为输入,再下一个下降沿脉冲来临之前先读取数据

看到没有??读字节跟写字节是有变化的!我也是后来通讯成功的时候发现数据不对头,另一个研发告诉我,数据已经收到了,只是我没有发现。你看看,是不是你的问题。

点评

感谢您的细致分析,我得程序和这个分析基本上是一致的,今天调试的时候尝试把时钟放慢,结果正常了,这样看来应该是速率的问题。感谢各位的无私帮助!  详情 回复 发表于 2014-12-17 11:24
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

17
 
本帖最后由 尘埃未定 于 2014-12-17 11:47 编辑

感谢大家的耐心解答!
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

18
 
本帖最后由 尘埃未定 于 2014-12-17 11:47 编辑

感谢大家的耐心解答!
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

19
 
弱弱的问一句,结贴怎么操作?
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

20
 
请问你用的硬件I2C的程序还在吗,在的话能发给我一份麽,我找了好几个版本都卡在while (UCB0CTL1 & UCTXSTT);找不出问题。。。
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

北京市海淀区中关村大街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
快速回复 返回顶部 返回列表