设为首页收藏本站

Discuz! Board

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 4171|回复: 2
打印 上一主题 下一主题

关于STM8s103f3p6使用IIC采集温湿度传感器HTU21D数据的问题

[复制链接]

2

主题

15

帖子

134

积分

注册会员

Rank: 2

积分
134
跳转到指定楼层
楼主
hgd123 发表于 2015-10-15 23:03:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "HTU21.H"
#include "stm8s_gpio.h"

/*================================================================
【名 称】字符表
【功 能】用于查表生成对应数字的ASCII码
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
const unsigned char Num[16] = {
                '0','1','2','3',
                '4','5','6','7',
                '8','9','A','B',
                'C','D','E','F' };


/*================================================================
【名 称】
【功 能】模拟IIC使用的引脚定义,注意要上拉电阻
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/

#define SCL(X)   (X==1?GPIO_WriteHigh(GPIOB, GPIO_PIN_4):GPIO_WriteLow(GPIOB, GPIO_PIN_4))
#define SDA(X)   (X==1?GPIO_WriteHigh(GPIOB, GPIO_PIN_5):GPIO_WriteLow(GPIOB, GPIO_PIN_5))

/*================================================================
【名 称】
【功 能】HTU21的I2C地址
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
#define HTU21ADDR 0x80

/*================================================================
【名 称】
【功 能】应答位电平定义
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
#define ACK       0
#define NACK      1

/*================================================================
【名 称】void Delay(unsigned int t)
【功 能】延时长
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
void Delay(unsigned int t)
{
  unsigned char i;
  while(t--)
  {
    for(i=0;i<200;i++);
  }                                          
}

//***********************以下是模拟I2C函数****************************//

/*================================================================
【名 称】void I2CDelay (unsigned char t)
【功 能】模拟IIC用的短延时
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
void I2CDelay (unsigned char t)
{
  while(t--);
}

/*================================================================
【名 称】void I2CInit(void)
【功 能】I2C初始化,空闲状态
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
void I2CInit(void)
{
  SDA(1);
  SCL(1);
}

/*================================================================
【名 称】void I2CStart(void)
【功 能】I2C起始信号
【备 注】SCL、SDA同为高,SDA跳变成低之后,SCL跳变成低
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
void I2CStart(void)
{
  SDA(1);
  SCL(1);
  I2CDelay(10);
  SDA(0);
  I2CDelay(20);
  SCL(0);
  I2CDelay(20);
}

/*================================================================
【名 称】void I2CStop(void)
【功 能】I2C停止信号
【备 注】SCL、SDA同为低,SCL跳变成高之后,SDA跳变成高
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
void I2CStop(void)
{
  SDA(0);
  SCL(0);
  I2CDelay(10);
  SCL(1);
  I2CDelay(10);
  SDA(1);
  I2CDelay(10);
}

/*================================================================
【名 称】unsigned char I2CWRByte(unsigned char WRByte)
【功 能】I2C写一个字节数据,返回ACK或者NACK
【备 注】从高到低,依次发送
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
unsigned char I2CWRByte(unsigned char WRByte)
{
  unsigned char i;
  SCL(0);
  for(i=0;i<8;i++)
  {
    if(WRByte&0x80)
    {
      SDA(1);       
    }
    else
    {
      SDA(0);
    }
    I2CDelay(10);
    SCL(1);        //输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样
    I2CDelay(50);
    SCL(0);
    I2CDelay(10);
    WRByte <<= 1;
  }
  SDA(1);
  SCL(1);
  I2CDelay(20);

  //if(SDA==1)        //SDA为高,收到NACK
  if(GPIO_ReadOutputPin(GPIOB,GPIO_PIN_5)==1)
  {
    SCL(0);
    I2CDelay(50);
    return NACK;
  }
  else                 //SDA为低,收到NACK
  {
    SCL(0);
    I2CDelay(50);
    return ACK;
  }
}

/*================================================================
【名 称】unsigned char I2CRDByte(unsigned char AckValue)
【功 能】I2C读一个字节数据,入口参数用于控制应答状态,ACK或者NACK
【备 注】从高到低,依次接收
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
unsigned char I2CRDByte(unsigned char AckValue)
{
  unsigned char i,RDByte=0;
  SCL(0);
  SDA(1);                //释放总线       
  for(i=0;i<8;i++)
  {
    RDByte <<= 1;        //移位
    SCL(1);        //给出上升沿
    I2CDelay(30);        //延时等待信号稳定

    //if(SDA==1)         //采样获取数据
    if(GPIO_ReadOutputPin(GPIOB,GPIO_PIN_5)==1)
    {
      RDByte |= 0x01;
    }
    else
    {
      RDByte &= 0xfe;
    }
    SCL(0);           //下降沿,从机给出下一位值
    I2CDelay(10);
  }
  SDA(AckValue);        //应答状态
  I2CDelay(10);
  SCL(1);                        
  I2CDelay(50);
  SCL(0);
  SDA(1);
  I2CDelay(1);
  return RDByte;
}

/*================================================================
【名 称】void HTU21Init(void)
【功 能】HTU21初始化函数,主函数中调用
【备 注】从高到低,依次接收
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
void HTU21Init(void)
{
  I2CInit();      //I2C初始化
  I2CStart();     //启动I2C
  I2CWRByte(HTU21ADDR&0xfe);  //写HTU21I2C地址
  I2CWRByte(0xfe);
  I2CStop();      //停I2C
  Delay(600);     //短延时
}

/*================================================================
【名 称】long ReadHtu21(char whatdo)
【功 能】读取函数函数
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
long ReadHtu21(char whatdo)   //whatdo 可替换为:0xf3、0xf5
{
  unsigned long temp;
  unsigned char Humidity,HumidityH,HumidityL;
  unsigned long wendu;

  I2CStart();    //IIC起始信号
  if(I2CWRByte(HTU21ADDR & 0xfe)==ACK)    //0xfe:软复位命令
  {
    if(I2CWRByte(whatdo)==ACK)      
    //IIC写一个字节的数据,返回ACK或者NACK(whatdo可以是:0xf3、0xf5)
    {
      do
      {
        Delay(30);
        I2CStart();
      }
      while(I2CWRByte(HTU21ADDR|0x01)==NACK);

      HumidityH = I2CRDByte(ACK);
      HumidityL = I2CRDByte(ACK);
      I2CRDByte(NACK);
      I2CStop();
      HumidityL &= 0xfc;
      temp = HumidityH*256+HumidityL;

      if (whatdo==((char)0xf5))
      {
        Humidity = (unsigned char)((temp*125)/65536-6)%0xff;
        return Humidity;
      }
      else
      {
        temp=((long)17572)*temp;
        temp=temp/((long)65536);
        wendu =temp-((long)4685);
        return wendu;                //输出
      }
      //        SendStrings("Humidity:");        //输出到串口
      //        SendByte(Num2Ascii[Humidity%100/10]);
      //        SendByte(Num2Ascii[Humidity%10]);
      //        SendByte('%');
      //        SendByte('\n');
    }
  }
  return 0;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖
回复

使用道具 举报

2

主题

15

帖子

134

积分

注册会员

Rank: 2

积分
134
沙发
 楼主| hgd123 发表于 2015-10-15 23:07:41 | 只看该作者
这个watch窗口中的两个数值,一直是这两个值,不变化,请问是什么原因?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

2

主题

15

帖子

134

积分

注册会员

Rank: 2

积分
134
板凳
 楼主| hgd123 发表于 2015-10-15 23:11:32 | 只看该作者
这两张图,是我用示波器检测到的 时钟与数据信号的波形,不知道是否正确?
我想问的问题主要是:我的程序是不是哪里有问题?
我一直找不出来,烦请会的大神能不吝赐教,谢谢!!!!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

Archiver|手机版|小黑屋|Comsenz Inc.   

GMT+8, 2024-11-23 08:38 , Processed in 0.122444 second(s), 29 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

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