4501|5

4

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

MSP430f149 I2C通讯(hut21d温湿度)读数总是返回0xff [复制链接]

大家好:我最近在做MSP430F149的I2C通讯, 从HTU21D模块中读取湿度,用P3.3和P3.3口做SCL和SDA。从单片机向模块写地址和命令时,模块能正确响应,即能返回ACK,但是读到的数据都是0xff。求高手解答~!万分感激~!
下面是我编写的代码,只读取湿度:

#include
#include "config.h"

#define SDA_1   P3OUT |= BIT3
#define SDA_0   P3OUT &= ~BIT3
#define SCL_1   P3OUT |= BIT2
#define SCL_0   P3OUT &= ~BIT2
#define DIR_IN  P3DIR &= ~BIT3; SDA_1;
#define DIR_OUT  P3DIR |= BIT3;
#define SDA_IN  ((P3IN>>3)&0x01)

uchar ack; //0 为ACK,1 为NACK
uint shidu;

void I2C_init(void)
{
   P3SEL=0;
   P3DIR |= BIT2+BIT3;  //输出
}


void I2C_Start()         
{
  DIR_OUT;
  SDA_1;      //发送起始条件的数据信号
  SCL_1;
  delay_us(10);       //起始条件建立时间大于4.7us,延时
  SDA_0;      //发送起始信号
  delay_us(10);      //起始条件建立时间大于4us,延时
  SCL_0;     //钳住I2C总线准备发送或接收数据
  delay_us(10);
}

void I2C_Stop()
{
  DIR_OUT;
  SDA_0;      //发送结束条件的数据信号
  delay_us(10);
  SCL_1;      //发送结束条件的时钟信号
  delay_us(10);      //结束条件建立时间大于4us,延时
  SDA_1;      //发送I2C总线结束信号
  delay_us(10);
}


//完成IIC的主机应答操作
void Mack()
{
  DIR_OUT;
  SDA_0;      //发送结束条件的数据信号
  delay_us(10);
  SCL_1;      //发送结束条件的时钟信号
  delay_us(10);      //结束条件建立时间大于4us,延时
  SCL_0;
  delay_us(10);
  SDA_1;
  delay_us(10);
}


//完成IIC的主机无应答操作
void MNack()
{
  DIR_OUT;
  SDA_1;     
  delay_us(10);
  SCL_1;   
  delay_us(10);   
  SCL_0;
  delay_us(10);
  SDA_0;
  delay_us(10);
}

//从机发送的应答信号
void check()
{
    SDA_1;      //释放数据线
    delay_us(20);
    SCL_1;      //发送结束条件的时钟信号
    delay_us(20);
    DIR_IN;
    ack=SDA_IN;
    SCL_0;
    delay_us(20);
    DIR_OUT;
}         

uchar I2C_writebyte(uchar a)
{
  uchar i;
  DIR_OUT;
  //SDA_0;
  //delay_us(10);
  for(i=0;i<8;i++)
  {
    if((a<     {
      SDA_1;
    }
    else
    {
      SDA_0;
    }
    delay_us(20);
    SCL_1;
    delay_us(20);   
    SCL_0;
    delay_us(20);
  }
  SCL_0;
  delay_us(20);
  check();
  return ack;
}

uchar I2C_readbyte(void)//读一个字节  
{  
    uchar i,k; //i读取位数,k存储读到的字节
    k=0x00;
    DIR_IN;
    for(i=0;i<8;i++)  
    {   

        SCL_0;//拉低SCL,使发送端可以把数据放在SDA上
        delay_us(20);
        SDA_1;//释放数据线
        delay_us(20);
        SCL_1;//上升沿时,IIC设备将数据放在sda线上,并在高电平期间数据已经稳定,可以接收啦  
        delay_us(20);
        //DIR_IN;
        k=(k<<1);
        if(SDA_IN==0)
        {
          k=k+0x00;
        }
        else
        {k=k+0x01;}
        //DIR_OUT;
        SCL_0;//拉低SCL,使发送端可以把数据放在SDA上
        delay_us(20);
    }   
    return k;
}  


ulong I2C_readword(uchar address)//读取一个16为数字
{  
    ulong date;
    uchar MSB,LSB;  
    I2C_Start();//启动  
    if(I2C_writebyte(0x80)==0)
    {
       if(I2C_writebyte(address)==0) //发送芯片内地址
       {
          delay_ms(20);
          I2C_Start();//启动
          while(I2C_writebyte(0x81)==0);
          MSB=I2C_readbyte();//获取数据  
          Mack();
          LSB=I2C_readbyte();//获取数据
          MNack();
          I2C_Stop();//停止  
       }
      else
      {I2C_readword(address);}
    }
    else
    {
      I2C_readword(address);
    }

   date=(ulong)MSB*256+(LSB&0xfc);
   delay_us(20);
   return date;//返回数据
}



void main()
{
   WDT_Init();                                   //看门狗设置
   Clock_Init();                                 //系统时钟设置
   I2C_init();
   Close_LED();                                  //关闭LED数码管,避免显示乱码
   delay_ms(100);                                //延时100ms
   LCD_init();                                   //液晶参数初始化设置
   LCD_clear();                                  //清屏
   delay_us(5);
   while(1)
   {
     ulong m=I2C_readword(0xf5);
     m=m*1250/65536-60;
     shidu=(uint)m;  
   }
}




最新回复

#include "config.h"这个文件里写的是什么呀  详情 回复 发表于 2016-7-26 12:01
 
点赞 关注

回复
举报

2549

帖子

0

TA的资源

五彩晶圆(初级)

推荐
 
看了几遍,觉得这个读时序是不是乱了啊,在写完地址后再次启动。。。。你把date直接复制0,看最后的数据是不是读出来的

赞赏

1

查看全部赞赏

 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
数码小叶 发表于 2016-3-21 10:41
看了几遍,觉得这个读时序是不是乱了啊,在写完地址后再次启动。。。。你把date直接复制0,看最后的数据是 ...


谢谢~!
确实是 写完地址后再次启动 时出错了。修改后可以正常读数了~!

修改后的I2C_readword(uchar)函数是:

ulong I2C_readword(uchar address)//读取一个16位数字
{  
    ulong date;
    uchar MSB,LSB;  
    I2C_Start();//启动  
    if(I2C_writebyte(0x80)==0)
    {
       if(I2C_writebyte(address)==0) //发送芯片内地址
       {
          delay_ms(10);
          I2C_Start();//启动
          while(I2C_writebyte(0x81)==1)
          {
            delay_us(100);
            I2C_Start();
          }

          MSB=I2C_readbyte();//获取数据  
          Mack();
          LSB=I2C_readbyte();//获取数据
          MNack();
          I2C_Stop();//停止  
          LSB=LSB&0xfc;
       }
      else
      {I2C_readword(address);}
    }
    else
    {
      I2C_readword(address);
    }
   date=(ulong)MSB*256+LSB;
   delay_us(10);
   return date;//返回数据
}

点评

问题解决了就好  详情 回复 发表于 2016-3-22 07:57
 
 
 

回复

2549

帖子

0

TA的资源

五彩晶圆(初级)

4
 
Mango_baby 发表于 2016-3-21 22:22
谢谢~!
确实是 写完地址后再次启动 时出错了。修改后可以正常读数了~!

修改后的I2C_rea ...

问题解决了就好
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(初级)

5
 
我想请问一下,你做的基于MSP430F149测湿度的,用了几个传感器芯片
 
个人签名时间是无声的锉刀
 
 

回复

31

帖子

0

TA的资源

一粒金砂(中级)

6
 
#include "config.h"这个文件里写的是什么呀
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表