4106|4

124

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

CC2541 无法驱动 SHT20 温湿度传感器的原因 [复制链接]

单独在一个工程里面使用 SHT20就没有问题,但是把它移植到 CC2541 的蓝牙工程里面,读到的数据就有问题,我百思不得其姐。有一次单步仿真的时候,发现有些代码居然直接跳过去了,仿真一下子跳了几行,不知道怎么回事。

后来想是不是IAR的设置,把这几步优化掉了,然后去对比2个工程的设置。发现优化等级是 high, 把优化等级降低,正确读到温湿度数据。
原来罪魁祸首是优化等级。至此困扰我1天的原因解决。




下面是CC2541的代码。我也是参考别人的,移植到2541上的。到原作者不记得是谁了,别见怪
#include
#include
#include "ioCC2541.h"
//#include
#include "SHT20.h"

#define add_w 0x80                           //传感器地址 + 写操作
#define add_r 0x81                           //传感器地址 + 读操作
#define T_code 0xe3                        //温度 测量指令
#define RH_code 0xe5                        //湿度 测量指令
#define user_code_w 0xe6                //用户寄存器 写指令
#define user_code_r 0xe7                //用户寄存器 读指令,可读电池电压是否小于2.25V。(测量后才可查看)
#define RST_code 0xfe                        //软复位,寄存器服务。

#define uchar unsigned char
#define uint unsigned int

//究竟会是什么原因导致的数据不正常?
//sbit sht20_sda=P1^3;        //数据线
//sbit sht20_scl=P1^4;        //时钟线
#define sht20_sda     P1_7
#define sht20_scl     P1_6

/***********延时程序***********/         
//11.0592MHz 1T 时钟周期0.09042us 机器周期0.09042us,根据当前配置计算延时程序。
//测量分辨率 RH 12 BIT、T 14 BIT,测量时间RH29ms、T85ms
//测量分辨率 RH 8  BIT、T 12 BIT,测量时间RH4 ms、T22ms
//sht20_scl时钟,延时2us

void delay85ms(void)   //误差 -0.000000000011us
{
  unsigned int a,b,c;
  for(c=397;c>0;c--)
  //for(c=97;c>0;c--)
    for(b=56;b>0;b--)
      for(a=85;a>0;a--);
  NOP();  //if Keil,require use intrins.h
  NOP();  //if Keil,require use intrins.h
}

void delay29ms(void)   //误差 -0.072337962967us
{
  unsigned int a,b,c;
  for(c=361;c>0;c--)
  //for(c=161;c>0;c--)
    for(b=221;b>0;b--)
      for(a=3;a>0;a--);
  NOP();  //if Keil,require use intrins.h
}


void delay15ms(void)   //误差 -0.000000000002us
{
  unsigned int a,b;
  for(b=520;b>0;b--)
  //for(b=220;b>0;b--)
    for(a=187;a>0;a--);
  NOP();  //if Keil,require use intrins.h
  NOP();  //if Keil,require use intrins.h
}

/*void delay4ms(void)   //误差 -0.072337962963us
{
unsigned char a,b;
for(b=89;b>0;b--)
for(a=247;a>0;a--);
}

void delay22ms(void)   //误差 -0.036168981484us
{
unsigned char a,b,c;
for(c=9;c>0;c--)
for(b=170;b>0;b--)
for(a=78;a>0;a--);
NOP();  //if Keil,require use intrins.h
NOP();  //if Keil,require use intrins.h
}  */

void delay2us(void)   //误差 -0.010706018519us
{
  unsigned char a,b;
  for(b=5;b>0;b--)
    for(a=8;a>0;a--);
}


/***********时序程序***********/
//传感器 基本时序程序。

//1 启动
//2        停止
//3        应答&非应答
//4        接收应答
//5        发送 一字节
//6        接收 一字节


//1 启动
void sht20_start(void)
{
  sht20_sda=1;
  delay2us();
  sht20_scl=1;
  delay2us();
  sht20_sda=0;
  delay2us();
  sht20_scl=0;
  delay2us();
}

//2 停止
void sht20_stop(void)
{
  sht20_sda=0;
  delay2us();
  sht20_scl=1;
  delay2us();
  sht20_sda=1;
  delay2us();
  sht20_scl=0;
  delay2us();
}

//3 应答&非应答
void sht20_ACK (void)
{        
  sht20_sda=0;
  delay2us();
  sht20_scl=1;
  delay2us();               
  sht20_scl=0;
  delay2us();         
}

void sht20_noACK (void)
{
  sht20_scl=1;
  delay2us();
  sht20_sda=0;        
  sht20_scl=0;
  delay2us();
}

//4        接收应答
//bit sht20_getACK(void)
unsigned char sht20_getACK(void)
{
  unsigned char ack1=0;
  //bit ack1 = 0;
  sht20_sda=1;
  delay2us();        
  sht20_scl=1;
  delay2us();
  ack1=sht20_sda;
  sht20_scl=0;
  delay2us();
  return ack1;        
}

//5        发送 一字节,代码都是一样的?
//在CC2541里面,位是怎么操作的?
void sht20_send(uchar send_data)
{
  uchar Bit_Counter=8;
  while(Bit_Counter>0)
  {
    //高位数据在前?那么如何换成一个位?
    //sht20_sda=(bit)(DATA&0x80);
    if(send_data&0x80)
      sht20_sda = 1;
    else
      sht20_sda = 0;
    send_data<<=1;
    sht20_scl=1;
    delay2us();
    sht20_scl=0;
    delay2us();
    Bit_Counter--;
  }

}  

//6        接收 一字节
unsigned char sht20_read()
{
  unsigned char x=0,y=8;
  sht20_sda=1;
  while(y>0)
  {
    sht20_scl=1;
    delay2us();
    if(sht20_sda)
      x=x|0x01;
    else
      x=x&0xfe;
    sht20_scl=0;
    delay2us();
    if(y>1)                        
      x=x<<1;
    y--;
  }

  return x;
}

/*1**********传感器初始化&软复位*********/
/*2**********传感器用户寄存器读取*******/
/*3**********传感器测量分辨率设置*******/
/*4**********传感器低电压检测***********/

// 1传感器初始化&软复位
void SHT2x_init()
{
  sht20_start();
  sht20_send(add_w);
  sht20_getACK();
  sht20_send(RST_code);
  sht20_getACK();
  sht20_stop();
  delay15ms();
  sht20_sda=1;
  sht20_scl=1;
}

// 2传感器用户寄存器读取
unsigned char SHT2x_user_register()
{
  uchar register_data;
  sht20_start();
  sht20_send(add_w);
  sht20_getACK();
  sht20_send(user_code_r);
  sht20_getACK();
  sht20_start();
  sht20_send(add_r);
  sht20_getACK();
  register_data=sht20_read();
  sht20_noACK();
  sht20_stop();
  return register_data;
}

// 3 传感器测量分辨率设置
// 测量分辨率设置 RH 8 BIT、T 12 BIT,测量时间RH4ms、T22ms
void SHT2x_Resolution()
{
  sht20_start();
  sht20_send(add_w);
  sht20_getACK();
  sht20_send(user_code_w);
  sht20_getACK();
  sht20_send(0x3b);
  sht20_getACK();
  sht20_getACK();
  sht20_stop();        
}

// 4 传感器低电压检测
// 此状态位在每次测量后更新
//bit SHT2x_battery()
unsigned char SHT2x_battery()
{
  uchar battery;
  sht20_start();
  sht20_send(add_w);
  sht20_getACK();
  sht20_send(user_code_r);
  sht20_getACK();
  sht20_start();
  sht20_send(add_r);
  sht20_getACK();
  battery=sht20_read();
  sht20_noACK();
  sht20_stop();
  battery=(battery&0x40)>>6;
  return battery;
}

/***********测量结果***********/

// 1 湿度测量
// 启动》发送地址+写操作》接收ACK》湿度测量命令》接收ACK》启动》发送地址+读操作》...
// ...接收ACK》测量时间延时》读取高位数据》ACK》读取低位数据》NO_ACK》停止。
// 计算结果。返回结果。
unsigned int RH_Result()   
{
  unsigned int RH_Data;
  unsigned long RH=0;        
  sht20_start();
  sht20_send(add_w);
  sht20_getACK();
  sht20_send(RH_code);
  sht20_getACK();        
  sht20_start();
  sht20_send(add_r);
  sht20_getACK();  
  delay29ms();
  RH_Data=sht20_read();
  sht20_ACK();         
  RH_Data=RH_Data<<8;  
  RH_Data=RH_Data|sht20_read();
  sht20_noACK();
  sht20_stop();

  RH_Data=RH_Data&0xfffc;               
  RH=RH_Data*12500L;
  RH=RH>>16;
  RH=RH-600;

  return RH;
}

// 2 温度测量
// 启动》发送地址+写操作》接收ACK》温度测量命令》接收ACK》启动》发送地址+读操作》...
// ...接收ACK》测量时间延时》读取高位数据》ACK》读取低位数据》NO_ACK》停止。
// 计算结果。返回结果。
unsigned int T_Result()
{
  unsigned int T_Data;
  unsigned long T=0;        
  sht20_start();
  sht20_send(add_w);
  sht20_getACK();
  sht20_send(T_code);
  sht20_getACK();                 
  sht20_start();
  sht20_send(add_r);
  sht20_getACK();           
  delay85ms();        

  T_Data=sht20_read();
  sht20_ACK();        
  T_Data=T_Data<<8;            
  T_Data=T_Data|sht20_read();
  sht20_noACK();
  sht20_stop();

  T_Data=T_Data&0xfffE;               
  T=T_Data*17572L;
  T=T>>16;
  T=T-4685;

  return T;
}  

//这个函数需要实现,具体看硬件电路怎么设计的
//难道是堆栈的原因,也不像,其实是程序飞了
void sht20_gpio_init(void)
{
  P1SEL &= ~BIT6 ;
  P1SEL &= ~BIT7;           // Function as General Purpose I/O.
  //P1_0 = 1;                 // LED1 on.
  P1DIR |= BIT6 + BIT7;            // Output.
  P1_6 = 1;
  P1_7 = 1;

}

void sht20_config(void)
{
  uint B1;//B1有什么用途
  SHT2x_init();
  SHT2x_Resolution();
  B1=SHT2x_user_register();

}

/***********主程序***********/
//void sht20_conver_start()
//{
//  uint T,RH,B1;
//  T=T_Result();
//  RH=RH_Result();
//  SHT2x_battery();
//}
extern sys_param_data_t sys_data_used_qhq;
/***********主程序***********/
void sht20_conver_start()
{
  uint temper_data,humitu_data,B1;
  temper_data = T_Result();

  humitu_data=RH_Result();
  sys_data_used_qhq.temper_data[0] = temper_data/256;
  sys_data_used_qhq.temper_data[1] = temper_data%256;
  sys_data_used_qhq.humitu_data[0] = humitu_data/256;
  sys_data_used_qhq.humitu_data[1] = humitu_data%256;
  SHT2x_battery();
}



欢迎光临小弟淘宝店:https://shop116994086.taobao.com ... 1997079397.2.ecENAL
此内容由EEWORLD论坛网友2638823746原创,如需转载或用于商业用途需征得作者同意并注明出处


此帖出自RF/无线论坛

最新回复

你这是广告呀!大表哥,这里有广告!  详情 回复 发表于 2017-4-17 14:56
点赞 关注
 

回复
举报

606

帖子

20

TA的资源

一粒金砂(高级)

沙发
 
出现这种问题,我觉得可能是因为延时造成的。不要用软件延时,能通过定时器延时是最好的了。
此帖出自RF/无线论坛
 
 

回复

9790

帖子

24

TA的资源

版主

板凳
 
SensorTag里有一个SHT21的代码
此帖出自RF/无线论坛
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复

2774

帖子

8

TA的资源

版主

4
 
哈哈!debug时候确实常发生哈!
此帖出自RF/无线论坛
 
 
 

回复

2774

帖子

8

TA的资源

版主

5
 
你这是广告呀!大表哥,这里有广告!
此帖出自RF/无线论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表