前言
这一次的实验,主要是要使用两个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通讯的项目进行深入了解。