方案名稱:915MHZ中遠(yuǎn)距離無線通信模塊
設(shè)計(jì)簡要說明:
利用MCU+RF實(shí)現(xiàn)中心頻率915MHZ的無線收發(fā)系統(tǒng),具體參數(shù)規(guī)格如下:
通信距離:1000-2000m
通信速率:0~57600kbs
接口類型:Micro USB/TTL串口
供電方式:USB/外部電源供電
供電范圍:DC5-18V
申請(qǐng)物料:
HY0320 10顆
HY0620 10顆
方案名稱:915MHZ中遠(yuǎn)距離無線通信模塊
設(shè)計(jì)簡要說明:
利用MCU+RF實(shí)現(xiàn)中心頻率915MHZ的無線收發(fā)系統(tǒng),具體參數(shù)規(guī)格如下:
通信距離:1000-2000m
通信速率:0~57600kbs
接口類型:Micro USB/TTL串口
供電方式:USB/外部電源供電
供電范圍:DC5-18V
申請(qǐng)物料:
HY0320 10顆
HY0620 10顆
方案設(shè)計(jì)
方案采用MCU+RF的結(jié)構(gòu),MCU采用STM2F042F6P6作為主控,RF收發(fā)器采用siliconlabs的高性能Sub1G芯片SI4463,兩個(gè)主芯片均工作在低功耗模式下,保證系統(tǒng)在性能可靠的前提下,降低系統(tǒng)功耗,通過經(jīng)過優(yōu)化算法的數(shù)傳無線收發(fā)算法,保證數(shù)據(jù)能考可靠穩(wěn)定的進(jìn)行傳輸。
下面開始上電路圖
電源電路,輸入電壓范圍DC5V-24V,增加了可恢復(fù)保險(xiǎn)絲,由于空間問題沒有在輸入端增加TVS做保護(hù)
TTL串口電路,為了增加系統(tǒng)穩(wěn)定性和可靠性,串聯(lián)了電阻,另外為做好接口兼容性,保證5V TTL串口電平,中間使用了后羿電子提供的MOSFET HY0320作為電平轉(zhuǎn)換,保證3.3V和5V電平相互轉(zhuǎn)換。
MCU主控電路,主控電路與RF芯片之間通過SPI接口進(jìn)行通信,完成數(shù)據(jù)的收發(fā)以及控制。
RF射頻電路,該電路需要通過大量測試進(jìn)行參數(shù)匹配,保證系統(tǒng)信號(hào)完整性。其中為了降低系統(tǒng)功耗,使用后羿電子提供的HY0620 進(jìn)行電源的供電與斷開的控制。
本來打算等樣片到了再繼續(xù)搞,過一段時(shí)間會(huì)比較忙,所以不等樣片了,先搞起來了,本來可以做2層板的,但是由于體積限制,板子空間太小,被迫做了4層PCB,好在目前的4層PCB的成本也不高,上PCB圖,板子尺寸:30*15mm
PCB布局圖(頂層)
PCB布局圖(底層)
頂層布線,射頻進(jìn)行了50歐姆阻抗控制,保證信號(hào)的完整性。對(duì)射頻電路進(jìn)行了合理的規(guī)劃布局。中間層
中間層(電源層)
底層布線
主程序結(jié)構(gòu)如下:
/* USER CODE END 0 */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_IWDG_Init(); MX_SPI1_Init(); // MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ //GetLockCode(); //rev_ID_write(Lock_Code1); //Lock_Code=0; //Lock_Code=rev_ID_read(); // if(Lock_Code != Lock_Code1) // return 0; //??0x123456789ABC??????ID RF_init(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ RF_TX_RX_CTRL(); RF_Process();
HAL_IWDG_Refresh(&hiwdg);//watch dog } /* USER CODE END 3 */ }
產(chǎn)品設(shè)計(jì)中涉及用到的外設(shè)包括SPI、USART、DMA、定時(shí)器以及看門狗。
其中SPI用來與RF射頻收發(fā)器進(jìn)行數(shù)據(jù)傳輸以及參數(shù)配置,USART作為用戶數(shù)據(jù)的收發(fā),DMA與USART配合提高數(shù)據(jù)收發(fā)效率
RF收發(fā)器調(diào)試,首先通過SPI接口讀取RF收發(fā)器的ID,如果ID為4463,那么可以證明通信接口通信沒問題,對(duì)RF收發(fā)芯片的初始化配置操作在工程中void RF_init()函數(shù)中實(shí)現(xiàn),下面上具體參數(shù)配置源碼
void RF_init() { Si4463_GpioInt(); HAL_DMA_Abort_IT(&hdma_usart1_tx); HAL_DMA_Abort_IT(&hdma_usart1_rx); RF_parameters_init(); RF_parameters_read(); MX_USART1_UART_Init(); HAL_UART_Receive_DMA(&huart1,tx_ph_data,buffer_size); __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //?????? sdn_reset();// reset RF SI4463_init(); // RF INIT delay_us(200); spi_read_info(); delay_us(200); HAL_NVIC_EnableIRQ(EXTI2_3_IRQn); HAL_NVIC_ClearPendingIRQ(EXTI2_3_IRQn); HAL_NVIC_SetPriority(EXTI2_3_IRQn, 1, 0); delay_us(200); nIRQ=1; recv_end_flag=0; uart_rx_len=0; rx_len_tmp=0; len_var=0; rx_init(); __HAL_UART_CLEAR_IDLEFLAG(&huart1); HAL_IWDG_Start(&hiwdg);//start iwdg }
spi_read_info();為讀取id函數(shù),返回值為4463,證明通信接口正常工作。
void SI4463_init(void) { U8 app_command_buf[20]; //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] = 125; // 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, (unsigned char *)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] = 0x31; // 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] = 0x81; // CRC = itu-c, enable 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] = 0x0a; app_command_buf[5] = 0x01; 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] = 0x05; app_command_buf[6] = 0x04; app_command_buf[7] = 0xaa; app_command_buf[8] = 0x00; app_command_buf[9] = payload_length; app_command_buf[10] = 0x00; app_command_buf[11] = 0xaa; 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, (unsigned char *)RF_MODEM_MOD_TYPE_12_data); spi_write(0x05, (unsigned char *)RF_MODEM_FREQ_DEV_0_1_data); spi_write(0x10, (unsigned char *)RF_MODEM_TX_RAMP_DELAY_12_data); spi_write(0x10, (unsigned char *)BCR_NCO_OFFSET_2_12_data); spi_write(0x10, (unsigned char *)RF_MODEM_TX_RAMP_DELAY_12_data); spi_write(0x07, (unsigned char *)RF_MODEM_AFC_LIMITER_1_3_data); //spi_write(0x10, BCR_NCO_OFFSET_2_12_data); spi_write(0x05, (unsigned char *)RF_MODEM_AGC_CONTROL_1_data); spi_write(0x10, (unsigned char *)AGC_WINDOW_SIZE_12_data); spi_write(0x0c, (unsigned char *)RF_MODEM_RAW_CONTROL_8_data); // spi_write(0x10, (unsigned char *)AGC_WINDOW_SIZE_12_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, (unsigned char *)COE13_7_0_12_data); spi_write(0x10, (unsigned char *)COE1_7_0_12_data); spi_write(0x10, (unsigned char *)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] = POWER; // set max power app_command_buf[6] =0x00; app_command_buf[7] = 0x3d; spi_write(8, app_command_buf); spi_write(0x0B, (unsigned char *)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] = rf_id[0]; app_command_buf[5] = 0xff; app_command_buf[6] = 0x40; app_command_buf[7] = rf_id[1]; app_command_buf[8] = 0xff; app_command_buf[9] = 0x01; app_command_buf[10] = rf_id[2]; app_command_buf[11] =0xff; app_command_buf[12] =0x02; app_command_buf[13] = rf_id[3]; app_command_buf[14] = 0xff; app_command_buf[15] =0x03; spi_write(16, app_command_buf); // ????í·?? spi_write(6, (unsigned char *)RF_MODEM_RAW_SEARCH2_2_data); // RF_FREQ_CONTROL_INTE_8_data[5] =uRF_FREQ_CONTROL[0]; // RF_FREQ_CONTROL_INTE_8_data[6] =uRF_FREQ_CONTROL[1]; // RF_FREQ_CONTROL_INTE_8_data[7] =uRF_FREQ_CONTROL[2]; spi_write(12, (unsigned char *)RF_FREQ_CONTROL_INTE_8_data); // set frequency }
系統(tǒng)整個(gè)工作流程大概如下:
首先配置好RF收發(fā)器,使其可以正常收發(fā)數(shù)據(jù),這包括寄存器參數(shù)配置,設(shè)備ID、中心頻率、空中傳輸速度、中斷等等配置
然后用戶通過串口發(fā)送數(shù)據(jù)時(shí),系統(tǒng)在DMA的控制下直接將數(shù)據(jù)存入指定發(fā)送緩沖區(qū),并且將發(fā)送標(biāo)志位置位,此時(shí)無線收發(fā)系統(tǒng)RF檢測到有數(shù)據(jù)要發(fā)送,便會(huì)啟動(dòng)發(fā)送數(shù)據(jù),當(dāng)RF發(fā)送數(shù)據(jù)完成后,通過中斷通知CPU數(shù)據(jù)發(fā)送完成。需要注意的是RF每次最多發(fā)送64字節(jié) 數(shù)據(jù),當(dāng)待發(fā)送數(shù)據(jù)超過64字節(jié)時(shí),系統(tǒng)會(huì)自動(dòng)拆包處理,接收數(shù)據(jù)過程與發(fā)送數(shù)據(jù)類似,只是方向相反。