4880|1

3

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

C8051F340单片机控制SHT10温湿度传感器(12864显示) [复制链接]

是新手,程序是从网上搜索之后根据自己的单片机修改的,(关于传感器那块用了官方的程序),但是结果显示的时候温度要么显示q13,要么显示614。湿度则显示0.1(湿度计算受温度影响) 但是调试过程中发现若注释掉温度部分,则湿度显示可以 ,并且冲传感器哈气的时候示数会出现预想的变化。 想破头也找不到问题出在哪 希望有懂的大神帮个忙
#include                  // SFR declarations
#include
#include
#include
#include
#include "string.h"

#define noACK 0
#define ACK  1
#define Set_LCD_EN() P4|=0x01//使能LCD,0有效,1无效
#define Clear_LCD_EN() P4&=(~0x01)

#define Set_LCD_RW() P4|=0x02//LCD读写操作选择,1:读,0:写
#define Clear_LCD_RW() P4&=(~0x02)

#define Set_LCD_RS() P4|=0x04//LCD寄存器选择,1:数据,0:指令
#define Clear_LCD_RS() P4&=(~0x04)

#define Set_LCD_RST() P4|=0x08//
#define Clear_LCD_RST() P4&=(~0x08)

#define Set_LCD_PSB() P4|=0x20//
#define Clear_LCD_PSB() P4&=(~0x20)

#define LCD_SDA P3
#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
unsigned char error=0;
sbit SDA= P1^0;
sbit SCL = P1^1;
sbit S2=P2^0;                           // S ='0' 表示按键被按下
sbit S3=P2^1;                        // S ='0' 表示按键被按下
sbit LED2=P2^2;                           // LED ='1' 表示亮灯,LED ='0' 表示灭灯
sbit LED3=P2^3;                           // LED ='1' 表示亮灯,LED ='0' 表示灭灯
enum {TEMP,HUMI};
typedef union
{
  unsigned int i;
  float f;
} value;

float rh_true; // rh_true: Temperature compensated humidity
float t_C; // Temperature_C : Temperature [C]

float temperature_C,humidity_RH;
unsigned char code table2[]="sht11 show T&RH";
unsigned char code table3[]="T is:          ";
unsigned char code table4[]="RHis:         ";
unsigned char code table5[]=".";
unsigned char wendu[6];
unsigned char shidu[6];
void Delay (unsigned int x)
{
        while(--x);
}
//////////////////////////Pino Electronics///////////////////////////

/********************************************************************
函数功能:短延时函数,约10us。
入口参数:x:循环次数。
返    回:无。
备    注:无。
********************************************************************/
void ShortDelay(unsigned int x)
{
        unsigned int i;
        for(i=0;i                 Delay(18);
}
//////////////////////////Pino Electronics///////////////////////////

/********************************************************************
函数功能:长延时函数,约1ms。
入口参数:x:循环次数。
返    回:无。
备    注:无。
********************************************************************/
void LongDelay(unsigned int x)
{
        unsigned int i;
        for(i=0;i                 Delay(2010);
}
void InitOSC(void)
{
        P0MDIN &= ~0xC0;                //P0.6, P0.7配置为模拟输入,用作外部晶振
        P0SKIP |=  0xC0;                //交叉开关跳过P0.6, P0.7脚,用作外部晶振

        OSCXCN = 0x67;         //配置为外部晶体不分频,配置晶体频率为10M~30M
        Delay(1024);            //等待外部晶振开始工作,不可省略一定要做的步骤
        while (!(OSCXCN & 0x80));        //一直读取标志位,直到外部晶体稳定
        RSTSRC = 0x06;                        // Enable missing clock detector and VDD Monitor reset

        CLKSEL = 0x01;                        //选择外部晶体为时钟
        OSCICN = 0x00;                        //关闭内部晶振
}
void Port_IO_Init()
{


    // P1.0  -P1.5  Unassigned,  Open-Drain and P1.7 = CLK -  Unassigned,  Push-Pull  
    // P1.6 = SDA -  Unassigned,  Open-Drain   

   P1MDOUT    = 0x80;
    P2MDOUT    = 0xFF;
    P3MDOUT    = 0x00;
                P4MDOUT=0x1f;                //P4设为推挽输出方式,用于控制引脚RW,RS,EN,RST,PSB
    XBR0      = 0x06;
    XBR1      = 0x40;
}

void TransferSDA(unsigned char SDA1,bit di)
{
        Clear_LCD_RW();
        if(di)
    Set_LCD_RS();
        else
        Clear_LCD_RS();
        ShortDelay(5);
        LCD_SDA=SDA1;
        Set_LCD_EN();
        ShortDelay(5);
        Clear_LCD_EN();
}
/********************************************************************
函数功能:将LCD12864初始化为LCD字库显示模式。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitStringMod(void)        //LCD字库初始化程序
{
        ShortDelay(40);            
        Set_LCD_PSB();                      //设置为8BIT并口工作模式
        ShortDelay(5);               //延时
        Clear_LCD_RST();            //复位
        ShortDelay(5);              //延时
        Set_LCD_RST();               //复位置高
        ShortDelay(10);
        TransferSDA(0x30,0);          //Extended Function Set :8BIT设置,RClear_LCD_EN(): basic instruction set, G=0 :graphic display OFF
        ShortDelay(100);            
        TransferSDA(0x30,0);          //Function Set
        ShortDelay(37);            
        TransferSDA(0x08,0);          //Display on Control
        ShortDelay(100);            
        TransferSDA(0x10,0);         //Cursor Display Control光标设置
        ShortDelay(100);            
        TransferSDA(0x0C,0);          //Display Control,D=1,显示开
        ShortDelay(100);            
        TransferSDA(0x01,0);          //Display Clear
        ShortDelay(100);            
        TransferSDA(0x06,0);          //Enry Mode Set,光标从右向左加1位移动
        ShortDelay(100);            
}
/********************************************************************
函数功能:LCD12864显示字符。
入口参数:addr:需要显示的字符数据区的首地址。
返    回:无。
备    注:无。
********************************************************************/
void display1(void)
{
  unsigned char i;
          TransferSDA(0x80,0);
  for(i=0;i<18;i++)
  {
            TransferSDA(table2[i],1);
     ShortDelay(1);
  }
}

void display2(void)
{
  unsigned char i;
        TransferSDA(0x90,0);
  for(i=0;i<18;i++)
  {
     TransferSDA(table3[i],1);
     ShortDelay(1);
  }
}

void display3(void)
{
  unsigned char i;
  TransferSDA(0x88,0);
  for(i=0;i<8;i++)
  {
     TransferSDA(table4[i],1);
     ShortDelay(1);
  }
}

void displaywendu(void)
{
   unsigned char i;
  TransferSDA(0x94,0);
   for(i=0;i<3;i++)
   {
TransferSDA(wendu[i],1);
ShortDelay(1);
   }
   for(i=0;i<1;i++)
  {
TransferSDA(table5[i],1);
  ShortDelay(1);
  }
  for(i=4;i<5;i++)
  {
TransferSDA(wendu[i],1);
ShortDelay(1);
  }
}

void displayshidu(void)
{
   unsigned char i;
  TransferSDA(0x8c,0);
   for(i=0;i<3;i++)
   {
  TransferSDA(shidu[i],1);
  ShortDelay(1);
   }
   for(i=0;i<1;i++)
  {
    TransferSDA(table5[i],1);
    ShortDelay(1);
  }
  for(i=4;i<5;i++)
  {
TransferSDA(shidu[i],1);
ShortDelay(1);
  }
}
char s_write_byte(unsigned char value)

{

unsigned char i; error=0;


for (i=0x80;i>0;i>>=1)             //shift bit for masking
{
if (i & value)

SDA=1;          //masking value with i , write to SENSI-BUS
else
SDA=0;  
ShortDelay(150);
SCL=1;
ShortDelay(150);

SCL=0;
ShortDelay(150);
}

SDA=1;// release SDA line
SCL=1;                            //clk #9 for ack
error=SDA;


SCL=0;

return error;

}
char s_read_byte(unsigned char ack)

{
unsigned char i,val=0;
SDA=1;                           //release SDA-line
for (i=0x80;i>0;i>>=1)             //shift bit for masking
{
ShortDelay(150);
SCL=1;
ShortDelay(150);                     //clk for SENSI-BUS
if (SDA) val=(val | i);        //read bit
SCL=0;

}

SDA=!ack;                        //in case of "ack==1" pull down SDA-Line
ShortDelay(150);
SCL=1;                            //clk #9 for ack
ShortDelay(150);           //pulswith approx. 5 us
SCL=0;
ShortDelay(150);
                          //release SDA-line
return val;
}
void s_transstart(void)

{


SDA=1;
SCL=0;
ShortDelay(150);
SCL=1;
ShortDelay(150);
SDA=0;
ShortDelay(150);
SCL=0;
ShortDelay(150);
SCL=1;
ShortDelay(150);
SDA=1;
ShortDelay(150);
SCL=0;
             //transmission start

}
void s_connectionreset(void)

{
unsigned char i;
SDA=1; SCL=0; //Initial state
for(i=0;i<9;i++) //9 SCL cycles
{ SCL=1;
ShortDelay(150);
SCL=0;
ShortDelay(150);
}
s_transstart(); //transmission start
}

char s_softreset(void)
// resets the sensor by a softreset
{
  unsigned char error=0;  
  s_connectionreset();              //复位通讯
  error+=s_write_byte(RESET);       //发送复位命令
  return error;                     //如果传感器没有响应则error=1
}

//-------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value,unsigned *p_checksum)
//-------------------------------------------------------------------
//读效验寄存器状态 (8-bit)
{
  unsigned char error=0;
  s_transstart();                   //通讯开始
  error=s_write_byte(STATUS_REG_R); //发送命令
  *p_value=s_read_byte(ACK);        //读状态寄存器(8-bit)
  *p_checksum=s_read_byte(noACK);   //读效验和  
  return error;          //如果传感器没有响应则error=1
}

//-------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//-------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
  unsigned char error=0;
  s_transstart();                   //通讯开始
  error+=s_write_byte(STATUS_REG_W);// 发送命令
  error+=s_write_byte(*p_value);    //发送状态寄存器的值
  return error;                     //如果传感器没有响应则error=1

}        

char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
unsigned error=0;
unsigned int i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
//case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i<65535;i++) if(SDA==0) break; //wait until sensor has finished the measurement
if(SDA) error+=1; // or timeout (~2 sec.) is reached
*(p_value) =s_read_byte(ACK); //read the first byte (MSB)
*(p_value+1)=s_read_byte(ACK); //read the second byte (LSB)
*p_checksum =s_read_byte(noACK); //read checksum
return error;
}

//----------------------------------------------------------------------------------------

void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [C] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [C]
{
const float C1=-4.0; // for 12 Bit
const float C2=+0.0405; // for 12 Bit
const float C3=-0.0000028; // for 12 Bit
const float T1=+0.01; // for 14 Bit @ 5V
const float T2=+0.00008; // for 14 Bit @ 5V
float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [C]
t_C=t*0.01 - 40; //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]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range
*p_temperature=t_C; //return temperature [C]
*p_humidity=rh_true; //return humidity[%RH]
}


  void SHT11(void)
{
unsigned int humi,temp;
value humi_val,temp_val;
//float dew_point;
unsigned char error,checksum;

InitStringMod();
display1();
display2();
display3();

s_connectionreset();
error=0;

error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI); //measure humidity
error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP); //measure temperature


if(error!=0)
s_connectionreset(); //in case of an error: connection reset
else
{
humi_val.f=(float)humi_val.i; //converts integer to float
temp_val.f=(float)temp_val.i; //converts integer to float
calc_sth11(&humi_val.f,&temp_val.f); //calculate humidity, temperature
temp=temp_val.f*10;
humi=humi_val.f*10;
         wendu[0]=(temp/1000)+'0';          //温度百位
         wendu[1]=(temp%1000)/100+'0';         //温度十位
         wendu[2]=(temp%100)/10+'0';           //温度个位
         wendu[3]=0x2E;                        //小数点
       wendu[4]=temp%10+'0';        //温度小数点后第一位
          displaywendu();
        shidu[0]=humi/1000+'0';                     //湿度百位
         shidu[1]=(humi%1000)/100+'0';               //湿度十位
         shidu[2]=(humi%100)/10+'0';                      //湿度个位
         shidu[3]=0x2E;                      //小数点
        shidu[4]=(humi%10)+'0';                     //湿度小数点后第一位
               displayshidu();
     }

LongDelay(2000);//----------wait approx. 0.8s to avoid heating up SHTxx------------------------------
//(be sure that the compiler doesn't eliminate this line!)
//-----------------------------------------------------------------------------------


}


void main()
{
   PCA0MD &= ~0x40;                       // Disable watchdog timer

InitOSC ();
Port_IO_Init();
                          // Enable global interrupts

s_connectionreset();
while(1)
{
SHT11();
}

}

此帖出自传感器论坛

最新回复

不用金币,好资料!   详情 回复 发表于 2019-9-11 14:29
点赞 关注
 
 

回复
举报

13

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

不用金币,好资料!

此帖出自传感器论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

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