发作品签到
专业版

基于AT32F435RGT7的LORA物联网射频终端

工程标签

3.5k
0
0
1

简介

基于AT32F435RGT7的LORA 433Mhz物联网射频终端

简介:基于AT32F435RGT7的LORA 433Mhz物联网射频终端

开源协议

GPL 3.0

创建时间:2023-01-10 10:58:24更新时间:2023-02-07 08:18:30

描述

基于AT32F435RGT7的LORA 433Mhz物联网射频终端

摘要

针对2.4G WIFI组网的物联网传输距离近,抗干扰能力弱,协议栈占用内存过多等问题,设计了一种基于Lora和AT32F435的的LORA 433Mhz物联网射频终端。系统使用AT32F435RGT7芯片,板载了多种器件,便于开发调试。使用Lora技术将需要执行的命令或者采集到的数据使用安信可RA-01SC Lora模块发送到接收端,或者作为接收端,主动接收发送端的数据。

硬件设计

主控芯片

本项目主控芯片采用了雅特力公司推出了AT32F435RGT7芯片,LQFP64封装,内部集成了1M的FLASH以及最多512K的SRAM,同时搭载了ARM Cortex M4F微处理器,主频最高可达288Mhz,性能较为优秀,可以满足本项目中相关的开发需求。

Lora射频模块

使用了安信可公司研发生产的RA-01SC模块,内部封装了射频电路和控制芯片LLCC68,最大发射功率22dbm,理论距离2KM左右。

NOR FLASH

本项目板载了一块W25Q128JVPIQ NOR FLASH芯片,如果主控内部的存储容量不满足需求,可以在Keil编译的时候使用分散加载和烧录算法将部分代码烧录到外置的FLASH中,配合AT32的QSPI外设中的XIP功能,主控可以从NOR FLASH中取出指令和数据,进行执行,从而满足了本项目大容量存储空间的需求。

EEPROM

板载一块AT24C02,用于存放配置。

蜂鸣器

板载蜂鸣器,可以完成提示音需求。

SD卡座

AT32F435带了两个SDIO外设,可以使用SDIO外设读取SD卡中的数据,完成相应的任务。

扩展按钮

板载四个扩展按钮,其中两个引出到排针,未使用时可以做GPIO使用。

扩展接口

板载了15*2的扩展接口,通过2.54标准间距排针引出,用于通过杜邦线外接其他外设,进行调试和完成需求。

USB接口

AT32F435内部带了两个USB OTG外设,由于设计原因,本系统电路只实现了USB device,做USB host时无法为外设供电,存在问题。

SWD调试接口

通过PH2.0引出SWD调试接口以及USART1串口,用于外接调试器烧录程序以及查看打印输出。

RTC电池

本系统抛弃了较为庞大的纽扣电池,使用了一颗超级电容用于RTC后备供电,在系统上电时,电流通过二极管流入超级电容,为其充电,超级电容内阻较大,所以无需限流电阻。当系统断电时,二极管保证了RTC电池不倒流给其他部分供电。

主程序设计

发送端设计

发送端程序在LLCC68官方驱动的基础上,完成了外设SPI以及GPIO的适配,同时移植了FreeRTOS,使用事件组响应外部中断,保证了系统实时性。

发送端的发送核心代码如下

void llcc68_rx_task(void *pvParameters)
{
    uint32_t temp = 0;
    char tmr_buf1[32];
    
    xLLCC68EventGroup = xEventGroupCreate();
    

// 芯片初始化
    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\r\n", send_msg);
            
            // rx done
            if(llcc68_irq_mask & LLCC68_IRQ_TX_DONE)
            {
                u8g2_DrawStr(&u8g2, 0, 26, "TX_DONE");
                // printf("TX_DONE\r\n");
            }
            if(llcc68_irq_mask & LLCC68_IRQ_TIMEOUT)
            {
                u8g2_DrawStr(&u8g2, 0, 26, "TIMEOUT");
                // printf("TIMEOUT\r\n");
            }
            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\r\n",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] = '\0';
                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\r\n", 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\r\n",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\r\n");
            }
            if(llcc68_irq_mask & IRQ_CRC_ERR_BIT){
                uart_printf_rtos("CRC_ERR\r\n");
            }
//            if(llcc68_irq_mask & IRQ_PREAMBLE_DETECTED_BIT){
//                uart_printf_rtos("PREAMBLE_DETECTED\r\n");
//            }
//            if(llcc68_irq_mask & IRQ_SYNC_WORD_VALID_BIT){
//                uart_printf_rtos("SYNC_WORD_VALID\r\n");
//            }
            if(llcc68_irq_mask & IRQ_HEADER_VALID_BIT){
                //uart_printf_rtos("HEADER_VALID\r\n");
            }
        }
    }
    
    vTaskDelete(NULL);
}

代码开源

发送端

https://gitee.com/fhcloud/ra01sc_rtos_dev_send

接收端

https://gitee.com/fhcloud/ra01sc_rtos_dev_recv

亚克力底板

工程中设计图部分给了亚克力底层的开孔设计图,有需要可以使用立创EDA上方菜单导出DXF外形文件,发淘宝切割。

展示图片

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
ATPI.25.png
11
2
DSC02156.png
8
3
DS_LLCC68_V1.0.pdf
19
4
SCH_Schematic1_2023-01-15.pdf
21
5
DS_AT32F435_437_V2.02_CH.pdf
13
克隆工程
添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1)
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航