搜索
bottom↓
回复: 7

PIC如何读取SHT11传感器

[复制链接]

出0入0汤圆

发表于 2009-6-23 22:52:58 | 显示全部楼层 |阅读模式
各位大侠,有谁知道PIC如何读取SHT11温湿度传感器的方法,本人把C51的改成PIC的调试了几天也没有调试成功。C51的端口输入输出和PIC的端口I/O老是分不清楚。谢谢指点。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2009-6-24 06:15:29 | 显示全部楼层
这是C51读写字节和初始化原代码:
//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
  unsigned char i,error=0;  
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { if (i & value) DATA=1;          //masking value with i , write to SENSI-BUS
    else DATA=0;                        
    SCK=1;                          //clk for SENSI-BUS
    _nop_();_nop_();_nop_();        //pulswith approx. 5 us         
    SCK=0;
  }
  DATA=1;                           //release DATA-line
  SCK=1;                            //clk #9 for ack
  error=DATA;                       //check ack (DATA will be pulled down by SHT11)
  SCK=0;        
  return error;                     //error=1 in case of no acknowledge
}

//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
  unsigned char i,val=0;
  DATA=1;                           //release DATA-line
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { SCK=1;                          //clk for SENSI-BUS
    if (DATA) val=(val | i);        //read bit  
    SCK=0;                                           
  }
  DATA=!ack;                        //in case of "ack==1" pull down DATA-Line
  SCK=1;                            //clk #9 for ack
  _nop_();_nop_();_nop_();          //pulswith approx. 5 us
  SCK=0;                                                    
  DATA=1;                           //release DATA-line
  return val;
}

//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{  
   DATA=1; SCK=0;                   //Initial state
   _nop_();
   SCK=1;
   _nop_();
   DATA=0;
   _nop_();
   SCK=0;  
   _nop_();_nop_();_nop_();
   SCK=1;
   _nop_();
   DATA=1;                  
   _nop_();
   SCK=0;                  
}

//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{  
  unsigned char i;
  DATA=1; SCK=0;                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK cycles
  { SCK=1;
    SCK=0;
  }
  s_transstart();                   //transmission start
}
下面是更改后的原代码:
char s_write_byte(unsigned char value)
//-------------------------------------------------------------------
// 写一个字节,检查应答信号
{
  unsigned char  i,error=0;  
DDREbits.RE1=0;
  for (i=0x80;i>0;i/=2)      
  { if (i & value) DATA=1;     
    else DATA=0;                        
    SCK=1;                       
    Nop();Nop();Nop();        //时钟脉冲宽度 5 us         
    SCK=0;
  }
DDREbits.RE1=1;
  SCK=1;                            //9个CLK后应答
    Nop();
  error=DATA;             //检查应答信号 (DATA 被拉低)
  SCK=0;        
DDREbits.RE1=0;

  return error;                     // 如果没有应答则error=1
}//
//-------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//-------------------------------------------------------------------
// 读一个字节,检查应答信号
{
  unsigned char i,val=0;
DDREbits.RE1=1;
  for (i=0x80;i>0;i/=2)            
  { SCK=1;                          
    if (DATA) val=(val | i);         
    SCK=0;                                           
  }
DDREbits.RE1=0;
DATA=!ack;                   //如果 "ack==1" ,拉低DATA
    Nop();Nop();
  SCK=1;                            //clk #9 for ack
  Nop();Nop();Nop();Nop();;Nop();Nop();        //延时5微秒
  SCK=0;                                                    
    Nop();Nop();        //时钟脉冲宽度 5 us         

DDREbits.RE1=0;
  return val;
}

//-------------------------------------------------------------------
void s_transstart(void)
//-------------------------------------------------------------------
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{  
   DDREbits.RE1=0;
   Nop();
        DATA=1;
   SCK=0;                   //初始状态
   Nop();
   SCK=1;
   Nop();
   DATA=0;
   Nop();
   SCK=0;  
   Nop();Nop();Nop();
   SCK=1;
   Nop();
   DATA=1;                  
   Nop();
   SCK=0;                  
}

//-------------------------------------------------------------------
void s_connectionreset(void)
//-------------------------------------------------------------------
//通讯复位: 至少在9 SCK 周期后,DATA=1 传输开始
//       _____________________________________________________         
// DATA:                                                      //|_______|
//      _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   
{  
  unsigned char i;
   DDREbits.RE1=0;
DATA=1; SCK=0;                    //初始状态
  for(i=0;i<9;i++)                  //9 SCK周期
  {
SCK=1;
SCK=0;
  }
  s_transstart();                   //通讯开始
}

出0入0汤圆

 楼主| 发表于 2009-6-24 06:18:01 | 显示全部楼层
读出来的湿度不是大于100就是0.1,温度老是几百,那位大侠能帮我指点一下。谢谢!

出0入137汤圆

发表于 2009-6-24 07:58:22 | 显示全部楼层
网上有pic的程序

出0入0汤圆

 楼主| 发表于 2009-6-24 11:20:14 | 显示全部楼层
3楼的朋友说的我没有找到,在那能具体说一下吗,谢谢

出0入0汤圆

发表于 2012-11-18 20:53:47 | 显示全部楼层
zhkwhx 发表于 2009-6-24 11:20
**** 作者被禁止或删除 内容自动屏蔽 ****

哎呀,哥~!我终于找到组织了。。。我现在要也遇到这个问题了。我用51做的驱动,在51上跑,完全没问题。。。结果我一直到新唐的M051上(12M主频)就是跑不起来了~!也是出现很大的数跟0.1.。。也是四五天了,  

出0入0汤圆

发表于 2012-11-18 20:55:00 | 显示全部楼层
zhkwhx 发表于 2009-6-24 11:20
**** 作者被禁止或删除 内容自动屏蔽 ****

哎呀,哥~!我终于找到组织了。。。我现在要也遇到这个问题了。我用51做的驱动,在51上跑,完全没问题。。。结果我一直到新唐的M051上(12M主频)就是跑不起来了~!也是出现很大的数跟0.1.。。也是四五天了,  dd

出0入0汤圆

发表于 2012-11-18 20:58:39 | 显示全部楼层
一直没解决,,,今天我用仿真器跟踪看了一下,,读取温湿度发完命令后,数据线拉不高,,一直是低,,,,导致下面的判断完全无效。。。不知道是为什么???你解决了吗????????????
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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