1463|0

1704

帖子

0

TA的资源

五彩晶圆(初级)

楼主
 

MSP430与SHT11的IIC通信问题 [复制链接]

MSP430始终接收不到数据,一直以为是代码的问题,今天无意中看到别人的一片文章,才发现问题出在上拉电阻上。DATA线的上拉电阻不能太大,10k不行,换成了1k就没问题了。mark一下,顺便感谢那位作者,附上他的链接:http://blog.sina.com.cn/s/blog_52f5ded30100bf68.html
附上MSP430代码:


在main里调用:

s_connectionreset();
s_write_status();
for(;;)
{
  s_read_temp_and_humi();//读取温度、湿度
}

sht11.h:

enum {TEMP,HUMI};
 
#define S_DATA_OUT (P6DIR |= BIT3) //P6.5 OUT
#define S_DATA_IN (P6DIR &=~BIT3) //P6.5 IN
#define S_DATA (P6IN & BIT3) //P6.5 DATA
#define S_DATA_LOW (P6OUT &=~BIT3)
#define S_DATA_HIGH (P6OUT |= BIT3)
#define S_SCK_OUT (P6DIR |= BIT4)
#define S_SCK_LOW (P6OUT &=~BIT4)
#define S_SCK_HIGH (P6OUT |= BIT4)
 
#define noACK 0
#define ACK 1
//adr command r/w
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define MEASURE_STATUS 0x06 //000 0011 0
 
void delay(unsigned int k);
void s_transstart(void);
void s_connectionreset(void);
unsigned char s_write_byte(unsigned char value);
unsigned char s_read_byte(unsigned char ack);
void s_calc_sth11(void);
unsigned char s_measure(unsigned int *p_value, unsigned char mode);
void s_write_status();
void s_read_temp_and_humi(void);
unsigned int temperature,humidity;
float f_temperature,f_humidity;
unsigned char s_read_data(unsigned int *p_value);
unsigned char s_measure_cmd(unsigned char mode);
unsigned char s_error=0;
 
extern float humi;
/******************************************************************************/
/* Temperature and humidity sensor function start */
/******************************************************************************/
// generates a tran××ission start 
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______ 
 
// calculates temperature [懊] and humidity [%RH] 
// input : humi [Ticks] (12 bit) 
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [懊]
void s_calc_sth11(void)

  float rh; // rh: Humidity
  float t; // t: Temperature
  float ttt;
  if(temperature>7000) 
  ttt=temperature-7000;
  else
  ttt=7000-temperature;
  t=temperature*0.01 - 39.64-0.00000002*ttt*ttt; //calc. temperature from ticks to [℃]
  rh=(0.0405-0.0000028*humidity)*humidity -4.0; //calc. humidity from ticks to [%RH]
  rh=(t-25)*(0.01+0.00008*humidity)+rh; //calc. temperature compensated humidity [%RH]
  f_temperature=t;
  temperature=t; //return temperature [℃]
  f_humidity=rh;
  humidity=rh; //return humidity[%RH]
  if((t-temperature)>=0.5)
  temperature+=1;
  if((rh-humidity)>=0.5)
  humidity+=1;
  if(humidity>100) humidity=100; //cut if the value is outside of 
  if(humidity<1) humidity=1; //the physical possi××e range
  
  humi=0.123;
}
 
 
 
void s_transstart(void)

  S_DATA_OUT;
  S_SCK_OUT;
  S_DATA_HIGH; //Initial state
  S_SCK_LOW;
  S_SCK_HIGH;
  S_DATA_LOW;
  S_SCK_LOW;
  S_SCK_HIGH; 
  S_DATA_HIGH;
  S_SCK_LOW; 
}
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
void s_connectionreset(void)

  unsigned char i; 
  S_DATA_OUT;
  S_SCK_OUT;
  S_DATA_HIGH; //Initial state
  S_SCK_LOW; 
  for(i=0;i<9;i++) //9 SCK cycles
  { 
    S_SCK_HIGH;
    //_nop();
    S_SCK_LOW;
  }
  s_transstart(); //tran××ission start
}
// writes a byte on the Sensibus and checks the acknowledge 
unsigned char s_write_byte(unsigned char value)

  unsigned char i,error=0; 
  S_DATA_OUT;
  for (i=0x80;i>0;i/=2) //shift bit for masking
  { 
    if (i & value) S_DATA_HIGH; //masking value with i , write to SENSI-BUS
    else S_DATA_LOW; 
    S_SCK_HIGH; //clk for SENSI-BUS
    S_SCK_LOW;
  }
  S_DATA_IN; 
  S_SCK_HIGH; //clk #9 for ack 
  error=S_DATA; //check ack (DATA will be pulled down by SHT11)
  S_SCK_LOW; 
  S_DATA_OUT; //release DATA-line
  return error; //error=1 in case of no acknowledge
}
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
unsigned char s_read_byte(unsigned char ack)

  unsigned char i,val=0;
  S_DATA_IN;
  for (i=0x80;i>0;i/=2) //shift bit for masking
  { 
    S_SCK_HIGH; //clk for SENSI-BUS
    if (S_DATA) val=(val | i); //read bit 
    S_SCK_LOW; 
  }
  S_DATA_OUT;
  if(ack)
  S_DATA_LOW;
  else
  S_DATA_HIGH; //in case of "ack==1" pull down DATA-Line
  S_SCK_HIGH; //clk #9 for ack
  S_SCK_LOW; //release DATA-line
  return val;

/*Write status register:12bit humi,14bit temp*/
void s_write_status(void)
{
  s_connectionreset();
  s_write_byte(MEASURE_STATUS);
  s_write_byte(0x00); 
}
// makes a measurement (humidity/temperature)
unsigned char s_measure(unsigned int *p_value,unsigned char mode)

  unsigned char error=0;
  unsigned int i;
  
  s_transstart(); //tran××ission start
  if(mode==TEMP) //send command to sensor
  error+=s_write_byte(MEASURE_TEMP);
  else
  error+=s_write_byte(MEASURE_HUMI);
  S_DATA_IN;
  for (i=0;i<65535;i++) 
    if(S_DATA==0) break; //wait until sensor has finished the measurement
  if(S_DATA) error+=1; // or timeout (~1 sec.) is reached
  *p_value =s_read_byte(ACK); //read the first byte (MSB)
  *p_value = (*p_value)<<8;
  (*p_value) +=s_read_byte(noACK); //read the second byte (LSB)
  return error;
}
/***mode:TEMP,HUMI***/
unsigned char s_measure_cmd(unsigned char mode)
{
  unsigned char error=0;
  s_transstart();
  if(mode==TEMP) //send command to sensor
  error+=s_write_byte(MEASURE_TEMP);
  else
  error+=s_write_byte(MEASURE_HUMI);
  S_DATA_IN;
  return error;
}
unsigned char s_read_data(unsigned int *p_value)
{
  if(S_DATA)
  return 1;
  else
  {
    *p_value =s_read_byte(ACK); //read the first byte (MSB)
    *p_value = (*p_value)<<8;
    (*p_value) +=s_read_byte(noACK); //read the second byte (LSB)
    return 0;
  }
}
 
 
// measure humidity [%RH](8 bit) and temperature [℃](12 bit)
void s_read_temp_and_humi(void)
{
  unsigned char error=1;
  while(error)
  {
    error=0;
    error+=s_measure(&humidity,HUMI); //measure humidity
    error+=s_measure(&temperature,TEMP); //measure temperature
    if(error!=0) 
    s_connectionreset(); //in case of an error: connection reset
    else
    s_calc_sth11(); //calculate humidity, temperature
  }
}
/******************************************************************************/
/* Temperature and humidity sensor function END */
/******************************************************************************/
void delay(unsigned int k)
{
  unsigned int ktemp;
  for(ktemp=0;ktemp<k;ktemp++);
}
 

 
点赞 关注

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

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