Discuz! Board
标题:
关于STM8s103f3p6使用IIC采集温湿度传感器HTU21D数据的问题
[打印本页]
作者:
hgd123
时间:
2015-10-15 23:03
标题:
关于STM8s103f3p6使用IIC采集温湿度传感器HTU21D数据的问题
#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;
}
作者:
hgd123
时间:
2015-10-15 23:07
这个watch窗口中的两个数值,一直是这两个值,不变化,请问是什么原因?
作者:
hgd123
时间:
2015-10-15 23:11
这两张图,是我用示波器检测到的 时钟与数据信号的波形,不知道是否正确?
我想问的问题主要是:我的程序是不是哪里有问题?
我一直找不出来,烦请会的大神能不吝赐教,谢谢!!!!!
欢迎光临 Discuz! Board (http://qfv8.com/)
Powered by Discuz! X3