hgd123 发表于 2015-10-15 23:03:28

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

#include "HTU21.H"
#include "stm8s_gpio.h"

/*================================================================
【名 称】字符表
【功 能】用于查表生成对应数字的ASCII码
【备 注】
【作 者】123
【时 间】2015年10月14日11:03:34
================================================================*/
const unsigned char Num = {
                '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);
      //        SendByte(Num2Ascii);
      //        SendByte('%');
      //        SendByte('\n');
    }
}
return 0;
}

hgd123 发表于 2015-10-15 23:07:41

这个watch窗口中的两个数值,一直是这两个值,不变化,请问是什么原因?

hgd123 发表于 2015-10-15 23:11:32

这两张图,是我用示波器检测到的 时钟与数据信号的波形,不知道是否正确?
我想问的问题主要是:我的程序是不是哪里有问题?
我一直找不出来,烦请会的大神能不吝赐教,谢谢!!!!!
页: [1]
查看完整版本: 关于STM8s103f3p6使用IIC采集温湿度传感器HTU21D数据的问题