基于Si4432和SX1212間無線通信的實現(xiàn) 來源:原創(chuàng) 作者: 發(fā)布時間: 2015-7-27 點擊數(shù): 66 |
一、引言 在為客戶提供和RF定制的過程中,我們發(fā)現(xiàn)由于功能要求升級和產(chǎn)品更新?lián)Q代等原因,經(jīng)常會遇到需要內(nèi)嵌不同無線芯片的模塊能相互通信的問題,但芯片間的規(guī)格、參數(shù)、數(shù)據(jù)格式的各種區(qū)別讓人不知從何著手。 本次測試選用的是深圳市思為無線科技有限公司自主研發(fā)的RF模塊RF4432PRO(內(nèi)嵌Si4432芯片)和RF4463PRO(內(nèi)嵌Si4463芯片),并描述了詳細(xì)實驗過程、硬件接口和相關(guān)示例程序,希望為解決不同無線芯片間的通信問題提供一個參考的方法。 深圳市思為無線科技有限公司是一家專注于RF及傳感器類模塊應(yīng)用開發(fā)的技術(shù)、服務(wù)及銷售型公司。其針對不同的射頻芯片開發(fā)了多種應(yīng)用模塊和方案。目前產(chǎn)品覆蓋有20mW、100mW、500mW、1W、2W、3W、5W 等不同功率等級;SPI、UART(含TTL/RS232/RS485及USB)等多種通訊接口; 315/ 433/470/868/915 MHz及2.4 GHz等不同工作頻率,總共上百種模塊。多年的沉淀和積累使得深圳市思為無線科技有限公司在射頻應(yīng)用的軟硬件方面都有著強(qiáng)勁的研發(fā)實力和豐富的應(yīng)用經(jīng)驗。 二、實驗系統(tǒng)硬件設(shè)計 1. 芯片性能和特點 2.系統(tǒng)硬件設(shè)計 實驗系統(tǒng)硬件使用了無線模塊RF4432PRO和RF4463PRO及其相應(yīng)的DEMO演示板。RF4432PRO和RF4463PRO模塊內(nèi)含了經(jīng)嚴(yán)格測試通過的工業(yè)級高性能的芯片應(yīng)用電路。將各模塊通過插針連接在一起,便完成了硬件平臺的搭建。通過DEMO演示板中單片機(jī)的SPI口控制,兩個無線收發(fā)模塊之間相互通信,從而實現(xiàn)數(shù)據(jù)的無線傳輸。 無線模塊DEMO演示板(如下圖2)是配合無線前端收發(fā)模塊,為方便客戶調(diào)試程序、測試距離而研發(fā)的開發(fā)板。該DEMO演示板外置無線模塊引腳,設(shè)置參數(shù)可掉電保存。用戶可通過按鍵設(shè)置修改模塊的工作頻率、發(fā)射功率以及通訊速率等相關(guān)參數(shù)。DEMO演示板共有5種工作模式,如表2。 表3和表4分別是RF4463PRO模塊和RF4432PRO模塊的腳位定義,具體可見深圳市思為無線科技有限公司中的RF4432PRO規(guī)格書和RF4463PRO規(guī)格書。 三、無線模塊工作原理 無線信號的發(fā)射和接收是將信號調(diào)制和解調(diào)的過程。無論是相同還是不同的無線模塊通信,發(fā)射和接收兩部分調(diào)制格式、調(diào)制速率和頻率、頻偏和接收帶寬等調(diào)制參數(shù)的差別都會導(dǎo)致模塊之間無法通信的情況。 3.1 SPI總線控制時序 RF4432PRO和RF4463PRO模塊與單片機(jī)的通信是RF模塊根據(jù)單片機(jī)通過SPI總線寫入的控制命令和數(shù)據(jù)將無線信號發(fā)射出去,并將接收到的數(shù)據(jù)和自身的相關(guān)信息通過SPI總線傳送給單片機(jī)。Si4432與Si4463的SPI時序稍有區(qū)別。 3.2 測試模式 RF4432PRO和RF4463PRO模塊的DEMO演示板都有常發(fā)和常收兩種測試模式,便于調(diào)試程序。RF4432PRO和RF1212模塊在DEMO演示板測試模式下共同點是不停地傳送“101010......”,并可在相應(yīng)引腳看到接收的實時波形。 3.3 正常模式 RF4432PRO和RF4463PRO模塊的DEMO演示板的正常收發(fā)模式運行在Si4432和Si4463的PH+FIFO模式。 Si4432與Si4463都配置了64字節(jié)的FIFO及相應(yīng)的數(shù)據(jù)包處理功能。該模式下,芯片自動添加和偵測前導(dǎo)碼、同步字、校驗等,并通過中斷表示通信狀態(tài),大大方便了通信過程。在正常模式下通信,必須保證通信的兩個模塊的數(shù)據(jù)包格式設(shè)置*一致,否則芯片將無法產(chǎn)生中斷。 3.4 總結(jié) 對比Si4432和Si4463芯片的數(shù)據(jù)包格式如表5??梢园l(fā)現(xiàn)除了Si4463的數(shù)據(jù)包中可分為多個部分并各自設(shè)CRC校驗外,其余部分基本一致。為保證兩個芯片可以通信,將測試數(shù)據(jù)包格式設(shè)置如表6。
| Si4432 | Si4463 | 前導(dǎo)碼Preamble | 1~8 Bytes | 1~8 Bytes | 同步字Sync Word | 1~4 Bytes | 1~4 Bytes | 字頭TX Header | √ | √ | 數(shù)據(jù)長度Packet Length | √ | √ | 數(shù)據(jù)DATA | 0~64 Bytes | 0~64 Bytes | CRC | 0~2 Bytes | 0,2,4 Bytes |
表5: Si4432與Si4463數(shù)據(jù)包格式對比
| 前導(dǎo)碼 | 同步字 | 字頭 | 數(shù)據(jù) | 長度 | Si4432 | 8 Bytes | 2 Bytes | 4 Bytes | 10 Bytes | Si4463 | 8 Bytes | 2 Bytes | 4 Bytes | 10 Bytes | 內(nèi)容 | Si4432 | “010101...” | 0xb42b | “sw” | “ABCDEFGHIm” | Si4463 | “010101...” | 0xb42b | “sw” | “ABCDEFGHIm” |
表6:測試數(shù)據(jù)包格式 四、具體調(diào)試過程 系統(tǒng)通信采用的射頻參數(shù)設(shè)置為:收發(fā)頻率433.0 MHz、頻偏20 KHz、RF速率:1.2 Kbps。發(fā)送的數(shù)據(jù)格式如表6所示。 為確保RF4432PRO和RF4463PRO模塊都能正常工作和提供參考波形,首先分別使相同模塊能在該設(shè)置下使用DEMO演示板的正常模式通信。 4.1 對比接收與發(fā)射波形 數(shù)據(jù)包模式由于芯片自動處理數(shù)據(jù),只顯示結(jié)果,不利于程序的調(diào)試。因此我們使用DEMO演示板測試模式和外置引腳,通過同步觀察發(fā)送和接收波形這種zui直觀的方式,來判斷通信質(zhì)量的好壞。 將RF4432PRO和RF4463PRO的GPIO2和GPIO1設(shè)置為Rx Data output功能輸出,使接收的數(shù)據(jù)可以分別從GPIO2和GPIO1腳上實時輸出。使用邏輯分析儀來同步觀察RF4463PRO和RF4432PRO模塊發(fā)射、接收的波形并做相應(yīng)的對比。如圖10,可發(fā)現(xiàn)RF4432PRO和RF4463PRO能正確接收對方的發(fā)射信號。 4.2 數(shù)據(jù)包模式接收 RF4432PRO模塊和RF4463PRO模塊互相接收波形正確,因此保留射頻參數(shù),將DEMO演示板的工作模式設(shè)為正常模式,看能否讓芯片產(chǎn)生中斷。發(fā)現(xiàn)沒有RF4432PRO模塊和RF4463PRO模塊都沒有產(chǎn)生接收中斷。 分別將DEMO演示板設(shè)置成RF4432PRO正常發(fā)射、RF4463PRO測試接收,RF4463PRO正常發(fā)射、RF4432PRO測試接收,對比RF4432PRO和RF4463PRO發(fā)射的數(shù)據(jù)包波形,發(fā)現(xiàn)兩模塊的數(shù)據(jù)包格式設(shè)置不一致。 5.2 軟件結(jié)果 圖19中4432IRQ為RF4432PRO中斷引腳,4463IRQ為RF4463PRO的中斷引腳。可見每個發(fā)送中斷都有相應(yīng)的接收中斷。 六、示例程序 實驗的關(guān)鍵在于RF4432PRO和RF4463PRO模塊的初始化設(shè)置部分,其余與相同模塊間的通信程序一致。將以下測試可行的RF4432PRO和RF4463PRO模塊初始化代碼直接代入通信程序,即可實現(xiàn)RF4432PRO和RF4463PRO模塊間的通信。本實驗使用的完整測試程序可見深圳市思為無線科技有限公司的RF4432 DEMO CODE和RF4463 DEMO CODE。
6.1 RF4432PRO初始化示例 void SI4432_init(void) { ItStatus1 = spi_rw(0x03,0x00); // clr RF interrupt factor ItStatus2 = spi_rw(0x04,0x00); SpiWriteCfg(0x06|0x80, 0x00); // Set RF interrupt SpiWriteCfg(0x07|0x80, SI4432_PWRSTATE_READY); // enter ready mode SpiWriteCfg(0x09|0x80, 0x7f); // load cap = 12P
SpiWriteCfg(0x0a|0x80, 0x05); // output clk set SpiWriteCfg(0x0b|0x80,0xea); // gpio0 for digital output SpiWriteCfg(0x0c|0x80,0xea); // gpio0 for digital output SpiWriteCfg(0x0d|0x80, 0xf4); // GPIO 2 = rx data SpiWriteCfg(0x70|0x80, 0x2c); SpiWriteCfg(0x1d|0x80, 0x40); // enable afc // 1.2K bps setting SpiWriteCfg(0x1c, 0x16); // according to Silabs's excel SpiWriteCfg(0x20, 0x83); SpiWriteCfg(0x21, 0xc0); SpiWriteCfg(0x22, 0x13); SpiWriteCfg(0x23, 0xa9); SpiWriteCfg(0x24, 0x00); SpiWriteCfg(0x25, 0x04); SpiWriteCfg(0x2a, 0x14); SpiWriteCfg(0x72, 0x20); SpiWriteCfg(0x6e, 0x09); SpiWriteCfg(0x6f, 0xd5); SpiWriteCfg(0x70, 0x2c); // 1.2K bps setting end
SpiWriteCfg(0x30|0x80, 0x88); // enable packet handler, msb first, enable crc, SpiWriteCfg(0x32|0x80, 0xff); // 0x32address enable for headere byte 0, 1,2,3, receive header check for byte 0, 1,2,3 SpiWriteCfg(0x33|0x80, 0x4a); // header 3, 2, 1,0 used for head length, fixed packet length, SpiWriteCfg(0x34|0x80, 64); // preamble = 64 nibbles SpiWriteCfg(0x35|0x80, 0x20); // preamble detection = 20 bit SpiWriteCfg(0x36|0x80,b4); // sync word = 0xb42b SpiWriteCfg(0x37|0x80,2b); SpiWriteCfg(0x38|0x80, 0x00); SpiWriteCfg(0x39|0x80, 0x00); SpiWriteCfg(0x3a|0x80, 's'); // tx header SpiWriteCfg(0x3b|0x80, 'w'); SpiWriteCfg(0x3c|0x80, 'w'); SpiWriteCfg(0x3d|0x80, 'x'); SpiWriteCfg(0x3e|0x80, 10); // total tx 10 byte SpiWriteCfg(0x3f|0x80, 's'); // check hearder SpiWriteCfg(0x40|0x80, 'w'); SpiWriteCfg(0x41|0x80, 'w'); SpiWriteCfg(0x42|0x80, 'x'); SpiWriteCfg(0x43|0x80, 0xff); // all the bit to be checked SpiWriteCfg(0x44|0x80, 0xff); // all the bit to be checked SpiWriteCfg(0x45|0x80, 0xff); // all the bit to be checked SpiWriteCfg(0x46|0x80, 0xff); // all the bit to be checked SpiWriteCfg(0x6d|0x80, 0x07); // maximum ouput power SpiWriteCfg(0x79|0x80, 0x0); // non hop SpiWriteCfg(0x7a|0x80, 0x0); // non hop SpiWriteCfg(0x71|0x80, 0x22); // FiFo, FSK , not need clk
SpiWriteCfg(0x72|0x80, 0x50); // deviation: 50KHz
SpiWriteCfg(0x73|0x80, 0x0); // no frequency offset SpiWriteCfg(0x74|0x80, 0x0); // no frequency offset SpiWriteCfg(0x75|0x80,0x53); SpiWriteCfg(0x76|0x80,0x57); SpiWriteCfg(0x77|0x80,0x80); // frequency:433.5 MHz } 6.2 RF4463初始化示例 const unsigned char RF_MODEM_CLKGEN_BAND_1_data[] = {RF_MODEM_CLKGEN_BAND_1}; //according to Silabs's wireless development suite const unsigned char RF_FREQ_CONTROL_INTE_8_data[] = {RF_FREQ_CONTROL_INTE_8}; const unsigned char RF_POWER_UP_data[] = { RF_POWER_UP}; const unsigned char RF_GPIO_PIN_CFG_data[] = { RF_GPIO_PIN_CFG}; const unsigned char RF_GLOBAL_XO_TUNE_1_data[] = { RF_GLOBAL_XO_TUNE_1}; const unsigned char RF_GLOBAL_CONFIG_1_data[] = { RF_GLOBAL_CONFIG_1}; const unsigned char RF_FRR_CTL_A_MODE_4_data[] = { RF_FRR_CTL_A_MODE_4}; const unsigned char RF_PREAMBLE_TX_LENGTH_9_data[] = { RF_PREAMBLE_TX_LENGTH_9}; const unsigned char RF_SYNC_CONFIG_5_data[] = { RF_SYNC_CONFIG_5}; const unsigned char RF_PKT_CRC_CONFIG_1_data[] = { RF_PKT_CRC_CONFIG_1}; const unsigned char RF_PKT_CONFIG1_1_data[] = { RF_PKT_CONFIG1_1}; const unsigned char RF_PKT_LEN_3_data[] = { RF_PKT_LEN_3}; const unsigned char RF_PKT_FIELD_1_LENGTH_12_8_12_data[]={ RF_PKT_FIELD_1_LENGTH_12_8_12}; const unsigned char RF_PKT_FIELD_4_LENGTH_12_8_8_data[] = { RF_PKT_FIELD_4_LENGTH_12_8_8}; const unsigned char RF_MODEM_FREQ_DEV_0_1_data[] = { RF_MODEM_FREQ_DEV_0_1}; const unsigned char RF_MODEM_AGC_CONTROL_1_data[] ={ RF_MODEM_AGC_CONTROL_1}; const unsigned char RF_MATCH_VALUE_1_12_data[] ={ RF_MATCH_VALUE_1_12}; const unsigned char RF_MODEM_RSSI_COMP_1_data[] = { RF_MODEM_RSSI_COMP_1}; const unsigned char RF_MODEM_MOD_TYPE_12_data[]= {RF_MODEM_MOD_TYPE_12}; const unsigned char RF_MODEM_TX_RAMP_DELAY_8_data[]= {RF_MODEM_TX_RAMP_DELAY_8}; const unsigned char RF_MODEM_BCR_OSR_1_9_data[]={RF_MODEM_BCR_OSR_1_9}; const unsigned char RF_MODEM_AFC_GEAR_7_data[]={RF_MODEM_AFC_GEAR_7}; const unsigned charRF_MODEM_AGC_WINDOW_SIZE_9_data[]={RF_MODEM_AGC_WINDOW_SIZE_9}; const unsigned char RF_MODEM_OOK_CNT1_11_data[]={RF_MODEM_OOK_CNT1_11}; const unsigned char RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_data[]= {RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12}; const unsigned char RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_data[] ={RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12}; const unsigned char RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_data[]= {RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12}; const unsigned char RF_SYNTH_PFDCP_CPFF_7_data[]={RF_SYNTH_PFDCP_CPFF_7}; void SI4463_init(void) { U8 app_command_buf[20],i; //spi_write(0x07, RF_GPIO_PIN_CFG_data); app_command_buf[0] = 0x13; // SET GPIO PORT app_command_buf[1] = 0x14; // gpio 0 ,Rx data app_command_buf[2] = 0x02; // gpio1, output 0 app_command_buf[3] = 0x21; // gpio2, hign while in receive mode app_command_buf[4] = 0x20; // gpio3, hign while in transmit mode app_command_buf[5] = 0x27; // nIRQ app_command_buf[6] = 0x0b; // sdo spi_write(7, app_command_buf); // spi_write(0x05, RF_GLOBAL_XO_TUNE_1_data); app_command_buf[0] = 0x11; app_command_buf[1] = 0x00; app_command_buf[2] = 0x01; app_command_buf[3] = 0x00; app_command_buf[4] = 98; // freq adjustment spi_write(5, app_command_buf);
// spi_write(0x05, RF_GLOBAL_CONFIG_1_data); app_command_buf[0] = 0x11; app_command_buf[1] = 0x00; app_command_buf[2] = 0x01; app_command_buf[3] = 0x03; app_command_buf[4] = 0x40; // tx = rx = 64 byte,PH,high performance mode spi_write(5, app_command_buf); spi_write(0x08, RF_FRR_CTL_A_MODE_4_data); // disable all fast response register // spi_write(0x0D, RF_PREAMBLE_TX_LENGTH_9_data); // set Preamble app_command_buf[0] = 0x11; app_command_buf[1] = 0x10; app_command_buf[2] = 0x09; app_command_buf[3] = 0x00; app_command_buf[4] = 0x08; // 8 bytes Preamble app_command_buf[5] = 0x14; // detect 20 bits app_command_buf[6] = 0x00; app_command_buf[7] = 0x0f; app_command_buf[8] = 0x32; // no manchest.1010... app_command_buf[9] = 0x00; app_command_buf[10] = 0x00; app_command_buf[11] = 0x00; app_command_buf[12] = 0x00; spi_write(13, app_command_buf); // // RF_SYNC_CONFIG_5_data, // set sync app_command_buf[0] = 0x11; app_command_buf[1] = 0x11; app_command_buf[2] = 0x05; app_command_buf[3] = 0x00; app_command_buf[4] = 0x01; // no manchest , 2 bytes app_command_buf[5] = 0x2d; // sync byte3 app_command_buf[6] = 0xd4; // sync byte2 app_command_buf[7] = 0x00; // sync byte1 app_command_buf[8] = 0x00; // sync byte0 spi_write(9, app_command_buf); // packet crc app_command_buf[0] = 0x11; app_command_buf[1] = 0x12; app_command_buf[2] = 0x01; app_command_buf[3] = 0x00; app_command_buf[4] = 0x80; // no crc spi_write(5, app_command_buf); // packet gernale configuration app_command_buf[0] = 0x11; app_command_buf[1] = 0x12; app_command_buf[2] = 0x01; app_command_buf[3] = 0x06; app_command_buf[4] = 0x02; // CRC MSB, data MSB spi_write(5, app_command_buf); // spi_write(0x07, RF_PKT_LEN_3_data); app_command_buf[0] = 0x11; app_command_buf[1] = 0x12; app_command_buf[2] = 0x03; app_command_buf[3] = 0x08; app_command_buf[4] = 0x00; app_command_buf[5] = 0x00; app_command_buf[6] = 0x00; spi_write(7, app_command_buf); app_command_buf[0] = 0x11; app_command_buf[1] = 0x12; app_command_buf[2] = 0x0c; app_command_buf[3] = 0x0d; app_command_buf[4] = 0x00; app_command_buf[5] = 14; //header(4)+10 bytes app_command_buf[6] = 0x04; app_command_buf[7] = 0xaa; app_command_buf[8] = 0x00; app_command_buf[9] = 0x00; app_command_buf[10] = 0x00; app_command_buf[11] = 0x00; app_command_buf[12] = 0x00; app_command_buf[13] = 0x00; app_command_buf[14] = 0x00; app_command_buf[15] = 0x00; spi_write(16, app_command_buf); // set length of Field 1 -- 4
// spi_write(0x0C, RF_PKT_FIELD_4_LENGTH_12_8_8_data); app_command_buf[0] = 0x11; app_command_buf[1] = 0x12; app_command_buf[2] = 0x08; app_command_buf[3] = 0x19; app_command_buf[4] = 0x00; app_command_buf[5] = 0x00; app_command_buf[6] = 0x00; app_command_buf[7] = 0x00; app_command_buf[8] = 0x00; app_command_buf[9] = 0x00; app_command_buf[10] = 0x00; app_command_buf[11] = 0x00; spi_write(12, app_command_buf); spi_write(0x10, RF_MODEM_MOD_TYPE_12_data); spi_write(0x05, RF_MODEM_FREQ_DEV_0_1_data); spi_write(0x0C, RF_MODEM_TX_RAMP_DELAY_8_data); spi_write(0x0D, RF_MODEM_BCR_OSR_1_9_data); spi_write(0x0B, RF_MODEM_AFC_GEAR_7_data); spi_write(0x05, RF_MODEM_AGC_CONTROL_1_data); spi_write(0x0D, RF_MODEM_AGC_WINDOW_SIZE_9_data); spi_write(0x0F, RF_MODEM_OOK_CNT1_11_data); // spi_write(0x05, RF_MODEM_RSSI_COMP_1_data); app_command_buf[0] = 0x11; app_command_buf[1] = 0x20; app_command_buf[2] = 0x01; app_command_buf[3] = 0x4e; app_command_buf[4] = 0x40; spi_write(5, app_command_buf); spi_write(0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_data); spi_write(0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_data); spi_write(0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_data); // RF_PA app_command_buf[0] = 0x11; app_command_buf[1] = 0x22; app_command_buf[2] = 0x04; app_command_buf[3] = 0x00; app_command_buf[4] = 0x08; app_command_buf[5] = 127; // set max power app_command_buf[6] =0x00; app_command_buf[7] = 0x3d; spi_write(8, app_command_buf); spi_write(0x0B, RF_SYNTH_PFDCP_CPFF_7_data); // header match app_command_buf[0] = 0x11; app_command_buf[1] = 0x30; app_command_buf[2] = 0x0c; app_command_buf[3] = 0x00; app_command_buf[4] = 's'; app_command_buf[5] = 0xff; app_command_buf[6] = 0x40; app_command_buf[7] = 'w'; app_command_buf[8] = 0xff; app_command_buf[9] = 0x01; app_command_buf[10] = 'w'; app_command_buf[11] =0xff; app_command_buf[12] =0x02; app_command_buf[13] = 'x'; app_command_buf[14] = 0xff; app_command_buf[15] = 0x03; spi_write(16, app_command_buf); spi_write(5, RF_MODEM_CLKGEN_BAND_1_data); spi_write(12, RF_FREQ_CONTROL_INTE_8_data); // set frequency =433.5 7 總結(jié) 本文描述了深圳市思為無線科技有限公司的無線收發(fā)模塊通信RF4432PRO和RF4463PRO間的詳細(xì)實現(xiàn)過程、硬件接口和示例程序,經(jīng)實驗驗證可行。實現(xiàn)通信的基本方法是將RF4432PRO和RF4463PRO設(shè)置相同射頻參數(shù)及數(shù)據(jù)格式。這個方法也可以引申至其他不同無線模塊和無線芯片的通信。如遇到與文中不同的實驗現(xiàn)象,對實驗過程有疑問或其他想法歡迎與我們進(jìn)行技術(shù)交流。 |