stm32+sx1268 LORA通信

发布时间 2023-06-08 18:06:49作者: 祈愿树下

前言:

由于亿佰特的lora代码不好移植,基于stm8且是IAR编译器,对于代码的处理很大困难。所以我通过搜索资料发现了泽耀科技的同配置的lora模块写了关于stm32的代码。

在实验中,我将买回来的lora模块的引脚按照手册上的需要引出并打板焊接(SPI通信的lora模块),通过stm32连接lora,lora的天线通过IPEX引出SMA接口天线。

问题:

在下载好代码,连接好之后,发现可以通信,但是LORA1发送LORA2可以接受,这个时候LORA2发送,LORA1接收不到,且这个时候LORA1和LORA2之间再也不能正常收发了。

代码分析:

主程序main.c

uint8_t g_RxBuffer[ 256 ] = { 0 }; 
uint8_t g_RxLen = 0;

int main()
{
	uint8_t irqRegs=0;
	delay_init();	    //延时函数初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//NVIC分组2:2位抢占优先级,2位响应优先
	USART1_Init(9600);		//UASRT1初始化
	LEDGPIO_Init();
	TIMx_Init(TIM2,10);	    //定时器2初始化
    
    RadioInit();            //SX1268初始化
    RadioStandby();
	{
		RadioSetTxConfig(MODEM_LORA, 22, 0,
						 2,11,
						 1, 12,
						 FALSE, TRUE  ,
						 FALSE,0, 0, 3000);

		RadioSetChannel(433000000);					 		 
	}
    
    USART_SendString( USART1 , "STM32F103+SX1268 收发测试\r\n");
    LED_Toogle(3);
    
    RadioRx(0);	
    
	while(1)
	{
        //SX1268发送
        if( Uart_dat.Receive_OK )
		{
            RadioSend( Uart_dat.Recv_Buff , Uart_dat.Receive_Num , 0 );
			Clear_Uart_Dat( &Uart_dat );
            USART_SendString( USART1 , "发送完成\r\n");
            //RadioRx(0);	工程师说加上才能自动转换接收模式,经过测试并没有解决问题。
            LED0_TOOGLE;                        //发送指示
		}
        
        //SX1268接收
        irqRegs = RadioGetIrqStatus();
        if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
		{
            RadioClearIrqStatus(IRQ_RADIO_ALL);
            RadioRx(0);                         //变为接收状态
            RadioGetBuffer( g_RxBuffer, &g_RxLen, 255 );
            
            if( g_RxLen )
            {
                USART_SendBuffDat( USART1 , g_RxBuffer , g_RxLen );
                LED1_TOOGLE;                    //接收指示灯
            }
        } 
	}
}

在SX1268手册中找到一幅图,后面可能有用。

从这边的流程图可以看出,我所遇到的问题有几种可能:

1. 系统复位之后,进入STDBY模式,对于RX接收的中断之后直接进入STDBY模式,没有继续接收。

2. 对于TX发送之后,没有进入RX模式,或者说,接收中断没有实际起作用

3. 发送TX之后,进入STDBY模式,不能接收。

通过SX1268手册,我总结几个关键点:

1. RX模式中,Single mode,在接收一次数据包之后就会进入STDBY_RC模式,需要改成Continuous mode。

这样才能不进入STDBY模式,我需要一直接受。

2. SetTx()函数,可以看到第三个点,当最后一个包被发送,IRQ TX_DONE生成,芯片回到STDBY_RC模式。

所以这边也可能有问题,我不希望他进入STDBY,我想让TX后,进入接收模式,或者接收模式就一直开着,才可以互传数据。

3. SetRx(),这个地方应该是重要的,参数设置为0x000000的时候,没有timeout,设备处于RX模式,但是在一次接收发生之后,返回STDBY_RC模式。

所以我们应该是使用Continuous mode,一直保持,直到指令改变。(有可能)。

4. 这边13步骤,IRQ TxDone完成或者Timeout之后,自动进入STDBY模式

尝试一下如何不进入,或者提前清除标志。

第10步骤,看看映射对不对。

5. 这边第10步,可以看出需要设定为RX连续接收模式,不然就会进入。

 

一些测试尝试:

1、通过用LED显示发送中断标志和接收中断标志,这边发现,第一次LORA1发送给LORA2。

LORA2有接收中断标志,但是LORA1没有发送标志。第二次发送,

LORA1有发送标志,LORA2也有接收标志。

发现:TXdone标志位,不是发送就会产生的。!!第一次发送结束好想不会产生中断标志位。

步骤分析:

1. TX步骤(上电后,或者复位后)

1. If not in STDBY_RC mode, then go to this mode with the command SetStandby(...)

这边是说第一步,如果不在stdby模式,需要用命令进入stdby模式。代码中在

void RadioStandby( void )
{
    SX126xSetStandby( STDBY_RC );
}

2. Define the protocol (LoRa® or FSK) with the command SetPacketType(...)

这边是设置调制方式LORA 或者 FSK方式,代码在设置模式中:

void RadioSetModem( RadioModems_t modem )
{
    switch( modem )
    {
    default:
    case MODEM_FSK:
//        SX126xSetPacketType( PACKET_TYPE_GFSK );
//        // When switching to GFSK mode the LoRa SyncWord register value is reset
//        // Thus, we also reset the RadioPublicNetwork variable
//        RadioPublicNetwork.Current = FALSE;
        break;
    case MODEM_LORA:
        SX126xSetPacketType( PACKET_TYPE_LORA );
        // Public/Private network register is reset when switching modems
        if( RadioPublicNetwork.Current != RadioPublicNetwork.Previous )
        {
            RadioPublicNetwork.Current = RadioPublicNetwork.Previous;
            RadioSetPublicNetwork( RadioPublicNetwork.Current );
        }
        break;
    }
}

可以看出是直接设置成MODEM_LORA模式。

3. Define the RF frequency with the command SetRfFrequency(...)

这边是设置频率,发送频率。代码在:

void RadioSetChannel( uint32_t freq )
{
    SX126xSetRfFrequency( freq );
}

也就是设置433000000,915000000等频率。

4. Define the Power Amplifier configuration with the command SetPaConfig(...)

这边是设置放大功率:

void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut )
{
    uint8_t buf[4];

    buf[0] = paDutyCycle;
    buf[1] = hpMax;
    buf[2] = deviceSel;
    buf[3] = paLut;
    SX126xWriteCommand( RADIO_SET_PACONFIG, buf, 4 );
}

参数包括,放大器的占空比、高功率输出模式的最大值、放大器引脚外设选择和功率放大器LUT

5. Define output power and ramping time with the command SetTxParams(...)

定义输出功率和斜升时间。

void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime )

sx1268_driver.c的635行。

6. Define where the data payload will be stored with the command SetBufferBaseAddress(...)

定义数据有效负载的存储位置。

void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress )
{
    uint8_t buf[2];

    buf[0] = txBaseAddress;
    buf[1] = rxBaseAddress;
    SX126xWriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 );
}

OKKK,不分析了,问题解决。在发送结束,转接收之前加个延迟。(离谱,折磨好久,也不算浪费时间,对sx1268手册看了一遍又一遍,有学到东西┭┮﹏┭┮)