從感測器中摘錄和監測資料對氣象組織至關重要。獨立的天氣資料記錄器用於記錄溫度、濕度、降雨量、葉片濕度、氣壓、日照等,但獨立資料記錄器僅限於收集地面站的資料。若是要監測天空中的溫度、濕度、氣壓、風速和風向等環境參數,這種地面站技術就派不上用場了,為了克服這個問題,有必要改變設計策略。

本文介紹的是使用射頻(RF)模組AX5042監測大氣參數環境氣象氣球的案例研究。氣象氣球通常被稱為無線電探空儀(Radiosonde)或GPS探空儀(GPSsonde),這種設計的目的是從感測器擷取資料並將其發送到位於地面的接收器。

氣象氣球可分成三部分,分別是UHF發射機(用於RF傳輸)、感測器單元和時間同步模組(GPS和RTC)。首先介紹無線電探空儀的框架圖。稍後探討硬體及其介面的內部細節。

20180917TA31P1 圖1 無線電探空儀(氣象氣球)框架圖。(來源:Kumar)

氣象氣球工作原理

RF晶片產生所需的傳輸頻率,透過它可以設置發送資料的傳輸時間間隔。可用任一款微控制器連接各種外掛晶片,如GPS、即時時脈(RTC)和感測器;從感測器擷取資料並透過RF通訊發送到遠端位置。若要實現正確的傳輸,則精準度為±1ppm的即時時脈DS3231可為首選。

但是,如何獲得時間和日期?可以選用GPS接收機Ublox從太空上的INSAT衛星獲取日期和時間。不僅可以從MAX7C GPS上獲取日期和時間,還能得到經緯度等資訊;再來將從GPS單元獲得的日期和時間載入微控制器。一般來說,無線電探空儀使用的頻率範圍為400MHz~600MHz。

演算法

演算法描述了實現氣象氣球的基本思想。

  1. 將GPS與衛星同步。

  2. 從GPS獲取時間資訊。

  3. 將此時間載入到即時時脈中。

  4. 使用RF模組鎖定頻率。

  5. 定期發送和接收感測器資料。

20180917TA31P2 圖2 軟體環境。(來源:Kumar B)

硬體簡介

以下介紹底層硬體。

安森美半導體(ON Semiconductor)提供了評估套件DVK-BASE-2-GEVK,以及必要的附加模組。AXsem積體電路(IC)使用AX-RadioLAB GUI和AX-MicroLab程式碼產生器、AXSDB調變器和AXCode:Blocks IDE。

在此,使用AT89C2051微控制器來製作原型。微控制器使用SPI介面與RF模組進行通訊。首先,RF模組必須以特定的頻率載入,為此,必須程式設計PLL。

硬體和軟體設計

在keil μVision IDE環境用嵌入式C編寫了應用程式碼。圖3顯示了微控制器、RF模組和HYT 271濕度感測器之間的連接。

濕度感測器和微控制器間的I2C匯流排要接上拉電阻(連3.3V工作電源)。建議使用2.2K電阻以獲得更好回應。

20180917TA31P3 圖3 射頻模組和微控制器連接。(來源:Kumar B)

必須對RF模組進行程式設計以生成所需的頻率。微控制器使用SPI介面寫入和讀取資料。

/ * 此程式碼將使用RF模組生成所需的RF頻率。 * /

#include <REG52.H>

#include <at892051.h

#include <stdio.h>

#define SyDataO P1_4

#define SyDataI P1_5

#define SyClock P1_6

#define SythLE P1_7

LoadPLL (void);

DataFrame (void);

spi_write (unsigned long spi_addr);

init_ax5042 (void);

unsigned char spi_read (unsigned int spi_addr);

函數將產生由RF模組引發的外部中斷。且RF模組做從機,微控制器為主機。

/********* 外部中斷-0的中斷函數 *********/

unsigned char ex0_isr_counter = 0;

void ex0_isr (void) interrupt 0

{

    ex0_isr_counter++; //Increment 

the count

LoadPLL ( );

P3_2 = 1;

}

應用程式碼從這裡開始。序列埠配置為9,600bps,用於將字元發送到串列終端。

/*******主函數 *******/

void main (void)

{

              unsigned char W;

/ * 設置串口為9,600bps@11.0592MHz。請注意:使用計時器1作為串列傳輸速率產生器。* /

SCON = 0x50;

TMOD |= 0x20;

TH1 = 0xFA;

TR1 = 1;

RI = 1;

TI = 1;

PCON |= 0x80;

IT0 = 1; //INT0 (P3.2) 的下降沿配置為中斷0

EX0 = 1; //使能EX0中斷

EA = 1; //使能全域中斷標誌

//頻率載入程式

P1=0;

P3=4;

SythLE = 1;

SyClock = 0;

SyDataO = 0;

while (1) //無限迴圈

{

getchar函數等待從串列終端接收字元。如果收到的字元匹配,函數將被執行。

/ 等待脈衝開始。 /

                       W = getchar ( );

                       if (W== 'r')

                          { 

                                     printf ("RF");

                                     init_ax5042 ( );

                                     LoadPLL ( );

                          }

                          if (W== 'w')

                          { 

                                 printf ("Wd");

                                 LoadPLL ( );

                           }

                           if (W==‘t’)

                           { 

                                        init_ax5042 ();

                           }

              }

    }

此函數可創建幾秒的延遲。

delay (int n) /等待‘n’秒/

{

       int i;

       for (i=0; i < n ; i + + )

        {

                ;

        }

}

要使用2051的配置寄存器,微控制器包含如下頭檔。

/* 微控制器的標頭檔 */

#ifndef AT892051_H

#define AT892051_H

/*----------------------------------------

P1位寄存器

------------------------------------------*/

sbit P1_4 = 0x94;

sbit P1_5 = 0x95;

sbit P1_6 = 0x96;

sbit P1_7 = 0x97;

/*----------------------------------------

P3位寄存器(助記符和埠)

------------------------------------------*/

sbit P3_0 = 0xB0;

sbit P3_1 = 0xB1;

sbit P3_2 = 0xB2;

sbit P3_3 = 0xB3;

sbit P3_4 = 0xB4;

sbit P3_5 = 0xB5;

/* P3_6 硬連線為AOUT */

sbit P3_7 = 0xB7;

/*----------------------------------------

中斷向量

中斷位址= (Number * 8) + 3

------------------------------------------*/

#define IE0_VECTOR 0 /* 0x03 外部中斷0 */

#define IE1_VECTOR 2 /* 0x13 外部中斷1 */

#define SIO_VECTOR 4 /* 0x23 串口 */

#endif

RF模組必須進行配置才能發送和接收資料。RF模組的寄存器必須使能。

/ * RF模組的標頭檔* /

/ 必須在傳輸或接收資料過程中修改或讀取的RF模組寄存器 /

#ifndef _AX5042_H

#define _AX5042_H

#define AX5042_REG_REVISION 0x00

#define AX5042_REG_SCRATCH 0x01

#define AX5042_REG_POWERMODE 0x02

#define AX5042_REG_FIFOCTRL 0x04

#define AX5042_REG_FIFODATA 0x05

#define AX5042_REG_IRQMASK 0x06

#define AX5042_REG_PINCFG1 0x0C

#define AX5042_REG_PINCFG2 0x0D

#define AX5042_REG_PINCFG3 0x0E

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

/* RF模組靜態寄存器定義*/

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

// RF模組寄存器名稱

#define AX5042_REG_XTALOSC 0x03

#define AX5042_REG_IFMODE 0x08

#define AX5042_REG_MODULATION 0x10

#define AX5042_REG_ENCODING 0x11

#define AX5042_REG_FRAMING 0x12

#define AX5042_REG_CRCINIT3 0x14

#define AX5042_REG_CRCINIT2 0x15

#define AX5042_REG_CRCINIT1 0x16

#define AX5042_REG_CRCINIT0 0x17

#define AX5042_REG_FEC 0x18

#define AX5042_REG_FECSYNC 0x19

#define AX5042_REG_FREQ3 0x20

#define AX5042_REG_FREQ2 0x21

#define AX5042_REG_FREQ1 0x22

#define AX5042_REG_FREQ0 0x23

#define AX5042_REG_FSKDEV2 0x25

#define AX5042_REG_FSKDEV1 0x26

#define AX5042_REG_FSKDEV0 0x27

#define AX5042_REG_IFFREQHI 0x28

#define AX5042_REG_IFFREQLO 0x29

#define AX5042_REG_PLLLOOP 0x2c

#define AX5042_REG_PLLRANGING 0x2d

#define AX5042_REG_PLLRNGCLK 0x2e

#define AX5042_REG_TXPWR 0x30

#define AX5042_REG_TXRATEHI 0x31

#define AX5042_REG_TXRATEMID 0x32

#define AX5042_REG_TXRATELO 0x33

#define AX5042_REG_MODMISC 0x34

#define AX5042_REG_ADCMISC 0x38

#define AX5042_REG_AGCTARGET 0x39

#define AX5042_REG_AGCATTACK 0x3a

#define AX5042_REG_AGCDECAY 0x3b

#define AX5042_REG_AGCCOUNTER 0x3c

#define AX5042_REG_CICDECHI 0x3e

#define AX5042_REG_CICDECLO 0x3f

#define AX5042_REG_DATARATEHI 0x40

#define AX5042_REG_DATARATELO 0x41

#define AX5042_REG_TMGGAINHI 0x42

#define AX5042_REG_TMGGAINLO 0x43

#define AX5042_REG_PHASEGAIN 0x44

#define AX5042_REG_FREQGAIN 0x45

#define AX5042_REG_FREQGAIN2 0x46

#define AX5042_REG_AMPLGAIN 0x47

#define AX5042_REG_SPAREOUT 0x60

#define AX5042_REG_TESTOBS 0x68

#define AX5042_REG_APEOVER 0x70

#define AX5042_REG_TMMUX 0x71

#define AX5042_REG_PLLVCOI 0x72

#define AX5042_REG_PLLCPEN 0x73

#define AX5042_REG_PLLRNGMISC 0x74

#define AX5042_REG_AGCMANUAL 0x78

#define AX5042_REG_ADCDCLEVEL 0x79

#define AX5042_REG_RFMISC 0x7a

#define AX5042_REG_TXDRIVER 0x7b

#define AX5042_REG_REF 0x7c

#define AX5042_REG_RXMISC 0x7d

#define AX5042_idle 0x00

// 接收狀態

#define AX5042_RX_preamble 0x01

#define AX5042_RX_delimiter_start 0x02

#define AX5042_RX_data 0x03

#define AX5042_RX_CRC 0x04

#define AX5042_RX_packet_end 0x05

#define AX5042_RX_abort 0x06

// 發送狀態

#define AX5042_TX_preamble 0x81

#define AX5042_TX_delimiter_start 0x82

#define AX5042_TX_data 0x83

#define AX5042_TX_CRC 0x84

#define AX5042_TX_delimiter_stop 0x85

#define AX5042_TX_postamble 0x86

#define AX5042_RX 0x00

#define AX5042_TX 0x01

#define DONE 0x00

#define PROCESSING 0x01

#endif /* _AX5042_H */

為RF模組配置的寄存器。

/ *此函數使用SPI介面初始化RF模組 * /

/ *初始化RF模組 * /

init_ax5042 (void)

{

/ * AXEVK軟體運算寄存器設置* /

spi_write (0x0200); //modeOFFAX5042_REG_POWERMODE

spi_write (0x0C10); //AX5042_REG_PINCFG1

spi_write (0x7201); //PLLARNG=1 AX5042_REG_PLLVCOI

spi_write (0x7401); //PLLARNG AX5042_REG_PLLRNGMISC

spi_write (0x0302); // AX5042_REG_XTALOSC

spi_write (0x0800); // AX5042_REG_IFMODE

spi_write (0x1009); // AX5042_REG_MODULATION

spi_write (0x1104); // AX5042_REG_ENCODING

spi_write (0x1204); // AX5042_REG_FRAMING

spi_write (0x14ff); // AX5042_REG_CRCINIT3

spi_write (0x15ff); // AX5042_REG_CRCINIT2

spi_write (0x16ff); // AX5042_REG_CRCINIT1

spi_write (0x17ff); // AX5042_REG_CRCINIT0

spi_write (0x1810); // AX5042_REG_FEC

spi_write (0x1962); // AX5042_REG_FECSYNC

spi_write (0x2036); // AX5042_REG_FREQ3

spi_write (0x2145); // AX5042_REG_FREQ2

spi_write (0x227b); // AX5042_REG_FREQ1

spi_write (0x2387); // AX5042_REG_FREQ0

spi_write (0x2c1d); // AX5042_REG_PLLLOOP

spi_write (0x2d08); // AX5042_REG_PLLRANGING

spi_write (0x2e03); // AX5042_REG_PLLRNGCLK

spi_write (0x3403); // AX5042_REG_MODMISC

spi_write (0x6000); // AX5042_REG_SPAREOUT

spi_write (0x6800); // AX5042_REG_TESTOBS

spi_write (0x7000); // AX5042_REG_APEOVER

spi_write (0x7100); // AX5042_REG_TMMUX

spi_write (0x7204); // AX5042_REG_PLLVCOI

spi_write (0x7301); // AX5042_REG_PLLCPEN

spi_write (0x7400); // AX5042_REG_PLLRNGMISC

spi_write (0x7a30); // AX5042_REG_RFMISC

spi_write (0x7c23); // AX5042_REG_REF

spi_write (0x2500); // AX5042_REG_FSKDEV2

spi_write (0x2666); // AX5042_REG_FSKDEV1

spi_write (0x2767); // AX5042_REG_FSKDEV0

spi_write (0x300f); // AX5042_REG_TXPWR

spi_write (0x3101); // AX5042_REG_TXRATEHI

spi_write (0x3299); // AX5042_REG_TXRATEMID

spi_write (0x339b); // AX5042_REG_TXRATELO

spi_write (0x7b88); // AX5042_REG_TXDRIVER

}

配置的頻率被載入到PLL IC中。

/ *此函數將PLL值儲存到RF模組 * /

LoadPLL ( )

{

unsigned int SyncDividend;

spi_write (0xaaaa);

spi_write (0xaaaa);

SyncDividend=spi_read (0x10aa);

DataFrame ( );

}

此函數將資料寫入RF模組。

/ 將資料寫入RF模組的函數 /

spi_write (unsigned long spi_addr)

{

   unsigned int j;

   spi_addr = spi_addr|0x8000;

   SythLE = 0;

   delay (3);

   for (j=0; j<=15; j++)

{

  SyClock= 0;

if((spi_addr & 0x8000)==0)

       SyDataO=0;

else

      SyDataO=1;

      delay(3);

      SyClock=1;

      spi_addr = (spi_addr<< 1);

      delay(3); 

  }

  delay(3);

  SythLE =1;

  SyClock =0;

  SyDataO =0; 

}

此函數將讀取RF模組的資料。

/ 從RF模組讀取資料的函數 /

unsigned char spi_read (unsigned int spi_addr)

{

  unsigned int d;

  unsigned int j;

      d=0x0000;

    spi_addr = spi_addr & 0x7fff; 

    SythLE = 1;

   delay(3);

   SythLE = 0;

   delay(3);

   for(j=0; j < = 15 ; j ++)

  {

                delay(3);

                SyClock= 0;

                if((spi_addr & 0x8000) ==0)


           SyDataO=0;

  else

            SyDataO=1;

            delay(3);

            SyClock=1;

          spi_addr=(spi_addr<<1);

          d=d<<1;

          d=d^SyDataO;

          delay(3);

}

         SythLE=1;

         SyClock=0;

         SyDataO=0;

                        return d;

}

此函數構造用於傳輸的資料封包。資料來自濕度模組。

DataFrame ( )

{

unsigned int Sensordata;

SythLE=0;

Sensordata=humidity;

SythLE=1;

SyClock=0;

}

設置RF頻率後,必須建構資料幀並發送給接收器。資料可能從任何感測器擷取,本文使用濕度感測器,並使用I2C匯流排讀取濕度和溫度值。由於RF模組充當發射器和接收器,因此可以使用相同的模組發送和接收資料,但RF模組只是氣象氣球的一部分。不過,於採用了GPS和即時時脈,氣象氣球的時間可很精確。

(參考原文: Launching a weather balloon design,by Kumar B)