spi.h

/******************************************************************
 * 文件:SPIx.h
 * 功能:声明SPI功能函数
 * 日期:2018-03-17
 * 作者:zx
 * 版本:Ver.1.0 | 最初版本
 * 
 * Copyright (C) 2018 zx. All rights reserved.
*******************************************************************/
#ifndef __SPI_H
#define __SPI_H
#include "stm32f10x.h"

void initSPIx(SPI_TypeDef* SPIx);
void setNSS(u8 status);
void sendSPIxByte(SPI_TypeDef* SPIx, u16 byte);
u16 readSPIxByte(SPI_TypeDef* SPIx);

#endif

SPI.c

/******************************************************************
 * 文件:SPIx.c
 * 功能:定义SPI功能函数
 * 日期:2018-03-17
 * 作者:zx
 * 版本:Ver.1.0 | 最初版本
 * 
 * Copyright (C) 2018 zx. All rights reserved.
*******************************************************************/
#include "SPIx/SPIx.h"

/**
 * 功能:初始化SPI相关引脚和SPI外设工作状态
 * 参数:
 *       SPIx:指定待初始化的SPI,SPI1-SPI3
 * 返回值:None
 */
void initSPIx(SPI_TypeDef* SPIx)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;

    if(SPIx==SPI1)
    {
        /*按需添加*/
    }else if(SPIx==SPI2)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);                //使能SPI2时钟       
    }else if(SPIx==SPI3)
    {
        /*按需添加*/
    }else 
    {
       /*按需添加*/ 
    }
    /***********************SPI GPIO配置****************************/
    if(SPIx==SPI1)
    {
        /*按需添加*/
    }else if(SPIx==SPI2)
    {
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;                      //配置PA8为NSS选通引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_SetBits(GPIOA,GPIO_Pin_8);                                 //默认拉高

        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13|GPIO_Pin_15;         //配置MOSI(PB15)和SCK(PB13)
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_14;                     //配置MISO(PB14)
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                                 
        GPIO_Init(GPIOB, &GPIO_InitStructure);
    }else if(SPIx==SPI3)
    {
        /*按需添加*/
    }else 
    {
       /*按需添加*/ 
    }
    /***********************SPI 工作模式****************************/
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置两线全双工
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                       //设置为SPI主机
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                   //8位数据帧格式
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                          //时钟线空闲低电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                        //第一个时钟沿(上升沿)采样,和SX1278一致
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                           //软件控制NSS选通
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//没有速度要求尽量设置的慢一点,这样可以兼容更多设备
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                  //高位在前传输,和SX1278一致
    SPI_InitStructure.SPI_CRCPolynomial = 7;                            //设置默认值即可
    SPI_Init(SPIx, &SPI_InitStructure);                                 //配置生效

    SPI_Cmd(SPIx, ENABLE);                                              //开启SPI
}

/**
 * 功能:设置NSS引脚状态
 * 参数:
 *       status:非0值表示拉高NSS,0表示拉低NSS
 * 返回值:None
 */
void setNSS(u8 status)
{
    if(status != 0) //拉高NSS
    {
        GPIO_SetBits(GPIOA,GPIO_Pin_8);  
    }else          //拉低NSS
    {
        GPIO_ResetBits(GPIOA,GPIO_Pin_8);  
    }
}

/**
 * 功能:发送一字节
 * 参数:
 *       SPIx:指定SPI
 *       byte:待发送数据
 * 返回值:None
 */
void sendSPIxByte(SPI_TypeDef* SPIx, u16 byte)
{
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);     //等待发送缓冲区为空
    SPI_I2S_ClearFlag(SPIx,SPI_I2S_FLAG_TXE);

    SPI_I2S_SendData(SPIx, byte);

    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);     //等待接收缓冲区非空
    SPI_I2S_ClearFlag(SPIx,SPI_I2S_FLAG_RXNE);
	
	SPI_I2S_ReceiveData(SPIx);
}

/**
 * 功能:接收一字节
 * 参数:
 *       SPIx:指定SPI
 * 返回值:读取到的数据
 */
u16 readSPIxByte(SPI_TypeDef* SPIx)
{
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);     //等待发送缓冲区为空
    SPI_I2S_ClearFlag(SPIx,SPI_I2S_FLAG_TXE);

    SPI_I2S_SendData(SPIx, 0xff);

    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);     //等待接收缓冲区非空
    SPI_I2S_ClearFlag(SPIx,SPI_I2S_FLAG_RXNE);
	
	return SPI_I2S_ReceiveData(SPIx);
}

SX1278.h

/******************************************************************
 * 文件:SX1278.h
 * 功能:定义SPI功能函数
 * 日期:2018-03-17
 * 作者:zx
 * 版本:Ver.1.0 | 最初版本
 * 声明:移植自Semtech和凌承芯官方Demo
 * Copyright (C) 2018 zx. All rights reserved.
*******************************************************************/
#ifndef __SX1278_H
#define __SX1278_H

#include "stm32f10x.h"

#define REG_LR_FIFO                                  0x00 
 // Common settings
#define REG_LR_OPMODE                                0x01 
#define REG_LR_BANDSETTING                           0x04
#define REG_LR_FRFMSB                                0x06 
#define REG_LR_FRFMID                                0x07
#define REG_LR_FRFLSB                                0x08 
 // Tx settings
#define REG_LR_PACONFIG                              0x09 
#define REG_LR_PARAMP                                0x0A 
#define REG_LR_OCP                                   0x0B 
 // Rx settings
#define REG_LR_LNA                                   0x0C 
 // LoRa registers
#define REG_LR_FIFOADDRPTR                           0x0D 
#define REG_LR_FIFOTXBASEADDR                        0x0E 
#define REG_LR_FIFORXBASEADDR                        0x0F 
#define REG_LR_FIFORXCURRENTADDR                     0x10 
#define REG_LR_IRQFLAGSMASK                          0x11 
#define REG_LR_IRQFLAGS                              0x12 
#define REG_LR_NBRXBYTES                             0x13 
#define REG_LR_RXHEADERCNTVALUEMSB                   0x14 
#define REG_LR_RXHEADERCNTVALUELSB                   0x15 
#define REG_LR_RXPACKETCNTVALUEMSB                   0x16 
#define REG_LR_RXPACKETCNTVALUELSB                   0x17 
#define REG_LR_MODEMSTAT                             0x18 
#define REG_LR_PKTSNRVALUE                           0x19 
#define REG_LR_PKTRSSIVALUE                          0x1A 
#define REG_LR_RSSIVALUE                             0x1B 
#define REG_LR_HOPCHANNEL                            0x1C 
#define REG_LR_MODEMCONFIG1                          0x1D 
#define REG_LR_MODEMCONFIG2                          0x1E 
#define REG_LR_SYMBTIMEOUTLSB                        0x1F 
#define REG_LR_PREAMBLEMSB                           0x20 
#define REG_LR_PREAMBLELSB                           0x21 
#define REG_LR_PAYLOADLENGTH                         0x22 
#define REG_LR_PAYLOADMAXLENGTH                      0x23 
#define REG_LR_HOPPERIOD                             0x24 
#define REG_LR_FIFORXBYTEADDR                        0x25
#define REG_LR_MODEMCONFIG3                          0x26

/*GPIO映射设置 用于指示发送接收状态*/
#define REG_LR_DIOMAPPING1                           0x40
#define REG_LR_DIOMAPPING2                           0x41

/*获取版本*/
#define REG_LR_VERSION                               0x42

/*其他设置*/
#define REG_LR_PLLHOP                                0x44
#define REG_LR_TCXO                                  0x4B
#define REG_LR_PADAC                                 0x4D
#define REG_LR_FORMERTEMP                            0x5B
#define REG_LR_BITRATEFRAC                           0x5D
#define REG_LR_AGCREF                                0x61
#define REG_LR_AGCTHRESH1                            0x62
#define REG_LR_AGCTHRESH2                            0x63
#define REG_LR_AGCTHRESH3                            0x64


#define GPIO_VARE_1                                  0X00
#define GPIO_VARE_2                                  0X00
#define RFLR_MODEMCONFIG2_SF_MASK                    0x0f
#define RFLR_MODEMCONFIG1_CODINGRATE_MASK            0xF1 
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK          0xFB 
#define RFLR_MODEMCONFIG1_BW_MASK                    0x0F 
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK        0xFE 
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK        0xfc
#define RFLR_MODEMCONFIG3_MOBILE_NODE_MASK           0xF7 

#define TIME_OUT_INT                                 0x80 
#define PACKET_RECVER_INT                            0x40 
#define CRC_ERROR_INT                                0x20 
#define RECVER_HEAR_INT                              0x10 
#define FIFO_SEND_OVER                               0x08 
#define RFLR_IRQFLAGS_CAD                            0x04 
#define RFLR_IRQFLAGS_FHSS                           0x02 
#define RFLR_IRQFLAGS_CADD                           0x01 

#define IRQN_TXD_Value                               0xF7
#define IRQN_RXD_Value                               0x9F
#define IRQN_CAD_Value                               0xFA
#define IRQN_SEELP_Value                             0xFF
#define PACKET_MIAX_Value                            0xff

/*工作状态枚举*/
typedef enum 
{
   Sleep_mode	    = (unsigned char)0x00, 
   Stdby_mode	    = (unsigned char)0x01, 
   TX_mode 	        = (unsigned char)0x02,
   Transmitter_mode	= (unsigned char)0x03,
   RF_mode 		    = (unsigned char)0x04,
   Receiver_mode	= (unsigned char)0x05,
   receive_single	= (unsigned char)0x06,
   CAD_mode		    = (unsigned char)0x07,
}RFMode_SET;

/*工作模式枚举*/
typedef enum 
{
   FSK_mode         = (unsigned char)0x00, 
   LORA_mode        = (unsigned char)0x80, 
}Debugging_fsk_ook;

/*使能状态*/
typedef enum
{
    false=0,
    true=1
}BOOL_t;


void initSX1278(void);
void transmitPackets(unsigned char *buffer,unsigned char len);
void receivePackets(unsigned char* buffer);

#endif


SX1278.c

/******************************************************************
 * 文件:SX1278.c
 * 功能:定义SPI功能函数
 * 日期:2018-03-17
 * 作者:zx
 * 版本:Ver.1.0 | 最初版本
 * 声明:移植自Semtech和凌承芯官方Demo
 * Copyright (C) 2018 zx. All rights reserved.
*******************************************************************/
#include "SX1278/SX1278.h"
#include "SPIx/SPIx.h"
#include "DELAY/Delay.h"

unsigned char   Frequency[3]={0x6c,0x80,0x00};

unsigned char   SpreadingFactor=7;             //扩频因子,7-12,扩频因子选小一些,发射时间会更快一些。

unsigned char   CodingRate=2;                   //编码率,1-4

unsigned char   Bw_Frequency=9;                 //信号带宽,6-9

unsigned char   powerValue= 15;                 //功率设置,作为power_data数组的索引
unsigned char   power_data[16]={0X80,0X81,0X82,0X83,0X84,0X85,0X86,0X87,0X88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f};

unsigned char   RF_EX0_STATUS;

unsigned char   CRC_Value;

unsigned char   SX1278_RLEN;

/***************************读写SX1278的基础函数********************************/
/**
 * 功能:向SX1278指定地址中写入数据,通常用作更改某寄存器中的值
 * 参数:
 *       addr:寄存器地址,寄存器地址参考头文件或者官方手册
 *            读或写由地址最高位决定
 *       byte:待发送数据
 * 返回值:None
 */
void writeSX1278(unsigned char addr, unsigned char buffer)
{ 
	setNSS(0);                      //拉低NSS
	sendSPIxByte(SPI2, addr|0x80);
	sendSPIxByte(SPI2, buffer);
	setNSS(1);                      //拉高NSS
}

/**
 * 功能:读取SX1278返回的数据
 * 参数:
 *       addr:寄存器地址,寄存器地址参考头文件或者官方手册
 *            读或写由地址最高位决定
 * 返回值:返回指定寄存器当中的值
 */	
unsigned char readSX1278(unsigned char addr)
{
	unsigned char Value;

	setNSS(0);                      //拉低NSS
	sendSPIxByte(SPI2, addr&0x7f);
	Value = readSPIxByte(SPI2);
	setNSS(1);                     //拉高NSS
	
	return Value; 
}
/**********************************~END~************************************/	

/******************************配置SX1278函数********************************/
/**
 * 功能:设置SX1278工作状态
 * 参数:
 *       opMode:操作模式 取值见RFMode_SET枚举
 * 返回值:None
 */	
void setSX1278OpMode( RFMode_SET opMode )
{
	unsigned char opModePrev;
	opModePrev=readSX1278(REG_LR_OPMODE);     //读0x01模式寄存器
	opModePrev &=0xf8;                        //清零低三位
	opModePrev |= (unsigned char)opMode;      //或上形参
	writeSX1278(REG_LR_OPMODE, opModePrev);   //重新写回去	
}

/**
 * 功能:设置SX1278工作模式
 * 参数:
 *       opMode:分为FSK和LoRa两种,通常选择LoRa
 * 返回值:None
 */	
void setSX1278LoRaFSK( Debugging_fsk_ook opMode )
{
	unsigned char opModePrev;
	opModePrev=readSX1278(REG_LR_OPMODE); //读0x01模式寄存器
	opModePrev &=0x7F; //清零最高位
	opModePrev |= (unsigned char)opMode;  //或上形参
	writeSX1278( REG_LR_OPMODE, opModePrev); //重新写回去		
}

/**
 * 功能:设置SX1278射频频率
 * 参数:None
 * 返回值:None
 * 补充:射频频率= (Frequency[0]<<16 | Frequency[1]<<8 |  Frequency[2])*61.035
 *       即射频频率 = 0x6C8000 * 61.035 = 433.99MHz
 */	
void setSX1278RFFrequency(void)
{
	writeSX1278( REG_LR_FRFMSB, Frequency[0]);  //写0x06寄存器
	writeSX1278( REG_LR_FRFMID, Frequency[1]);  //写0x07寄存器
	writeSX1278( REG_LR_FRFLSB, Frequency[2]);  //写0x08寄存器
}

/**
 * 功能:设置SX1278射频功率
 * 参数:
 *        power:功率值数组索引
 * 返回值:None
 */	
void setSX1278RFPower(unsigned char power )
{
	writeSX1278( REG_LR_PADAC, 0x87);                   //设置更高功率
	writeSX1278( REG_LR_PACONFIG,  power_data[power] ); //若没有这一句,频谱仪几乎测不到信号,但是可以进行正常收发。
}

/**
 * 功能:SX1278数据包配置
 * 参数:
 *        value:待设置值
 * 返回值:None
 */		
void setSX1278NbTrigPeaks(unsigned char value )
{
	unsigned char RECVER_DAT;
	RECVER_DAT = readSX1278( 0x31);  //Read RegDetectOptimize,
	RECVER_DAT = ( RECVER_DAT & 0xF8 ) | value; //process;
	writeSX1278( 0x31, RECVER_DAT );  //write back;
}
/**
 * 功能:设置SX1278扩频因子
 * 参数:
 *        factor:扩频因子 7-12
 * 返回值:None
 */	
void setSX1278SpreadingFactor(unsigned char factor )
{
	unsigned char RECVER_DAT;
	setSX1278NbTrigPeaks(3); //0x03-->SF7 to SF12
	RECVER_DAT=readSX1278( REG_LR_MODEMCONFIG2); //读0x1E寄存器  
	RECVER_DAT = ( RECVER_DAT & RFLR_MODEMCONFIG2_SF_MASK ) | ( factor << 4 );
	writeSX1278( REG_LR_MODEMCONFIG2, RECVER_DAT ); 
}
	
/**
 * 功能:设置SX1278纠错编码
 * 参数:
 *        value:纠错编码率 1-4
 * 返回值:None
 */
void setSX1278ErrCode(unsigned char value)
{	
	unsigned char RECVER_DAT;
	RECVER_DAT=readSX1278( REG_LR_MODEMCONFIG1); //读0x1D寄存器
	RECVER_DAT = ( RECVER_DAT & RFLR_MODEMCONFIG1_CODINGRATE_MASK ) | ( value << 1 );       //纠错编码率,位3~1。
	writeSX1278( REG_LR_MODEMCONFIG1, RECVER_DAT);
}

/**
 * 功能:设置是否开启SX1278的CRC校验
 * 参数:
 *        enable:是否使能 0或1
 * 返回值:None
 */	
void setSX1278PacketCRC(BOOL_t enable )
{	
	unsigned char RECVER_DAT;
	RECVER_DAT= readSX1278( REG_LR_MODEMCONFIG2);  //读0x1E寄存器 
	RECVER_DAT = ( RECVER_DAT & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) | ( enable << 2 );
	writeSX1278( REG_LR_MODEMCONFIG2, RECVER_DAT );
}

/**
 * 功能:设置SX1278扩频带宽
 * 参数:
 *        bw:带宽值 6-9
 * 返回值:None
 */	
void setSX1278BandWidth(unsigned char bw)
{
	unsigned char RECVER_DAT;
	RECVER_DAT=readSX1278( REG_LR_MODEMCONFIG1);  //读0x1D寄存器
	RECVER_DAT = ( RECVER_DAT & RFLR_MODEMCONFIG1_BW_MASK ) | ( bw << 4 );
	writeSX1278( REG_LR_MODEMCONFIG1, RECVER_DAT );
}

/**
 * 功能:设置是否将SX1278的报头设置为隐式模式
 * 参数:
 *        enable:使能状态,0或1
 * 返回值:None
 */		
void setSX1278ImplicitHeader(BOOL_t enable)
{
	unsigned char RECVER_DAT;
	RECVER_DAT=readSX1278( REG_LR_MODEMCONFIG1 );  //读0x1D寄存器
	RECVER_DAT = ( RECVER_DAT & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) | ( enable );
	writeSX1278( REG_LR_MODEMCONFIG1, RECVER_DAT );
}

/**
 * 功能:设置SX1278接收超时时间
 * 参数:
 *        value:超时值
 * 返回值:None
 */		
void setSX1278SymbTimeout(unsigned int value )
{
	unsigned char RECVER_DAT[2];
	RECVER_DAT[0]=readSX1278( REG_LR_MODEMCONFIG2 );    //读0x1E寄存器
	RECVER_DAT[1]=readSX1278( REG_LR_SYMBTIMEOUTLSB );  //读0x1F寄存器
	RECVER_DAT[0] = ( RECVER_DAT[0] & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) | ( ( value >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK );
	RECVER_DAT[1] = value & 0xFF;
	writeSX1278( REG_LR_MODEMCONFIG2, RECVER_DAT[0]);
	writeSX1278( REG_LR_SYMBTIMEOUTLSB, RECVER_DAT[1]);
}

/**
 * 功能:设置SX1278负载字节长度
 * 参数:
 *        value:负载字节长度,最大值256,调用时要注意
 * 返回值:None
 */		
void setSX1278PayLoadLength(unsigned char value)
{
	writeSX1278( REG_LR_PAYLOADLENGTH, value );  //写0x22寄存器,RegPayloadLength
} 
	
/**
 * 功能:是否使能SX1278低速率优化
 * 参数:
 *        enable:使能状态 0或1
 * 返回值:None
 */	
void setSX1278MobileNode(BOOL_t enable )
{	 
	unsigned char RECVER_DAT;
	RECVER_DAT=readSX1278( REG_LR_MODEMCONFIG3 );  //读0x26寄存器,低数据率优化
	RECVER_DAT = ( RECVER_DAT & RFLR_MODEMCONFIG3_MOBILE_NODE_MASK ) | ( enable << 3 );
	writeSX1278( REG_LR_MODEMCONFIG3, RECVER_DAT );
}

/**
 * 功能:设置SX1278为连续接收接收模式
 * 参数:None
 * 返回值:None
 */
void setSX1278Receive (void)
{
	setSX1278OpMode(Stdby_mode );
	writeSX1278(REG_LR_IRQFLAGSMASK,IRQN_RXD_Value);  //0x11,打开接收中断
	writeSX1278(REG_LR_HOPPERIOD,PACKET_MIAX_Value);  //0x24寄存器,设置频率跳变周期为最大
	writeSX1278( REG_LR_DIOMAPPING1,0X00);            //DIO引脚映射设置,按默认
	writeSX1278( REG_LR_DIOMAPPING2,0X00);	
	setSX1278OpMode(Receiver_mode);                   //设置为连续接收模式
}

/**
 * 功能:复位SX1278,只在初始化之前复位
 * 参数:None
 * 返回值:None
 */
void resetSX1278(void)
{
    GPIO_ResetBits(GPIOB,GPIO_Pin_12);
    Delay_ms(10);
    GPIO_SetBits(GPIOB,GPIO_Pin_12);
    Delay_ms(10);
}
/**
 * 功能:初始化SX1278
 * 参数:None
 * 返回值:None
 */	
void initSX1278(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12;            //配置PB12为SX1278复位引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB,GPIO_Pin_12);    

    resetSX1278();                                          //复位设备
	setSX1278OpMode(Sleep_mode);                            //设置睡眠模式
	setSX1278LoRaFSK(LORA_mode);	                        // 设置扩频模式
	setSX1278OpMode(Stdby_mode);                            // 设置为普通模式
	writeSX1278( REG_LR_DIOMAPPING1,GPIO_VARE_1);           //写0x40寄存器,DIO引脚映射设置,设为00.
	writeSX1278( REG_LR_DIOMAPPING2,GPIO_VARE_2);           //写0x41寄存器
	setSX1278RFFrequency();                                 //频率设置
	setSX1278RFPower(powerValue);                           //功率设置
	setSX1278SpreadingFactor(SpreadingFactor);	            // 扩频因子设置
	setSX1278ErrCode(CodingRate);		                    //纠错编码率设置
	setSX1278PacketCRC(true);			                    //CRC 校验打开
	setSX1278BandWidth(Bw_Frequency);	                    //设置扩频带宽, 125khz
	setSX1278ImplicitHeader(false);		                    //同步头是显性模式
	setSX1278PayLoadLength(0xff);                           //设置有效负载长度
	setSX1278SymbTimeout(0x3FF);                            //设置接收超时时间,TimeOut = SymbTimeout * Ts。
	setSX1278MobileNode(true); 	                            //低数据率优化,当有效数据速率较低时,必须使用LowDataRateOptimize位提高LoRa链路的鲁棒性。
	writeSX1278(REG_LR_IRQFLAGS, 0xff); 
	setSX1278Receive();                                     //设置为连续接收模式
}
/**
 * 功能:发送数据包
 * 参数:
 *       buffer:数据包地址
 *       len:数据包长度
 * 返回值:None
 */		
void transmitPackets(unsigned char *buffer,unsigned char len)
{	
	unsigned char i;
	
	setSX1278OpMode( Stdby_mode );
	writeSX1278( REG_LR_HOPPERIOD, 0 );	             //不做频率跳变
	writeSX1278(REG_LR_IRQFLAGSMASK,IRQN_TXD_Value); //打开发送中断
	writeSX1278( REG_LR_PAYLOADLENGTH, len);	     //最大数据包设置
	writeSX1278( REG_LR_FIFOTXBASEADDR, 0);          //写Tx FIFO基址
	writeSX1278( REG_LR_FIFOADDRPTR, 0 );            //FIFO指针
    
	setNSS(0);                                   //拉低NSS
	sendSPIxByte(SPI2,0x80);			             //0X00 | 0X80,突发访问,写
	for(i = 0;i<len;i++)                             //将待发送数据发送到FIFO并等待发送
	{
		sendSPIxByte(SPI2,*buffer);
		buffer++;
	}
	setNSS(1);                                       //拉高NSS
	writeSX1278(REG_LR_DIOMAPPING1,0x40);            //设置0x40寄存器为0100 0000b,即设置发射完成指示映射到DIO0引脚
	writeSX1278(REG_LR_DIOMAPPING2,0x00);
	setSX1278OpMode(Transmitter_mode);               //设置为传输模式

    while((readSX1278(REG_LR_IRQFLAGS)&0x08) != 0x08)//等待发送完成
    {
        Delay_ms(20);
    }

    writeSX1278(REG_LR_IRQFLAGS, 0xff);              //清零所有标志位,所有的DIOx口都会恢复低电平
}

void receivePackets(unsigned char* buffer)
{
    unsigned char i;
    unsigned char len;

	setSX1278Receive();
    
	if((readSX1278(REG_LR_IRQFLAGS)&0x40)==0x40)            //接收完成
	{
		if((readSX1278(REG_LR_MODEMCONFIG2)&0x04)==0x04)    //是否CRC校验完成
		{
			writeSX1278 (REG_LR_FIFOADDRPTR,0x00);          //设置SPI接口在FIFO缓冲区中的地址指针
			len = readSX1278(REG_LR_NBRXBYTES);             //读取最后一个包的字节数
			setNSS(0);
			sendSPIxByte(SPI2,0x00);                        //0X00 | 0X00,突发访问,读。
            		
			for(i=0;i<len;++i)                              //读取接收到的数据到指定数组
			{
				buffer[i]= readSPIxByte(SPI2);		
			}
			setNSS(1);
		}
		writeSX1278(REG_LR_IRQFLAGS, 0xff);  
	}        
}
/**********************************~END~************************************/





main.c

/******************************************************************
 * 文件:main.c
 * 功能:主函数入口
 * 日期:2018-02-16
 * 作者:zx
 * 版本:Ver.1.0 | 最初版本
 * 官博:http://fengmeitech.club
 * Copyright (C) 2017 zx. All rights reserved.
*******************************************************************/
#include "stdio.h8include "DELAY/Delay.h"
#include "UART/uart.h"
#include "ADC/ADC.h"
#include "LED/LED.h"
#include "IIC/IIC.h"
#include "OLED/OLED.h"
#include "SPIx/SPIx.h"
#include "SX1278/SX1278.h"

int main(void)
{
	u8 i = 0;
	u8 rx;
	/*初始化各外设*/ 
    initSysTick();  
	initADC();
    initUART();           //波特率9600
	initLED();
	initIIC();
    initOLED();

    initSPIx(SPI2);
    initSX1278();

	formatScreen(0x00);
    for(i=0;i<=128;i+=2)  //风媒电子LOGO从左向右动态显示
    {
		showImage(0,0,i,8,FM_LOGO_ENUM);
    }
	formatScreen(0x00);
    showCNString(32,0,"ooo",FONT_16_CN);
	showNumber(0,2,rx,DEC,5,FONT_16_CN);
    while (1)
    {
        receivePackets(&rx);
		printf("%d\n",rx);
		showNumber(0,2,rx,DEC,3,FONT_16_EN);
		toggleLED();
        Delay_ms(500);
    }
}