Keine Beschreibung

dropLin 1fd2ab58cf 更新md的目录 vor 10 Monaten
STM32F10x_FWLib 42ef4e7a37 第一次提交 vor 10 Monaten
app 42ef4e7a37 第一次提交 vor 10 Monaten
core 42ef4e7a37 第一次提交 vor 10 Monaten
keil_v5 f803f8eb16 更新readme、更新keil配置项名称、优化射频操作 vor 10 Monaten
peripheral f803f8eb16 更新readme、更新keil配置项名称、优化射频操作 vor 10 Monaten
project f803f8eb16 更新readme、更新keil配置项名称、优化射频操作 vor 10 Monaten
radio f803f8eb16 更新readme、更新keil配置项名称、优化射频操作 vor 10 Monaten
.gitignore 42ef4e7a37 第一次提交 vor 10 Monaten
README.md 1fd2ab58cf 更新md的目录 vor 10 Monaten
keilkilll.bat 42ef4e7a37 第一次提交 vor 10 Monaten

README.md

基本说明

  • 编程语言:C99
  • 开发环境:MDK-ARM Standard Version: 5.14.0.0
  • 芯片型号:AT32F413RCT7 或 STM32F103RCT6,这两个型号软硬件兼容
  • 软件LIB版本:STM32F10x_StdPeriph_Lib_V3.5.0
  • 射频驱动官方库版本:V0.7
  • 烧录仿真接口:SWD
  • 烧录仿真器:J-Link 或 DAP
  • 文档编写日期:2024年5月14日

已适配的无线模块

  • VG4130SxxxN0S1系列

IO口定义

序号 模块IO MCU IO 转接板排针 模块功能 必需 备注
1 IRQ PB0 IO0 收发状态中断信号输出 输出高电平,外部可做上升沿触发检测
2 NRST PB1 IO1 芯片复位脚 N 可以不控制,悬空或者置高
3 DIO03 PC5 IO2 N
4 DIO11 PA2 IO3 N
5 NC X
6 NC X
7 VCC VCC
8 GND G
9 GND G
10 NSS PA4 NSS NSS 从机SPI片选脚
11 MOSI PA7 DO MOSI 主机SPI数据发送,从机SPI数据接收
12 MISO PA6 DI MISO P 主机SPI数据接收,从机SPI数据发送,3线SPI可以不接
13 SCK PA5 SCK SCK 主机SPI时钟输出
14 NC X
15 GND G
16 ANT

说明:

  • :表示必须连接
  • N:表示可以根据实际需要选择是否连接
  • P:表示根据SPI模式选择是否连接
  • X:表示不需要连接

SPI驱动接口

  • 固件已适配3线和4线SPI接口
  • 支持SPI时钟频率范围:最大10MHz
  • 支持SPI时钟极性:低电平,空闲状态下SCK为低电平
  • 支持SPI时钟相位:第一边沿

    工程文件架构

    ..\adapterBoardDriver_xxxxxxxxxxxxxxx_Vxx
    ├──app \\常用应用模块封装
    |  └──
    ├──core    \\MCU内核文件
    |  └──
    ├──STM32F10x_FWLib \\MCU官方库函数
    └──
    ├──image   \\md文件显示用的图片
    |  └──
    ├──keil_v5 \\keil编译器工程文件,包含编译生成的HEX文件
    |  └──Object  \\编译生成的HEX文件在此文件夹
    ├──peripheral  \\项目用到的MCU外设
    |  └──
    ├──project \\项目的主函数和GPIO定义包含文件
    |  └──
    ├──radio   \\射频底层驱动文件
    |  ├──myRadio_gpio.c  \\射频驱动接口硬件初始化
    |  └──myRadio.c   \\为无线应用通用封装API
    |  └──...
    

无线通讯开发注意事项

  • 无线频率
    1. 避免使用中心频率为射频芯片使用的晶体频率整数倍的,比如晶体频率为32MHz,就需要避免使用448MHz的中心频点
  • SPI驱动调试
    1. 首先保证SPI通讯正常,具体SPI时序需根据射频芯片要求设置,可通过示波器或者逻辑分析仪进行硬件分析
    2. SPI通讯正常后,进一步调试查看寄存器操作,读写寄存器,若能正常操作,基本可判定移植成功了
    3. 直观判断可以看射频初始化的时候ret = rf_init();这个返回值是否等于OK
  • 通讯距离 影响无线传输距离的因素
    1. 无线电频谱,包括使用的无线频段和无线波特率,原则上无线波特率越低,无线信号传播距离越远,但是时间延迟也越大,由于PAN3029射频芯片使用的是扩频调制技术,其无线波特率主要有扩频因子、带宽、容错率三个参数控制,根据这个三个参数不同组合可以得到不同的无线波特率,可以通过计算器磐启微电子PAN3029计算器.xlsx计算得到最终的波特率
    2. 发射功率,原则上发射功率越大,无线信号传播距离越远
    3. 天线增益,不同增益的天线对无线信号的接收效果影响很大
    4. 路径损耗,主要是包括无线使用的周围环境,比如楼宇、树木山峰遮挡
    5. 其他的无线信号干扰

硬件篇

  1. 无线模组转接板插槽,带金手指,可以适配不同的模块转接板
  2. 普通 LED 指示灯
  3. 显示屏,显示工作状态以及工作使用参数
  4. MCU 预留 I/O 口
  5. 主板 MCU 复位按键
  6. SWD 主板 MCU 程序下载调与调试接口
  7. 供电电源 3 档开关,可以用于切换选择测试板的供电电源,切换到 BT 档, 测试板为底部的 3 节 5 号电池供电,切换到 USB 档,测试板为⑧的 Micro-B 座子 供电,打在中间档关闭供电
  8. Micro-B USB 座子,可以用于测试板的供电;连接电脑可以做 TTL 转 USB 功 能,测试板内含 CP2102N 芯片

    编译软件工具KEIL篇

    编译参数选择

keil工程已经设置了4个选项:

  • projecet_AT:表示该工程的MCU型号选择的是雅特力AT32F413RCT7单片机,不带自定义boot功能,即不设置偏移地址
  • projecet_ST:表示该工程的MCU型号选择的是ST意法半导体STM32F103RCT6单片机,不带自定义boot功能,即不设置偏移地址
  • projecet_AT_APP:表示该工程的MCU型号选择的是雅特力AT32F413RCT7单片机,带自定义boot功能,设置偏移地址为0x000C800
  • projecet_ST_APP:表示该工程的MCU型号选择的是ST意法半导体STM32F103RCT6单片机,带自定义boot功能,设置偏移地址为0x000C800

模块演示板出厂默认烧录projecet_ST_APP工程,该工程是带boot功能的,默认选择的Debug工具是CMSIS-DAP Debugger工具,在Option->Debug->Setting->Flash Download->Programming Algorithm->Start中设置了起始地址,如果更换了Debug工具,起始地址会恢复默认,需要重新设置起始地址。

更新固件方式

  1. 使用Debug工具通过keil的Download下载,需要注意编译参数选择。
  2. 使用串口下载,通过USB数据线连接电脑,通过vollgoKit-update.exe工具升级

软件开发篇

1、进入低功耗

调用./radio/myRadio.c/myRadio_abort()函数,将射频模块进入低功耗模式,进入低功耗模式后,射频模块将不接收任何无线信号,只有当射频模块进入接收状态后,才能再次接收无线信号,具体测试参数见PAN3029_470-510MHz指标测试报告.pdf

  • 调用rf_deepsleep();可进入超低功耗模式,电流功耗200na左右,唤醒后需要重新初始化
  • 调用rf_sleep();可进入低功耗模式,电流功耗1ua左右

    void myRadio_abort(void)
    {
    if (rf_handle == 0)
    {
        return;
    }
    RF_EXT_PA_TO_IDLE();
    // rf_deepsleep();
    rf_sleep();
    }
    

2、射频模块进入接收状态

调用./radio/myRadio.c/myRadio_receiver()函数,将射频模块进入接收状态,进入接收状态后,射频模块将接收周围环境中的无线信号,并可以接收数据包。在接收状态或者发送过程不能重新调用该函数,发送需要等待发送完成才能再次调用该函数,不然会打断无线发送。接收到无线数据后,射频模块会通过IRQ引脚产生输出个信号,然后再./radio/myRadio.c/myRadio_process(void)函数中读取fifo中的数据包。

void myRadio_receiver(void)
{ 
    if (rf_handle == 0)
    {
        return;
    }
    RF_EXT_PA_TO_RX();
    if (rf_get_mode() == PAN3029_MODE_DEEP_SLEEP)
    {
        rf_deepsleep_wakeup();
        myRadio_setFrequency(rfFrequence);
        myRadio_setTxPower(rfTxPower);
        myRadio_setRfParams(rf_sf, rf_bw, rf_cr);
        myRadio_delay(10);
    }
    if (rf_get_mode() == PAN3029_MODE_SLEEP)
    {
        rf_sleep_wakeup();
        myRadio_delay(10);
    }
    rf_enter_continous_rx();
    rf_workProcess = RF_PRC_RX;
}

3、射频模块发送数据包

调用./radio/myRadio.c/myRadio_transmit(rfTxPacket_ts *packet)函数,将射频模块进入发送状态,进入发送状态后,射频模块将发送数据包,发送完成后才可以调用接收函数进入接收状态,发送完成后,射频模块会通过IRQ引脚产生输出个信号,然后再./radio/myRadio.c/myRadio_process(void)函数中读取发送完成状态。

void myRadio_transmit(rfTxPacket_ts *packet)
{
    if (rf_handle == 0)
    {
        return;
    }
    RF_EXT_PA_TO_TX();
    uint32_t getTxtime;
    if (rf_get_mode() == PAN3029_MODE_DEEP_SLEEP)
    {
        rf_deepsleep_wakeup();
        myRadio_setFrequency(rfFrequence);
        myRadio_setTxPower(rfTxPower);
        myRadio_setRfParams(rf_sf, rf_bw, rf_cr);
        myRadio_delay(10);
    }
    if (rf_get_mode() == PAN3029_MODE_SLEEP)
    {
        rf_sleep_wakeup();
        myRadio_delay(10);
    }
    
    if(rf_single_tx_data(packet->payload, packet->len, &packet->absTime) != OK)	
    {
    }
    else
    {
    }
    rf_workProcess = RF_PRC_TX;
}

4、射频初始化

调用./radio/myRadio.c/myRadio_init(int agr0, void *agr1_ptr)函数,将射频模块初始化,初始化完成后,射频模块将进入接收状态,该函数会初始化一个默认的参数,如果需要自定义参数,比如频率信道,发射功率,无线波特率等参数,可以调用相关函数接口重新设置,如果不需要自定义参数,也可以通过修改rf_set_default_para();中的默认参数:

  • ./radio/myRadio.c/myRadio_setFrequency(uint32_t freq):设置射频模块工作频率
  • ./radio/myRadio.c/myRadio_setTxPower(uint8_t power):设置射频模块发射功率
  • ./radio/myRadio.c/myRadio_setRfParams(uint8_t sf, uint8_t bw, uint8_t cr):设置射频模块无线波特率,信道带宽,编码速率

初始化完成后就可以进入接收状态或者发送无线数据包了,具体使用方法可以参考示例代码。

void myRadio_init(int agr0, void *agr1_ptr)
{
    myRadio_gpio_init(myRadio_gpioCallback);
    
/**-------------------------radio init----------------------------------**/
    uint32_t ret = 0;
#ifdef SPI_SOFT_3LINE
    PAN3029_write_reg(REG_SYS_CTL, 0x03);
    PAN3029_write_reg(0x1A, 0x83);
#endif

	ret = rf_init();
	if(ret != OK)
	{
		// printf("  RF Init Fail");
		while(1);
	}

	rf_set_default_para();

    rf_set_dcdc_mode(regulatorMode);
/**-------------------------radio init end----------------------------------**/
    myRadio_delay(10);
    RF_EXT_PA_TO_IDLE();
    if ((rfRxCallBack )agr1_ptr)
    {
        rxCb = (rfRxCallBack )agr1_ptr;
    }
    rf_handle = 0xe5;
}

5、射频底层执行

调用./radio/myRadio.c/myRadio_process(void)函数,该函数需要放在主函数中不断判断检测是否有中断触发,然后根据中断标志来解析处理。状态处理可以直接在相应的位置处理,或者通过回调函数rxCb将结果返回上一层处理

  • REG_IRQ_RX_DONE:表示接收到无线数据包
  • REG_IRQ_TX_DONE:表示无线数据包发送成功

    void myRadio_process(void)
    {
    rfRxPacket_ts rfRxPacket;
    if (rf_handle == 0)
    {
        return;
    }
    if (rf_ifq == false)
    {
        return;
    }
    rf_ifq = false;
    if (!((rf_workProcess == RF_PRC_TX) || (rf_workProcess == RF_PRC_RX)))
    {
        return;
    }
    
    uint8_t plhd_len;
    uint8_t irq = rf_get_irq();
    
    if(irq & REG_IRQ_RX_PLHD_DONE)
    {
        plhd_len = rf_get_plhd_len();
        rf_set_recv_flag(RADIO_FLAG_PLHDRXDONE);
        RxDoneParams.PlhdSize = rf_plhd_receive(RxDoneParams.PlhdPayload,plhd_len);
        //PAN3029_rst();//stop it
    
    }
    if(irq & REG_IRQ_RX_DONE)
    {
        RxDoneParams.Snr = rf_get_snr();
        RxDoneParams.Rssi = rf_get_rssi();
        rf_set_recv_flag(RADIO_FLAG_RXDONE);
        RxDoneParams.Size = rf_receive(RxDoneParams.Payload);
        rf_set_recv_flag(RADIO_FLAG_IDLE); 
        if (rxCb)
        {
            rfRxPacket.rssi = RxDoneParams.Rssi;
            rfRxPacket.len = RxDoneParams.Size;
            memcpy(rfRxPacket.payload, RxDoneParams.Payload, RxDoneParams.Size);
            rxCb(RX_STA_SECCESS, rfRxPacket);
        }
            
    }
    if(irq & REG_IRQ_CRC_ERR)
    {
        rf_set_recv_flag(RADIO_FLAG_RXERR);
        rf_clr_irq();
    
    }
    if(irq & REG_IRQ_RX_TIMEOUT)
    {
        rf_set_refresh();
        rf_set_recv_flag(RADIO_FLAG_RXTIMEOUT);
        rf_clr_irq();
        rf_set_recv_flag(RADIO_FLAG_IDLE); 
        RF_EXT_PA_TO_IDLE();
        if (rxCb)
        {
            rxCb(RX_STA_TIMEOUT, rfRxPacket);
        }
    }
    if(irq & REG_IRQ_TX_DONE)
    {
        rf_set_transmit_flag(RADIO_FLAG_TXDONE);
        rf_clr_irq();
    
        RF_EXT_PA_TO_IDLE();
        if (rxCb)
        {
            rxCb(TX_STA_SECCESS, rfRxPacket);
        }
    }
    }
    

6、无线波特率设置

可以通过void myRadio_setBaudrate(uint32_t br)或者void myRadio_setRfParams(uint8_t sf, uint8_t bw, uint8_t cr)来设置。

  • void myRadio_setBaudrate(uint32_t br):通过数组选择定义好的几组扩频因子、带宽、码率的组合即可
  • void myRadio_setRfParams(uint8_t sf, uint8_t bw, uint8_t cr):通过参数设置具体的扩频因子、带宽、码率

版本更新

  • V05

免责说明

1、本工程驱动软件只提供做演示项目使用,未经过大批量项目验证,客户需谨慎使用,如果使用在正式项目中引发的所有问题,本司概不负责。使用过程若发现任何问题,可及时与本司相关人员联系。 2、本工程所有文件可以用于商业性项目移植,无需向本司申请。