【STM8】两个单片机之间的Lora通讯实验

发布于:2022-10-22 ⋅ 阅读:(1420) ⋅ 点赞:(1)


前言

这一次的实验,主要是要使用两个STM8单片机和SX1278Lora模块,互相实现数据的接受和发送。
STM8系列的单片机,和之前WIFI台灯项目所使用的STM32一样,都是属于意法半导体公司的一款单片机。所不同的是,STM32是32位的,而STM8是8位的。8位的单片机,在之前也是使用过的,是51单片机,都是8位的单片机,但这两种单片机之间的差异也还是蛮大的。51单片机一般来说使用寄存器开发的,上大学的时候初次接触就是用的这种开发方式。STM8却是不同的,它的开发方式有些类似于它的老大哥STM32,拥有着自己的固件库,可以通过调库的方式快速开发,对比51单片机来说有着一定的效率优势,不过相对的他的价格也是更胜一筹。
这次使用的是STM8L101F3,这一款型号属于是低功耗,正好和Lora通讯的特性符合。

Lora(Long Range)通讯,是美国Semtech公司开发的一种远距离低功耗通讯方式,在物联网行业中对比其他通讯方式有着其特有的优势。
距离长,最远可以达到十公里左右。功耗低,可使用好几年。全双工双向通讯。穿透强等。常常运用在对通信距离和功耗有着严苛要求的场合。如智能停车位、智能仪表和智能农业等行业中。
当然它也有着一些劣势,比方说在中国它的频段被限制在430——510MHz,而且由于技术本身由美国公司拥有,其成本并不十分占优势……


一、SX1278的AT命令

在Semtech公司的官网上,能够下载到有关的AT命令手册,通过查看手册可找到几个常用的AT指令。
AT+IPR= 用来设置模块的波特率。
AT+MODE 参数掉电保存。
AT+ POWER = 用来设置模块的发射功率。
AT+FRE= 设置模块的工作频率, 频率设置的数值以 KHZ 为单位。
AT+FAC =,用来设置模块 Lora 通讯的扩频因子。
AT+RATE =,用来设置模块 Lora 通讯的无线数据发送或接收的速率。
AT+DAT =”String” 发送数据……
在这一次实验中,主要用AT+DAT在两个单片机之间传递数据。

二、使用步骤

1.SPI驱动

STM8单片机和Sx1278lora模块之间,是通过SPI通讯连接的,这是一种一主多从的全双工或半双工通讯方式,要注意的是通讯的时候,时钟线的拉高和拉低。

#include "hal_spi.h"
static void hal_Sx1278_GpioInt(void);
void hal_spi_Config(void)
{
  CLK_PeripheralClockConfig(CLK_Peripheral_SPI, ENABLE);  //SPI 时钟配置
  hal_Sx1278_GpioInt();   ///SPI GPIO 配置
  SPI_Init(SPI_FirstBit_MSB, SPI_BaudRatePrescaler_2, SPI_Mode_Master,SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_2Lines_FullDuplex,SPI_NSS_Soft);
  SPI_Cmd(ENABLE);
}

static void hal_Sx1278_GpioInt(void)
{
  //*****RF_rst    PD_ODR_ODR2
  GPIO_Init(RF_RST_PORT,RF_RST_PIN , GPIO_Mode_Out_PP_Low_Slow);
 //***** RF_SCK         PC_ODR_ODR4
  GPIO_Init(SCK_PORT,SCK_PIN , GPIO_Mode_Out_PP_Low_Fast);  
  //*****RF_MISO       PC_IDR_IDR5 //INPUT
  GPIO_Init(MISO_PORT,MISO_PIN , GPIO_Mode_In_PU_No_IT);
 //*****RF_MOSI       PC_ODR_ODR6
  GPIO_Init(MOSI_PORT,MOSI_PIN , GPIO_Mode_Out_PP_Low_Fast);
  //*****RF_NSEL_PIN   PC_ODR_ODR7
  GPIO_Init(CS_PORT,CS_PIN , GPIO_Mode_Out_PP_Low_Fast);
  
  //*****RF_MISO       PC_IDR_IDR5 //INPUT
  GPIO_Init(RF_IRQ_DIO0_PORT,RF_IRQ_DIO0_PIN,GPIO_Mode_In_PU_No_IT);  
  EXTI_SetPinSensitivity (EXTI_Pin_3,EXTI_Trigger_Rising);           //Lora接收中断  
  enableInterrupts();//使能中断
  
  CS_HIGH;
  RF_RST_HIGH;
}


uint8_t SpiInOut( uint8_t outData )
{
    SPI_SendData(outData );
    while( SPI_GetFlagStatus(SPI_FLAG_RXNE ) == RESET );
    return SPI_ReceiveData();
}
//功能:SX1276 寄存器写

void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;
    //NSS = 0;
    CS_LOW;
    SpiInOut( addr | 0x80 );
    for( i = 0; i < size; i++ )
    {
        SpiInOut( buffer[i] );
    }
    CS_HIGH;
}

//功能: SX1278 单个寄存器写搓澡

void SX1276WriteReg( uint8_t addr, uint8_t dat)
{
    CS_LOW;
    SpiInOut( addr | 0x80 );
    SpiInOut( dat);
    CS_HIGH;
}


//功能:SX1276 寄存器读

void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;
    CS_LOW;

    SpiInOut( addr & 0x7F );

    for( i = 0; i < size; i++ )
    {
        buffer[i] = SpiInOut( 0 );
    }
   CS_HIGH;
}
/

//功能: SX1278 单个寄存器读

uint8_t SX1276ReadReg(uint8_t addr)
{
    uint8_t dat;
    CS_LOW;
    SpiInOut( addr & 0x7F );
    dat = SpiInOut(0);
    CS_HIGH;
    return dat;
}




2.串口驱动

调试传递命令都需要串口。

#include "hal_usart.h"


uint16_t Delay_Uartrx;



Queue120 QusartRx;
Queue256 QusartTx;

const uint32_t usartIpr_Conf[USART_IPR_MAX] = {4800,9600,14400,19200,28800,38400,57600,115200};


void hal_usart_init(void)
{
  hal_usart_Config(USART_IPR_115200);
  QueueEmpty(QusartRx);  
  QueueEmpty(QusartTx);
}


void hal_usart_Config(uint32_t rate)
{
    GPIO_ExternalPullUpConfig(GPIOC,GPIO_Pin_3|GPIO_Pin_2, ENABLE);
    

    CLK_PeripheralClockConfig(CLK_Peripheral_USART, ENABLE);
    
    USART_DeInit();   串口的复位功能

    */ 
    USART_Init((uint32_t)usartIpr_Conf[rate - 1], USART_WordLength_8D, USART_StopBits_1,
               USART_Parity_No, (USART_Mode_TypeDef)(USART_Mode_Rx | USART_Mode_Tx));
 
   
    USART_ITConfig(USART_IT_TXE, DISABLE);
    
    USART_ITConfig(USART_IT_RXNE, ENABLE);

  
    enableInterrupts();  ///  
}

/*******************************************************************************
****入口参数:需要发送的字符串
****出口参数:无
****函数备注:USART发送函数
****功能;串口发送数据函数,函数长度为len 
*******************************************************************************/
void hal_usart_SendStrLen(unsigned char *Str,unsigned char len) 
{
        while(len--)//不为结束
        {
            USART_SendData8(*Str);     //发送数据 
            while(!USART_GetFlagStatus (USART_FLAG_TXE));//等待发送完毕
            Str++;//下一个数据
        }
}

void usart_interhander(void)
{
   uint8_t  redat;
   redat = USART_ReceiveData8();
   if(QueueDataLen(QusartRx) < 120)
   {
      QueueDataIn(QusartRx,&redat,1);
      Delay_Uartrx = 0;
   }
}


void hal_usart_tx_putindat(unsigned char *buf,unsigned char len)
{
    if((QueueDataLen(QusartTx) + len) < 256)
    {
        QueueDataIn(QusartTx,buf,len);
    }
}

之后还有sx1278的驱动等,通过调用SPI驱动和sx1278接发数据。


3.串口发送

在这里插入图片描述

总结

以上就是Lora通讯实验的内容了,通过该实验又接触了一款单片机,也是了解了Lora模块sx1278的基础用法,以后有机会的话,可以更进一步寻找一个Lora通讯的项目进行深入了解。

本文含有隐藏内容,请 开通VIP 后查看

网站公告


今日签到

点亮在社区的每一天
去签到