OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3535|回复: 5

求助,msp430与LSM303DLH的IIC通信问题!

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2016-11-7
在线时间
1 小时
发表于 2016-11-7 16:30:34 | 显示全部楼层 |阅读模式
2金钱
调了好几天了没结果,现在的问题是收到的全是错误的OXff,LSM303_RecvACK()没有应答,地址左移、右移一位都试过,增加延时也尝试过无果,实在是没办法来寻求大神帮助
#include "msp430x22x4.h"
#define uchar unsigned char
#define uint unsigned int
int Byte_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);
uchar Random_Read(uchar SlaveAddress,uchar REG_Address);
#define         LSM303A_SlaveAddress   0x30        //定义器件在IIC总线中的从地址,(加速度)根据ALT  ADDRESS地址引脚不同修改 0x30(ADDRESS=0)                                 
#define         LSM303M_SlaveAddress   0x3C   //定义器件在IIC总线中的从地址,(磁场)根据ALT    ADDRESS地址引脚不同修改       
void delayms(uint x)
{
    uint a,b;
    for(a=x;a>0;a--)
      for(b=110;b>0;b--);
}
void main()
{
  WDTCTL = WDTPW + WDTHOLD;//关看门狗定时器
  uchar num1,num2;
  P3SEL &= ~(BIT0+BIT1);//P3.0  P3.1设置为普通IO口
  Byte_Write(LSM303A_SlaveAddress,0x20,0x27);
  delayms(10);
  //Byte_Write(LSM303M_SlaveAddress,0x02,0x00);
// delayms(10);
  num1=Random_Read(LSM303A_SlaveAddress,0x28);
  num2=Random_Read(LSM303A_SlaveAddress,0x29);
}
/************IIC初始化***************
分析:以P3.0控制SDA,P3.1控制SCL方式编写

连线:P3.0~SDA
      P3.1~SCL

************************************/
void delay()
{
  ;;
}
/*=============总线初始化==============*/
void init()
{
    P3DIR |= BIT0+BIT1;//P3.0  P3.1端口方向设置为输出
    P3OUT |= BIT1; //SCL=1,时钟线置高
    delay();
    P3OUT |= BIT0;//SDA=1,数据线置高
    delay();
}
/*==============启动信号===========*/
void start()  
{
    P3OUT |= BIT1;  //SCL=1
    P3OUT |= BIT0;  //SDA=1
    delay();//延时时间要大于4.7us
    P3OUT &= ~BIT0;  //SDA=0
    delay();//延时时间应大于4us
    P3OUT &= ~BIT1;  //SCL=0
}
/*============终止信号==========*/
void stop()  
{
    P3OUT |= BIT1;  //SCL=1
    P3OUT &= ~BIT0; //SDA=0
    delay();//延时时间应大于4us
    P3OUT |= BIT0;  //SDA=1
    delay();//延时时间应大于4.7us
}
/*============应答信号=============*/
void Ask()
{
    P3OUT &= ~BIT0; //SDA=0
    delay();
    P3OUT |= BIT1; //SCL=1
    delay();//延时时间应大于4us
    P3OUT &= ~BIT1; //SCL=0
    delay();
}
/*=============非应答信号============*/
void NoAsk()
{
    P3OUT |= BIT0; //SDA=1
    delay();
    P3OUT |= BIT1; //SCL=1
    delay();//应大于4us
    P3OUT &= ~BIT1; //SCL=0
    delay();
}
/*=============检测是否有应答信号============*/
int LSM303_RecvACK(){   
    int nTemp=1;  
    _NOP();
    _NOP();
    P3OUT &=~ BIT1;    //时钟置低;
    delay();
    P3OUT |= BIT0;    //数据置高
    delay();
    P3DIR &= ~BIT0;//SDA端口方向改为输入,因为此后要读入数据
    P3OUT |= BIT1;  //时钟置高
    delay();
    nTemp = (int)(P3IN&BIT0);        //获得SDA数据
    P3OUT&= ~BIT1;    //时钟置低;
    return (nTemp);
}
/*==========写一个字节=================*/
void write_byte(uchar Data)
{
    uchar i;//i用以计算发送的位数
    for(i=0;i<8;i++)
    {
      P3OUT &= ~BIT1; //SCL=0,SCL为低时,允许数据变化
      delay();
      if(Data&0x80)
        P3OUT|= BIT0;//送1位数据
      else
        P3OUT &= ~BIT0;
      Data<<=1;
      delay();
      P3OUT |= BIT1; //SCL=1,SCL为1时,要求数据稳定,将数据写入内存
      delay();
    }
    P3OUT &= ~BIT1; //SCL=0
    delay();
    //P3OUT |= BIT0; //SDA=1,释放数据线
    //delay();
}
/*=========读取一个字节=========
在每次SCL由0变1时,读取一位,
读8位,一字节
==============================*/
uchar read_byte()
{
    uchar i,temp=0;
    P3OUT &= ~BIT1; //SCL=0
    delay();
    P3OUT |= BIT0; //SDA=1
    delay();
    P3DIR &= ~BIT0;//SDA端口方向改为输入,因为此后要读入数据
    for(i=0;i<8;i++)
    {
       P3OUT |= BIT1; //SCL=1
       delay();
       temp<<=1;
       if(P3IN&BIT0)
          temp|=0x01;//获取P2.0口读回的数
     //  P3OUT &= ~BIT1; //SCL=0
     //  delay();
    }
    P3OUT &= ~BIT1; //SCL=0
    delay();
   // P3DIR |= BIT0; //读完1Byte数据,SDA口方向设置为输出
    return temp;
}
/********写操作*********/
int Byte_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
{
    int ntemp;
    P3DIR |= BIT0+BIT1;//P3.0  P3.1端口方向设置为输出
    start();//启动IIC
    //ntemp = LSM303_RecvACK();
    //if(ntemp) return 0;
    write_byte(SlaveAddress);//写器件地址,实验板上器件高4位为1010,低3位接了地,最地位为R/W,现在是写,最低位也为0
    ntemp = LSM303_RecvACK();
    if(ntemp) return 0;
    Ask();
    write_byte(REG_Address);//写数据地址,即欲将该数据存放于何处,address在0~255取值
    Ask();
    write_byte(REG_data);
    Ask();
    stop();
}
/********读操作***********************
说明:随机读取,程序分析参见操作时序
*************************************/
uchar Random_Read(uchar SlaveAddress,uchar REG_Address)
{
    P3DIR |= BIT0+BIT1;//P3.0  P3.1端口方向设置为输出
    uchar Data;
    start();
    write_byte(SlaveAddress);//写器件地址最低位为0
    Ask();
    write_byte(REG_Address);//广播数据存放的地方
    Ask(); //得到应答后开始读数据
    start();
    write_byte(SlaveAddress+1);//器件地址最低位为read,为1,表明此时24C02将发送数据,MCU接收数据
    Ask();
    Data=read_byte();//读取数据赋给Data
    NoAsk();
    stop();
    return Data;
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2016-11-7
在线时间
1 小时
 楼主| 发表于 2016-11-7 16:43:08 来自手机 | 显示全部楼层
RecvACK()中,sda随scl的变化而变化,其他子程序中没有出现这种情况
回复

使用道具 举报

11

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2015-8-10
在线时间
21 小时
发表于 2016-11-8 15:52:03 | 显示全部楼层
辣妹子辣 发表于 2016-11-7 16:43
RecvACK()中,sda随scl的变化而变化,其他子程序中没有出现这种情况

有没有示波器啊,有示波器可以抓一下波形看一下问题出在那里,只是分析程序的话感觉会想爆脑壳。
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2016-11-7
在线时间
1 小时
 楼主| 发表于 2016-11-10 16:46:14 | 显示全部楼层
黑色光线 发表于 2016-11-8 15:52
有没有示波器啊,有示波器可以抓一下波形看一下问题出在那里,只是分析程序的话感觉会想爆脑壳。

用逻辑分析仪看了,其他时序都对就是没有ACK
回复

使用道具 举报

11

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2015-8-10
在线时间
21 小时
发表于 2016-11-12 14:34:55 | 显示全部楼层
辣妹子辣 发表于 2016-11-10 16:46
用逻辑分析仪看了,其他时序都对就是没有ACK

你的delay();函数是空的,这样的延时时间够么?如果是空函数,会不会被编译器优化掉了?从而没有提供IIC时序足够的延时时间?没有接收到ACK就说明传感器没有正确识别你发送的命令,后面的数据是不会有变化的。
回复

使用道具 举报

1

主题

27

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-12-17
在线时间
1 小时
发表于 2016-12-17 10:33:20 | 显示全部楼层
有需要用到电子元器件的,都可以加我聊下,我们做了十几年了,或者你在苦苦寻找的料我们刚好就有,虽然说几率可能很小,但起码还有!给我们一次机会,也给自己一次机会!2355348525
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-6-8 12:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表