LORA_SX1278跳频_E32-400M22S(EBYTE模块)


前言

最近在用EBYTE家的E32-400M22S模块(LORA_SX1278),用作跳频操作,但在国内资料中很少提起,所以在此做记录。


一、LORA_SX1278

此为semtech家生产的芯片,除此之外还有sx1262等,1278是最早的一批叫做一代lora,他家很奇怪代码越小出的越晚。SX126X和SX127X差的很大,SX126X采用指令的形式而SX127X仍是往寄存器里送数值。

官网:

Semtech Semiconductor, IoT Systems and Cloud Connectivity | Semtech

二、E32-400M22S

ebyte家的模块,MCU用的stm8有工程DEMO,但用的IAR-STM8,不太习惯。https://www.ebyte.com/,网站有sx1278的文档但版本较早缺少很多有用的信息,建议看semtech的版本。

三、FHSS(跳频)

跳频表示为FHSS,翻阅手册找到如下解释

操作:

  1. standby模式设置一些基本参数
  2. 寄存器0x24写入非零数值
  3. 打开FHSS中断
  4. 打开RX或者TX模式
  5. 在RX或TX模式检测FHSS中断是否产生
  6. 若产生中断,要写入新的频率。没有FHSS则继续检测(若开启FH功能则必定会切换信道)
  7. 一定要清除FHSS中断
  8. 检测是否有RX,TX中断,若有则接收或者发送结束

描述:

文档里面很简单就这一段表述,可以知道0x24寄存器写入非零数值即可启动FHSS,这个数值又称为在信道停留时间,建议的>4。实测1和2都产生了信道混乱,因为时间太短无法完成跳频设置的功能。3中注意打开中断的时候不要忘记要把RX TX也打开,我在第一次操纵的时候覆盖了RXTX。4.就是正常操作模式没有什么需要注意的。5.我在发射端采用DO_WHILE编程,在死循环检测FHSS的中断,若产生RX中断则跳出循环。在接收端采用IF编程,之前采用而是DO_WHILE后才发现有时候会写死,跑不出来了。6.写入频率这个过程要快,所需时间越短越好,频率可在循环外提前计算好。

下面附上收发方的时序图

在图中,可以看到箭头所指为FHSS中断,故在每个信道开始前产生而不是在信道结束的时候产生,这是较为重要的一点。收发双方的0X24中信道停留时间即hoppingperiod此处保证了双方的时序同步。信道0中放的是前导码和同步字。

手册里还有一张图

这张图我并没有将他实现到代码里面。

四、代码实现

const uint32e_t fre_list[]=    //频率表存放跳频频率,其中起始频率为434MHz为信道0,每次跳1MHz
    {
    434000000,    //channel 1
    435000000,    //channel 2
    436000000,
    437000000,
    438000000,
    
    439000000,
    440000000,
    441000000,
    442000000,
    443000000,
    
    444000000,
    445000000,
    446000000,
    447000000,
    448000000   };

uint8e_t num_hop_channel = 15;        //表中就15个信道     
static uint8e_t config_tx[45];       //num_hop_channel*3,上表中每个信道要占用3个字节
uint32e_t freq_tx;


/****初始化只需运行一次*******/
void  HOP_INIT()
{
  
  uint8e_t i=0;
  for(i=0;i<num_hop_channel;i++)
  {
    
    freq_tx = ( uint32e_t )( ( double )fre_list[i] / ( double )FREQ_STEP );
    config_tx[i*3] = ( uint8e_t )( ( freq_tx >> 16 ) & 0xFF );
    config_tx[i*3+1] = ( uint8e_t )( ( freq_tx >> 8 ) & 0xFF );
    config_tx[i*3+2] = ( uint8e_t )( freq_tx & 0xFF );
          
  }
 
}


/*******此为EBYTE中函数,我在其中更改*****/
uint8e_t E32x_GoTransmit( uint8e_t* data, uint8e_t size )
{

  static uint8e_t Hop_channel=0;

 uint8e_t irqStatus = 0;
    

    /* 模式切换:待机 */
    E32x_SetStby();

    
    /* off跳频 寄存器地址:0x24 */
    E32x_SetRegister( 0x24,4 );
    
    /* 设置数据包长度 寄存器地址:0x22 */
    E32x_SetRegister( 0x22, size );
    
    /* FIFO:发送区 发送地址从128开始  寄存器地址:0x0E */
    E32x_SetRegister( 0x0E, 0x80 );
    
    /* FIFO:发送区 SPI写入地址从128开始  寄存器地址:0x0D */
    E32x_SetRegister( 0x0D, 0x80 );
    
    /* FIFO:写入发送数据 */
    E32x_SetFIFO( data, size );
    /* 设置GPIO映射 这里配置DIO0映射到TxDone 即触发发送完成中断
       本例程采用轮询读取模块内部标志位的方式来判断是否发送完成。所以,IO配置了也没用到。
       如需考虑中断,需要配置宏定义 EBYTE_TRANSMIT_MODE_BLOCKED 并自行做IO中断处理 */
    E32x_SetGPIO( 0x40, 0x40 );
    /* IO: 开启发送电路 */
    E32X_SetAntenna( ANTENNA_TXEN );
    
    /* 允许发送中断 */
    E32x_SetIRQ( IRQ_TXDONE );
    
    /* 清除中断标识 */
    E32x_ClearIRQ();
    
       
 /******加入跳频模式*********/
       
 E32x_SetIRQ( 0x0a );  //允许发送跳频中断
    
      
    
    /* 切换为发送模式 */
    E32x_SetTransmit(); 

    /* 阻塞 等待发送完成 */
    do
    {
        irqStatus = E32x_GetIRQ();
          /* 读取模式控制寄存器 寄存器地址:0x01   */

        if(irqStatus & IRQ_FHSSCHANGEDCHANNEL)          //产生跳频中断,提示当前信道发送完毕要跳频到下一信道
        {


          Hop_channel =( E32x_GetRegister( 0x1c )&0x3f);      //读取当前信道标号bit0~5为信道号

                //更改新的频率
          E32x_SetRegisters( 0x06, config_tx+Hop_channel*3, 3 );  //寄存器起始地址:0x06  共计3字节,采用当前信道号的方法去取频率表中的数据
            
        //  DEBUG( "\r\n CHANNEL : %d  %d",Hop_channel,irqStatus );     //直接串口打印出来,但耗时间后来采用下面方法  

          buff_tx_texxt[Hop_channel]=Hop_channel;    //先存储当前信道号,在循环外串口调试出来测试
  
         
         E32x_SetRegister( 0x12,( 0x02&irqStatus));    //清除中断当前位的中断不是全部
         
        }
        
    }
    while(  ( !( irqStatus & IRQ_TXDONE ) ) ); 
    /* 到此发送完成 清除中断 */
    E32x_ClearIRQ();
    /* 待机 */
    E32x_SetStby();    DEBUG( "\r\n TXDONE " );
    /* 回调用户处理函数 */
    Ebyte_Port_TransmitCallback( 0x0001 );
    return 0;
}

初次之外还需要注意,本代码若超过15个信道则发生乱码,并没有进行循环处理,除此之外还需要注意,sx1278中存储当前信道号的寄存器中 仅有5位保存,即只能64个信道,每次发生FHSS中断自增一,下次就是信道0,但我不知道是否影响其内部操作,如果不影响则跳频信道数还能往上加,加到FIFO的最大值没什么问题。

除此之外查阅资料,还有人写了代码GitHub - nimaltd/sx1278: sx1278 LoRa driver for Stm32 HAL

基于stm32移植性很高可以操作,比我写的好多了。

五、实验测试

下面将给出两组数据,

第一组数据采用LORA扩频因子10,发射功率20dBm,带宽126Khz,前导码20,跳频150Khz,起始频率434Mhz,CRC开,编码率4/5,低空速优化开,同步字一个字节。

1.发送字符1,信道占用0~4,其中信道0已知是前导码

很奇怪的是信道1并没有数据,接收也正常

2.前提条件不变,发射1234,四个字节数据。占用信道0~6

3.前提条件不变,发送八个字节,占用信道0~7

第二组数据采用LORA扩频因子7,发射功率20dBm,带宽500Khz,前导码10,跳频1Mhz,起始频率434Mhz,CRC开,编码率4/5,低空速优化开,同步字一个字节。发送1个字节需要8ms,计算器在sem官网有。

1.发送一个字节,占用信道0~6,大约8ms

这个与第一组数据对比可以知道信道1也被使用了,不知道为什么之前那个不行

2.发送四字节数据,占用信道0~7,大约10ms

速度很快

由于0X24寄存器中写入的是4,即HOPPINGPERIOD

总结:1278收发较为简单,但参数较少,现在有二代LORS,sx1262稍微看了一眼文档里面的跳频操作比这个复杂,过几天就研究一下

个人邮箱gaozu@chinaham.com

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值