Summary of LORA 433Mhz IoT RF terminal based on AT32F435RGT7
Aiming at the problems of short transmission distance, weak anti-interference ability, and too much memory occupied by the protocol stack in the 2.4G WIFI network of IoT, a LORA 433Mhz IoT based on Lora and AT32F435 was designed Networked radio frequency terminal. The system uses the AT32F435RGT7 chip and has a variety of devices onboard to facilitate development and debugging. Use Lora technology to send commands to be executed or collected data to the receiving end using the Essence RA-01SC Lora module, or as a receiving end, actively receive data from the sending end.
Hardware design
main control chip
The main control chip of this project adopts the AT32F435RGT7 chip launched by Yatli Company, LQFP64 package, which integrates 1M FLASH and up to 512K SRAM. It is also equipped with an ARM Cortex M4F microprocessor with a maximum frequency of Up to 288Mhz, the performance is relatively excellent and can meet the relevant development needs of this project.
The Lora radio frequency module
uses the RA-01SC module developed and produced by Essence Company. The radio frequency circuit and control chip LLCC68 are packaged inside. The maximum transmit power is 22dbm and the theoretical distance is about 2KM.
NOR FLASH
This project has a W25Q128JVPIQ NOR FLASH chip onboard. If the internal storage capacity of the main control does not meet the needs, you can use distributed loading and burning algorithms to burn part of the code into the external FLASH during Keil compilation. With the XIP function in the QSPI peripheral of AT32, the main control can retrieve instructions and data from NOR FLASH and execute them, thereby meeting the large-capacity storage space requirements of this project.
The EEPROM
board carries an AT24C02 for storing configuration.
Buzzer
The onboard buzzer can fulfill the prompt tone requirement.
The SD card holder
AT32F435 comes with two SDIO peripherals. You can use the SDIO peripherals to read the data in the SD card and complete the corresponding tasks.
The expansion button
has four expansion buttons onboard, two of which are led to pin headers and can be used as GPIO when not in use.
The expansion interface
has a 15*2 expansion interface onboard, which is led out through 2.54 standard spacing pin headers and is used to connect other peripherals through Dupont lines for debugging and completing requirements.
The USB interface
AT32F435 has two USB OTG peripherals inside. Due to design reasons, this system circuit only implements USB device. When used as a USB host, it cannot power the peripherals, which causes problems.
The SWD debugging interface
leads to the SWD debugging interface and USART1 serial port through PH2.0, which is used for external debugger programming and viewing print output.
RTC battery
This system abandons the relatively large button battery and uses a supercapacitor for RTC backup power supply. When the system is powered on, current flows into the supercapacitor through the diode to charge it. The internal resistance of the supercapacitor is large, so no need Current limiting resistor. When the system is powered off, the diode ensures that the RTC battery does not flow back to power other parts.
The main program design
of the sender
is based on the LLCC68 official driver. The sender program completes the adaptation of peripheral SPI and GPIO. At the same time, FreeRTOS is transplanted and the event group is used to respond to external interrupts to ensure the real-time performance of the system.
The sending core code of the sending end is as follows
void llcc68_rx_task(void *pvParameters){ uint32_t temp = 0; char tmr_buf1[32]; xLLCC68EventGroup = xEventGroupCreate();
// Chip initialization llcc68_chip_init();
// 设置射频参数 llcc68_set_tx_cfg(0xff); uint64_t i = 0; while(1) { char send_msg[30]; sprintf(send_msg, "send_msg=%03llu", i++); llcc68_send((uint8_t *)send_msg, strlen(send_msg)); LED_ORANGE_OFF(); EventBits_t uxBits; uxBits = xEventGroupWaitBits( xLLCC68EventGroup, /* The event group being tested. */ DIO_DONE_BIT, /* The bits within the event group to wait for. */ pdTRUE, /* BIT_0 & BIT_4 should be cleared before returning. */ pdFALSE, /* Don't wait for both bits, either bit will do. */ pdMS_TO_TICKS(3000) );/* Wait a maximum of 100ms for either bit to be set. */ llcc68_irq_mask_t llcc68_irq_mask; llcc68_get_and_clear_irq_status(NULL, &llcc68_irq_mask); if(uxBits & DIO_DONE_BIT) { LED_ORANGE_ON(); // ERTC ertc_time_type time; ertc_calendar_get(&time); if(temp != time.sec) { sprintf(tmr_buf1, "%02d-%02d-%02d %02d:%02d:%02d",time.year, time.month, time.day,time.hour, time.min, time.sec); temp = time.sec; } // SHOW MESSAGE u8g2_ClearBuffer(&u8g2); u8g2_SetFont(&u8g2, u8g2_font_6x13_tf); u8g2_DrawStr(&u8g2, 0, 13, send_msg); //cdc_uart_print("%s
", send_msg); // rx done if(llcc68_irq_mask & LLCC68_IRQ_TX_DONE) { u8g2_DrawStr(&u8g2, 0, 26, "TX_DONE"); // printf("TX_DONE
"); } if(llcc68_irq_mask & LLCC68_IRQ_TIMEOUT) { u8g2_DrawStr(&u8g2, 0, 26, "TIMEOUT"); // printf("TIMEOUT
"); } u8g2_DrawStr(&u8g2, 0, 64, tmr_buf1); u8g2_SendBuffer(&u8g2); } vTaskDelay(pdMS_TO_TICKS(50)); } vTaskDelete(NULL);}
接收端设计
接收端与发送端区别不大,主要完成了中断接收以及事件组处理。
接收端核心代码如下
void llcc68_rx_task(void *pvParameters){ uint32_t temp = 0; char tmr_buf1[32]; xLLCC68EventGroup = xEventGroupCreate(); llcc68_chip_init(); llcc68_set_tx_cfg(0xff); while(1) { LED_ORANGE_OFF(); EventBits_t uxBits; uxBits = xEventGroupWaitBits( xLLCC68EventGroup, /* The event group being tested. */ DIO_DONE_BIT, /* The bits within the event group to wait for. */ pdTRUE, /* BIT_0 & BIT_4 should be cleared before returning. */ pdFALSE, /* Don't wait for both bits, either bit will do. */ portMAX_DELAY );/* Wait a maximum of 100ms for either bit to be set. */ if(uxBits & DIO_DONE_BIT) { llcc68_irq_mask_t llcc68_irq_mask; llcc68_get_and_clear_irq_status(NULL, &llcc68_irq_mask); // rx done if(llcc68_irq_mask & IRQ_RX_DONE_BIT){ LED_ORANGE_ON(); llcc68_rx_buffer_status_t llcc68_rx_buffer_status; llcc68_get_rx_buffer_status(NULL, &llcc68_rx_buffer_status); //printf("%X,%X
",llcc68_rx_buffer_status.buffer_start_pointer, llcc68_rx_buffer_status.pld_len_in_bytes); uint8_t red_buf[255]; red_buf[llcc68_rx_buffer_status.pld_len_in_bytes] = ''; llcc68_read_buffer(NULL, llcc68_rx_buffer_status.buffer_start_pointer, red_buf, llcc68_rx_buffer_status.pld_len_in_bytes); //uart_printf_rtos("%s
", red_buf); llcc68_pkt_status_lora_t llcc68_pkt_status_lora; llcc68_get_lora_pkt_status(NULL, &llcc68_pkt_status_lora); char pkt_buf[32]; char pkt_buf1[32]; char pkt_buf2[32]; sprintf(pkt_buf, "rssi_pkt_in_dbm=%d", llcc68_pkt_status_lora.rssi_pkt_in_dbm); sprintf(pkt_buf1, "sig_dbm=%d", llcc68_pkt_status_lora.signal_rssi_pkt_in_dbm); sprintf(pkt_buf2, "snr_pkt_in_db=%d", llcc68_pkt_status_lora.snr_pkt_in_db); //uart_printf_rtos("rssi_pkt_in_dbm=%d,signal_rssi_pkt_in_dbm=%d,snr_pkt_in_db=%d
",llcc68_pkt_status_lora.rssi_pkt_in_dbm,llcc68_pkt_status_lora.signal_rssi_pkt_in_dbm,llcc68_pkt_status_lora.snr_pkt_in_db); ertc_time_type time; ertc_calendar_get(&time); if(temp != time.sec) { sprintf(tmr_buf1, "%02d-%02d-%02d %02d:%02d:%02d",time.year, time.month, time.day,time.hour, time.min, time.sec); temp = time.sec; } u8g2_ClearBuffer(&u8g2); u8g2_SetFont(&u8g2, u8g2_font_6x13_tf); u8g2_DrawStr(&u8g2, 0, 13, (const char *)red_buf); u8g2_DrawStr(&u8g2, 0, 26, pkt_buf); u8g2_DrawStr(&u8g2, 0, 39, pkt_buf1); u8g2_DrawStr(&u8g2, 0, 52, pkt_buf2); u8g2_DrawStr(&u8g2, 0, 64, tmr_buf1); u8g2_SendBuffer(&u8g2); llcc68_rx(); } if(llcc68_irq_mask & IRQ_HEADER_ERR_BIT) { uart_printf_rtos("HEADER_ERR
"); } if(llcc68_irq_mask & IRQ_CRC_ERR_BIT){ uart_printf_rtos("CRC_ERR
"); }// if(llcc68_irq_mask & IRQ_PREAMBLE_DETECTED_BIT){// uart_printf_rtos("PREAMBLE_DETECTED
");// }// if(llcc68_irq_mask & IRQ_SYNC_WORD_VALID_BIT){// uart_printf_rtos("SYNC_WORD_VALID
");// } if(llcc68_irq_mask & IRQ_HEADER_VALID_BIT){ //uart_printf_rtos("HEADER_VALID
"); } } } vTaskDelete(NULL);}
代码开源
发送端
https://gitee.com/fhcloud/ra01sc_rtos_dev_send
接收端
https://gitee.com/fhcloud/ra01sc_rtos_dev_recv
亚克力底板
工程中设计图部分给了亚克力底层的开孔设计图,有需要可以使用立创EDA上方菜单导出DXF外形文件,发淘宝切割。
展示图片