最近在编写sht71的驱动程序,用的板子是stm32 107,但是完成之后运行,却不出结果,就用示波器检测SCK引脚的波形,发现差的太大,几乎是2s才翻转一次,而程序中时2us变化一次,为什么会出现这种问题,是延时太短了吗,还是板子的引脚选择有问题?
下面将我写的驱动程序贴出来,希望高手出手援助
/*******************************************************************************
*时钟线:PC.6
*数据线:PC.7
*采用温度14位,湿度12位
*******************************************************************************/
/*****包含头文件*******/
#include "stm32f10x.h"
#include "SHT71.h"
#include "Delay.h"
#include "Common.h"
#include "math.h" //Keil library
#include "stdio.h" //Keil library
/*****宏定义*******/
#define SHT_noACK 0 //用于判断是否结束SHT71通讯
#define SHT_ACK 1 //结束数据传输// r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1E //000 1111 0
#define SHT_SCK_1 PCout(6)=1 //SHT_SCK=1
#define SHT_SCK_0 PCout(6)=0 //SHT_SCK=0
#define SHT_DAT_1 PCout(7)=1 //SHT_DAT=1
#define SHT_DAT_0 PCout(7)=0 //SHT_DAT=0
#define Read_SHT_Dat PAin(7)
#define SHT_DAT_OUT {GPIOC->CRL&=0x0FFFFFFF;GPIOC->CRL|=0x50000000;} //开漏输出
#define SHT_DAT_IN {GPIOC->CRL&=0x0FFFFFFF;GPIOC->CRL|=0x40000000;} //浮空输入
/* Private function prototypes -----------------------------------------------*/
void SHT_Tra_Sta(void); //SHT传输起始
void SHT_Tra_Res(void); //SHT传输重启
u8 SHT_Wri_Byte(u8 value); //向SHT写入一个字节
u8 SHT_Rea_Byte(u8 ack); //从SHT读入一个字节
u8 SHT_Sof_Res(void); //SHT软件复位
u8 SHT_Rea_Sta(u8 *p_value, u8 *p_checksum); //读状态寄存器
u8 SHT_Wri_Sta(u8 *p_value); //写状态寄存器
u8 SHT_Mea_TH(u8 *p_value,u8 *p_checksum,u8 mode); //开始测量
void SHT_Cal_TH(float *p_humidity,float *p_temperature); //计算温、湿度值
/* Private functions ---------------------------------------------------------*/
//SHT传输起始
//------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// DAT: |_______|
// ___ ___
// SCK : ___| |___| |______
void SHT_Tra_Sta(void)
{
SHT_DAT_OUT;
SHT_DAT_1;
SHT_SCK_0;
Delay_us(2);
SHT_SCK_1;
Delay_us(2);
SHT_DAT_0;
Delay_us(2);
SHT_SCK_0;
Delay_us(5);
SHT_SCK_1;
Delay_us(2);
SHT_DAT_1;
Delay_us(2);
SHT_SCK_0;
}
//SHT传输重启
//------------------------------------------------------------------------------
// communication reset: DAT_line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DAT: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
void SHT_Tra_Res(void)
{
u8 temp;
SHT_DAT_OUT;
SHT_DAT_1;
SHT_SCK_0;
Delay_us(1);
for(temp=0;temp<9;temp++) //至少9个Clock
{
SHT_SCK_1;
Delay_us(1);
SHT_SCK_0;
Delay_us(1);
}
SHT_Tra_Sta();
}
//向SHT写入一个字节
//------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
u8 SHT_Wri_Byte(u8 value)
{
u8 _error=0;
u8 temp;
SHT_DAT_OUT;
for(temp=0x80;temp>0;temp/=2)
{
if(temp&value)
SHT_DAT_1;
else
SHT_DAT_0;
SHT_SCK_1;
Delay_us(5);
SHT_SCK_0;
}
//等待响应
//SHT_DAT_OUT;
SHT_DAT_1;
Delay_us(2);
SHT_DAT_IN;
SHT_SCK_1;
Delay_us(2);
_error=Read_SHT_Dat;
SHT_SCK_0;
Delay_us(1);
return _error; //error=1时无响应
}
//从SHT读入一个字节
//------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
u8 SHT_Rea_Byte(u8 ack)
{
u8 temp;
u8 val=0,read_temp;
//释放数据线
SHT_DAT_OUT;
SHT_DAT_1;
Delay_us(1);
SHT_DAT_IN;
for(temp=0x80;temp>0;temp/=2)
{
SHT_SCK_1;
Delay_us(2);
read_temp=Read_SHT_Dat;
if(read_temp)
val|=temp;
SHT_SCK_0;
Delay_us(2);
}
//是否停止传输
SHT_DAT_OUT;
//继续
if(ack) SHT_DAT_0;
//停止
else SHT_DAT_1;
Delay_ms(5);
SHT_SCK_1;
Delay_us(5);
SHT_SCK_0;
SHT_DAT_1;
Delay_us(1);
return val;
}
//SHT软件复位
//------------------------------------------------------------------------------
// resets the sensor by a softreset
u8 SHT_Sof_Res(void)
{
u8 _error=0;
SHT_Tra_Res(); //reset communication
_error+=SHT_Wri_Byte(RESET); //send RESET-command to sensor
return _error; //error=1 in case of no response form the sensor
}
//读状态寄存器
//------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
u8 SHT_Rea_Sta(u8 *p_value,u8 *p_checksum)
{
u8 _error=0;
SHT_Tra_Sta(); //transmission start
_error=SHT_Wri_Byte(STATUS_REG_R); //send command to sensor
*p_value=SHT_Rea_Byte(SHT_ACK); //read status register (8-bit)
*p_checksum=SHT_Rea_Byte(SHT_noACK); //read checksum (8-bit)
return _error; //error=1 in case of no response form the sensor
}
//写状态寄存器
//------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
u8 SHT_Wri_Sta(u8 *p_value)
{
u8 _error=0;
SHT_Tra_Sta(); //transmission start
_error+=SHT_Wri_Byte(STATUS_REG_W); //send command to sensor
_error+=SHT_Wri_Byte(*p_value); //send value of status register
return _error; //error>=1 in case of no response form the sensor
}
//开始测量
//------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
u8 SHT_Mea_TH(u8 *p_value,u8 *p_checksum,u8 mode)
{
u8 _error=0;
u8 read_temp;
unsigned int temp;
SHT_Tra_Sta(); //transmission start
//send command to sensor
switch(mode)
{
case 0:
_error+=SHT_Wri_Byte(MEASURE_TEMP);
break;
case 1:
_error+=SHT_Wri_Byte(MEASURE_HUMI);
break;
default:
break;
}
/*准备接收*/
SHT_DAT_IN; //数据线为输入
/*wait until sensor has finished the measurement or timeout (~2 sec.) is reached*/
for(temp=0;temp<65535;temp++)
{
read_temp=Read_SHT_Dat;
if(read_temp==0)
{
Delay_ms(1000);
break;
}
} //wait until sensor has finished the measurement
read_temp=Read_SHT_Dat;
if(read_temp) _error+=1;
*(p_value+1)=SHT_Rea_Byte(SHT_ACK); //read the first byte (MSB)
*(p_value)=SHT_Rea_Byte(SHT_ACK); //read the second byte (LSB)
*p_checksum=SHT_Rea_Byte(SHT_noACK); //read checksum
return _error;
}
//计算温、湿度值
//------------------------------------------------------------------------------
// calculates temperature [℃] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH] +
// temp [℃]
void SHT_Cal_TH(float *p_humidity,float *p_temperature)
{
static float C1=-4.0; //for 12 Bit
static float C2=+0.0405; //for 12 Bit
static float C3=-0.0000028; //for 12 Bit
static float T1=+0.01;
static float T2=+0.00008;
float rh_lin; //rh_lin:Humidity linear
float rh_true; //rh_true:Temperature compensated humidity
float t_C; //t_C:Temperature [℃]
float rh=*p_humidity; //rh:Humidity [Ticks] 12 Bit
float t=*p_temperature; //t:Temperature [Ticks] 14 Bit
t_C=t*0.01-39.64; //calc. temperature from ticks to [c]
rh_lin=C3*rh*rh+C2*rh+C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]
/*cut if the value is outside of the physical possi××e range*/
if(rh_true>100)
rh_true=100;
if(rh_true<0.1)
rh_true=0.1;
*p_temperature=t_C; //return temperature [℃]
*p_humidity=rh_true; //return humidity[%RH]
} |