RM新时代网站-首页

您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶(hù)?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子元器件>傳感器>

淺析CC2530下ZigBee協(xié)議棧中添加BH1750數(shù)字光照傳感器

2018年10月07日 11:51 網(wǎng)絡(luò)整理 作者:工程師譚軍 用戶(hù)評(píng)論(0
  數(shù)字傳感器
?
  數(shù)字傳感器是指將傳統(tǒng)的模擬式傳感器經(jīng)過(guò)加裝或改造A/D轉(zhuǎn)換模塊,使之輸出信號(hào)為數(shù)字量(或數(shù)字編碼)的傳感器,主要包括:放大器、A/D轉(zhuǎn)換器微處理器CPU)、存儲(chǔ)器、通訊接口、溫度測(cè)試電路等,在微處理器和傳感器變得越來(lái)越便宜的今天,全自動(dòng)或半自動(dòng)(通過(guò)人工指令進(jìn)行高層次操作,自動(dòng)處理低層次操作)系統(tǒng)可以包含更多智能性功能,能從其環(huán)境中獲得并處理更多不同的參數(shù)。
?
  特點(diǎn)
?
  1、先進(jìn)的A/D轉(zhuǎn)換技術(shù)和智能濾波算法,在滿(mǎn)量程的情況下仍可保證輸出碼的穩(wěn)定。
?
  2、可行的數(shù)據(jù)存儲(chǔ)技術(shù),保證模塊參數(shù)不會(huì)丟失。
?
  3、良好的電磁兼容性能。
?
  4、傳感器的性能采用數(shù)字化誤差補(bǔ)償技術(shù)和高度集成化電子元件,用軟件實(shí)現(xiàn)傳感器的線(xiàn)性、零點(diǎn)、溫漂、蠕變等性能參數(shù)的綜合補(bǔ)償,消除了人為因素對(duì)補(bǔ)償?shù)挠绊?,大大提高了傳感器綜合精度和可靠性。
?
  5、傳感器的輸出一致性誤差可以達(dá)到0.02%以?xún)?nèi)甚至更高,傳感器的特性參數(shù)可完全相同,因而具有良好的互換性。
?
  6、采用A/D轉(zhuǎn)換電路、數(shù)字化信號(hào)傳輸和數(shù)字濾波技術(shù),傳感器的抗干擾能力增加,信號(hào)傳輸距離遠(yuǎn),提高了傳感器的穩(wěn)定性。
?
  7、數(shù)字傳感器能自動(dòng)采集數(shù)據(jù)并可預(yù)處理、存儲(chǔ)和記憶,具有唯一標(biāo)記,便于故障診斷。
?
  8、傳感器采用標(biāo)準(zhǔn)的數(shù)字通訊接口,可直接連入計(jì)算機(jī),也可與標(biāo)準(zhǔn)工業(yè)控制總線(xiàn)連接,方便靈活。
?
  9, 數(shù)字傳感器是將AD,EPROM,DIE(指還未封裝的傳感器芯片,屬于裸片,大小介于cell和chip之間),封裝在一塊用PCB,金屬塊或陶瓷板上的集成。通過(guò)各種溫度,壓力點(diǎn)的校準(zhǔn),計(jì)算出DIE的線(xiàn)性,再利用AD去補(bǔ)償?shù)姆椒庸ざ傻摹?/div>
?
  應(yīng)用及前景
?
  在微處理器和傳感器變得越來(lái)越便宜的今天,全自動(dòng)或半自動(dòng)(通過(guò)人工指令進(jìn)行高層次操作,自動(dòng)處理低層次操作)系統(tǒng)可以包含更多智能性功能,能從其環(huán)境中獲得并處理更多不同的參數(shù)。尤其是MEMS(微型機(jī)電系統(tǒng))技術(shù),它使數(shù)字傳感器的體積非常微小并且能耗與成本也很低。以納米碳管或其它納米材料制成的納米傳感器同樣具有巨大的潛力 [1] 。
?
  即使在萌芽階段,人們?nèi)匀徽J(rèn)為在不久的將來(lái)數(shù)字傳感器對(duì)電子市場(chǎng)具有重要的推動(dòng)作用。制作數(shù)字傳感器的接口以及支持用于數(shù)字傳感器網(wǎng)絡(luò)的形式多樣的通訊協(xié)議都是對(duì)技術(shù)工藝的巨大挑戰(zhàn)。傳感器的非均質(zhì)特性和其操作條件的多樣化也對(duì)技術(shù)工藝提出了巨大的挑戰(zhàn)。
?
  現(xiàn)在系統(tǒng)設(shè)計(jì)所包含的傳感器和處理器越來(lái)越多。隨著傳感器和處理器價(jià)格的不斷降低,取代機(jī)械控制結(jié)構(gòu)的閾值也在不斷變化。在系統(tǒng)中選擇正確的傳感器組合和處理算法可以顯著地降低原材料及能耗的費(fèi)用并提高系統(tǒng)的總體性能。目前,不斷提高操作的簡(jiǎn)化程度和延長(zhǎng)能源的使用壽命變得越來(lái)越重要,尤其是如今越來(lái)越多的傳感器網(wǎng)絡(luò)動(dòng)輒就配置1000或更多的傳感器節(jié)點(diǎn)。

  項(xiàng)目里需要獲得光照強(qiáng)度,之前用的是光敏電阻,但是光敏電阻實(shí)在不精確,換用BH1750數(shù)字光照傳感器。網(wǎng)上購(gòu)買(mǎi)后,送的資料都是單片機(jī)的,移植到ZigBee協(xié)議棧里面,時(shí)序有些問(wèn)題,在網(wǎng)上找的一些資料,很雜亂。主要出現(xiàn)兩個(gè)問(wèn)題:一、讀取不到數(shù)據(jù);二、讀取到的數(shù)據(jù)是亂的。

  仔細(xì)研究之后,發(fā)現(xiàn),第一個(gè)問(wèn)題讀不到數(shù)據(jù),八成是延時(shí)函數(shù)有差別;第二個(gè)問(wèn)題,一直以為是時(shí)序的問(wèn)題,糾結(jié)了很久還是沒(méi)弄好,后來(lái)突然想把數(shù)據(jù)處理的地方單獨(dú)弄出來(lái)測(cè)試,結(jié)果正是這里,采集到數(shù)據(jù),轉(zhuǎn)為字符串的時(shí)候,數(shù)據(jù)類(lèi)型跟所需要的數(shù)據(jù)類(lèi)型有差,最大范圍不同,可能每個(gè)人宏或者自定義的數(shù)據(jù)類(lèi)型都不太一樣,所以移植過(guò)來(lái)的時(shí)候,雖然名字一樣,但是實(shí)際上定義的時(shí)候不一樣,導(dǎo)致使用的時(shí)候不容易發(fā)現(xiàn)問(wèn)題。

  下面貼上代碼。(之前在網(wǎng)上看到別人做的bh1750,想問(wèn)他買(mǎi)代碼,結(jié)果告訴我一個(gè)代碼要我80,瞬間無(wú)語(yǔ),還好自己弄出來(lái)了 ,共享給大家,也給自己提個(gè)醒,最是覺(jué)得沒(méi)有問(wèn)題的地方,往往就是問(wèn)題所在,需時(shí)刻抱有懷疑的態(tài)度)

  BH1750.h:

  #ifndef __BH1750_H

  #define __BH1750_H

  #include 《ioCC2530.h》

  #define st(x) do { x } while (__LINE__ == -1)

  #define HAL_IO_SET(port, pin, val) HAL_IO_SET_PREP(port, pin, val)

  #define HAL_IO_SET_PREP(port, pin, val) st( P##port##_##pin## = val; )

  #define HAL_IO_GET(port, pin) HAL_IO_GET_PREP( port,pin)

  #define HAL_IO_GET_PREP(port, pin) ( P##port##_##pin)

  #define LIGHT_SCK_0() HAL_IO_SET(1,3,0)

  #define LIGHT_SCK_1() HAL_IO_SET(1,3,1)

  #define LIGHT_DTA_0() HAL_IO_SET(1,1,0)

  #define LIGHT_DTA_1() HAL_IO_SET(1,1,1)

  #define LIGHT_DTA() HAL_IO_GET(1,1)

  #define LIGHT_SCK() HAL_IO_GET(1,3)

  #define SDA_W() (P1DIR |=(1 《《 1) )

  #define SDA_R() (P1DIR &=~(1 《《 1) )

  #define LIGHT_INIT() \

  do{ \

  P1SEL &= ~0x08; \

  P1DIR |=0x08; \

  P1_3 = 1; \

  \

  P1SEL &= ~0x02; \

  P1DIR |= 0x02; \

  P1_1 = 1; \

  }while(0)

  extern unsigned short get_light(void);

  #endif // __BH1750_H

  BH1750.c:

  #include “BH1750.h”

  #include “OnBoard.h”

  void halMcuWaitUs(uint16 usec)

  {

  while(usec--)

  {

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  asm(“nop”);

  }

  }

  //以ms延時(shí)

  void halMcuWaitMs(uint16 msec)

  {

  while(msec--)

  halMcuWaitUs(1000);

  }

  void delay_us()

  {

  halMcuWaitUs(1);

  // MicroWait(1);

  }

  void delay_5us()

  {

  halMcuWaitUs(5);

  //MicroWait(5);

  }

  void delay_10us()

  {

  halMcuWaitUs(10);

  //MicroWait(10);

  }

  void delay_nms(int n)

  {

  halMcuWaitMs(n);

  }

  /****************************/

  static void start_i2c(void)

  {

  SDA_W() ;

  LIGHT_DTA_1();//

  LIGHT_SCK_1() ;//

  delay_us() ;

  LIGHT_DTA_0() ;

  delay_us() ;

  LIGHT_SCK_0() ;

  delay_us() ;

  //delay() ;

  }

  static void stop_i2c(void)

  {

  SDA_W() ;

  LIGHT_DTA_0() ;

  delay_us();

  LIGHT_SCK_1() ;

  delay_us();

  LIGHT_DTA_1() ;

  delay_us();

  LIGHT_SCK_0() ;

  delay_us();

  }

  static char i2c_send(unsigned char val)

  {

  int i;

  char error=0;

  SDA_W();

  for(i=0x80;i》0;i/=2)

  {

  if(val&i)

  LIGHT_DTA_1();

  else

  LIGHT_DTA_0();

  delay_us();

  LIGHT_SCK_1() ;

  delay_us();

  LIGHT_SCK_0() ;

  delay_us();

  }

  LIGHT_DTA_1();

  SDA_R();

  delay_us();

  //delay_us();

  LIGHT_SCK_1() ;

  delay_us();

  if(LIGHT_DTA())

  error=1;

  delay_us();

  LIGHT_SCK_0() ;

  return error;

  }

  static char i2c_read(char ack)

  {

  int i;

  char val=0;

  LIGHT_DTA_1();

  //SDA_R();

  for(i=0x80;i》0;i/=2)

  {

  LIGHT_SCK_1() ;

  delay_us();

  SDA_R();

  //SDA_W();

  //LIGHT_DTA_0();

  //LIGHT_DTA_0() ;

  //delay_us();

  if(LIGHT_DTA())

  val=(val|i);

  delay_us();

  //SDA_R();

  LIGHT_SCK_0() ;

  delay_us();

  }

  SDA_W();

  if(ack)

  LIGHT_DTA_0();

  else

  LIGHT_DTA_1();

  delay_us();

  LIGHT_SCK_1() ;

  delay_us();

  LIGHT_SCK_0() ;

  LIGHT_DTA_1();

  return val;

  }

  unsigned short get_light(void)

  {

  unsigned char ack1=1;

  unsigned char ack2=1;

  unsigned char ack3=1;

  unsigned char ack4=1;

  unsigned char ack5=1;

  unsigned char ack6=1;

  unsigned char ack7=1;

  unsigned char t0;

  unsigned char t1;

  unsigned short t;

  P1DIR |= (1 《《 1);

  delay_nms(200);

  start_i2c();

  ack1=i2c_send(0x46);

  if(ack1)

  return 255;

  ack2=i2c_send(0x01);

  if(ack2)

  return 254;

  stop_i2c(); //init

  start_i2c();

  ack3=i2c_send(0x46);

  if(ack3)

  return 253;

  ack4=i2c_send(0x01);

  if(ack4)

  return 252;

  stop_i2c();//power

  start_i2c();

  ack5=i2c_send(0x46);

  if(ack5)

  return 251;

  ack6=i2c_send(0x10);

  if(ack6)

  return 250;

  stop_i2c();

  delay_nms(1500);

  start_i2c();

  ack7=i2c_send(0x47);

  if(ack7)

  return 249;

  t0 = i2c_read(1);

  t1 = i2c_read(0);

  stop_i2c();

  t = ((short)t0)《《8;

  t |= t1;

  return t;

  }

  在主函數(shù)中加入以下函數(shù)(注意,此處就是最容易忽視的地方,uint應(yīng)該是unsigned int,不能是范圍太小的類(lèi)型):

  char wan,qian,bai,shi,ge;

  void conversion(unsigned int temp_data)

  {

  wan=(uint)temp_data/10000 ;

  temp_data=temp_data%10000;

  qian=(uint)temp_data/1000 ;

  temp_data=temp_data%1000;

  bai=(uint)temp_data/100;

  temp_data=temp_data%100;

  shi=(uint)temp_data/10;

  temp_data=temp_data%10;

  ge=(uint)temp_data;

  }

  調(diào)用光照獲取函數(shù),講數(shù)據(jù)轉(zhuǎn)為字符串:

  uint32 w;

  w = get_light()/1.2;

  conversion(w);

  char buf[5];

  buf[0] = wan + 48;

  buf[1] = qian + 48;

  buf[2] = bai + 48;

  buf[3] = shi + 48;

  buf[4] = ge + 48;


非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

( 發(fā)表人:金巧 )

      發(fā)表評(píng)論

      用戶(hù)評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?
      RM新时代网站-首页