研究了好些天,刚开始把操作码当做地址了笑死,我调了好些天发现不行,昨天发现了,然后调了半天还是不行,今天发现一个东西叫状态码
然后靠状态码发现我中断之类的根本没配置进去,后来发现是发送数据太快了,笑死,然后我现在加了个10MS的延时就好了,大家如果遇到问题可以先看状态码有没有,然后是根据数据手册里的配置是下面这样的
手册配置顺序
TX
1、设置为RC模式 0x80 0x00
2、定义为LORA协议 0x8A 0x01
3、配置射频频率0x86(配置频率前需要配置图像校准)0x98
4、功率放大器配置0x95
5、输出功率和不知道啥时间0x8E
6、配置缓存基地址0x8F
7、写入数据到缓冲区,应该可以后面再写0x1E
8、扩频因子等空中速率参数 0x8B
9、最大数据包长度等数据包参数0x8C
10、配置DIO和IRQ
11、同步字Sync Word 参考 13-55(可不配)
12、开启发送状态 0x83 后面的三位数据是超时时间
13、等待发送或者超时,数据包被送出芯片自动进入RC模式
14、清除TxDone的中断标志
RX
1、设置为RC模式 0x80 0x00
2、定义为LORA协议 0x8A 0x01
3、配置射频频率0x86(配置频率前需要配置图像校准)0x98
4、配置缓存基地址 0x8F
5、扩频因子等空中速率参数 0x8B
6、数据包格式 0x8C
7、配置DIO和IRQ
8、同步字Sync Word 参考 13-55(可不配)
9、开启接收状态 0x82 后面的三位数据是超时时间
工程代码
下面是我一边摸索一边写的代码,所以很多没用的模块没删而是直接注释,可以参考一下,如果你LORA模块是硬件SPI接的就能直接用
#include "reg51.h"
#include "intrins.h"
#include <stdlib.h>
sfr P_SW1 = 0xa2;
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xc9;
sfr P5M0 = 0xca;
sfr SPSTAT = 0xcd;
sfr SPCTL = 0xce;
sfr SPDAT = 0xcf;
#define ESPI 0x02
sbit CS = P2^6;
sbit RES = P2^1;
sbit BUSY = P2^0;
sfr S2CON = 0x9A;
sfr T2L = 0xD7;
sfr T2H = 0xD6;
sfr S2BUF = 0x9B;
sfr IE2 = 0xAF;
extern const int RX_buffer_MAX;
extern volatile unsigned int Time0_count;
volatile unsigned int rx2_count = 0;
volatile unsigned int tx2_count = 0;
volatile unsigned int t2_busy = 0;
volatile unsigned int r2_busy = 0;
volatile unsigned int RX2_Timeout = 0;
volatile unsigned char rx2_buffer[128];
volatile unsigned char rxLoraBuffer[128];
void UART2_Isr(void) interrupt 8
{
// IE2 &= ~1;
if (S2CON & 0x02)
{
S2CON &= ~0x02; //清中断标志
t2_busy = 0;
tx2_count++;
}
if (S2CON & 0x01)
{
r2_busy = 0;
S2CON &= ~0x01; //清中断标志
if(rx2_count < RX_buffer_MAX) //小于最大接收时接收数据
{
rx2_buffer[rx2_count++] = S2BUF;
}
RX2_Timeout = Time0_count+10; //有数据输入时延时50MS
if(RX2_Timeout>1000)
{
RX2_Timeout-=1000; //怕计数器超量程,每次到1000会变成1,所以这边也要减
}
}
// IE2 |= 1; //允许中断
}
void Uart2Init(void) //9600bps@11.0592MHz
{
P1M0 = 0x04;
P1M1 = 0x00;
S2CON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0xE0; //设置定时初始值
T2H = 0xFE; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 1; //允许中断
EA = 1;
}
void print(unsigned char * dat)
{
while(*dat)
{
S2BUF = *dat;
t2_busy = 1;
while(t2_busy==1);
dat++;
}
}
void print_char(unsigned char dat)
{
S2BUF = dat;
t2_busy=1;
while(t2_busy==1);
}
void print_int(long dat)
{
unsigned char storage[15];
int count = 0;
if(dat<0)
{
print_char('-');
dat =~dat;
dat += 1;
}
if(dat == 0)
{
print_char('0');
}
else
{
while(dat)
{
storage[count++] = dat % 10;
dat /= 10;
}
while(count--)
{
print_char(storage[count]+48);
}
}
}
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay10us() //@11.0592MHz
{
unsigned char i, j;
i = 18;
j = 235;
do
{
while (--j);
} while (--i);
}
unsigned char Spi_WrByte(unsigned char dat)
{
SPDAT = dat; //发送测试数据
while (!(SPSTAT & 0x80)); //查询完成标志
SPSTAT = 0xc0; //清中断标
return SPDAT;
}
/*
功能:写入寄存器数据
参数:
addres - 寄存器地址
dat - 写入的数据
返回:
SPDAT - 接收到的状态码
*/
unsigned char Spi_IntWrChar(unsigned int addres,unsigned char dat)
{
int count = 0;
CS = 0;
Spi_WrByte(0x0D);
Spi_WrByte((unsigned char)(((addres&0xFF00)>8)));
Spi_WrByte((unsigned char)(addres&0x00FF));
Spi_WrByte(dat);
CS = 1;
return SPDAT;
}
/*
功能:写入指令数据
参数:
addres - 操作码
dat - 写入的数据
返回:
SPDAT - 接收到的状态码
*/
unsigned char Spi_WrChar(unsigned char addres,unsigned char dat)
{
int count = 0;
CS = 0;
//Spi_WrByte(0x0D);
//Spi_WrByte((unsigned char)(((addres&0xFF00)>8)));
Spi_WrByte(addres);
Spi_WrByte(dat);
CS = 1;
if((SPDAT & 0x0F)== 0x08)
{
print_char(0xFF);
print_char(addres);
print_char(SPDAT);
}
return SPDAT;
}
/*
功能:写入多位指令数据
参数:
addres - 操作码
dat - 写入的数据
com_size - 发送长度
返回:
SPDAT - 接收到的状态码
*/
unsigned char Spi_WrData(unsigned char addres,unsigned char * dat,int com_size)
{
int count = 0;
CS = 0;
//Spi_WrByte(0x0D);
//Spi_WrByte((unsigned char)(((addres&0xFF00)>8)));
Spi_WrByte(addres);
for(count=0;count<com_size;count++)
{
Delay10us();
Spi_WrByte(dat[count]);
// if((SPDAT & 0x0F)== 0x08)
// {
// print_char(0xFF);
// print_char(addres);
// print_char(SPDAT);
// }
// if(addres == 0x08)
// {
// print_char(0x99);
// print_char(count);
// print_char(SPDAT);
// }
}
CS = 1;
return SPDAT;
}
/*
功能:读取lora寄存器数据
参数:
addres - 地址
返回:
dat - 读取到的数据
*/
unsigned char Spi_IntReChar(unsigned int addres)
{
int count = 0;
unsigned char dat;
CS = 0;
Spi_WrByte(0x1D);
Spi_WrByte((unsigned char)(((addres&0xFF00)>8)));
Spi_WrByte((unsigned char)(addres&0xFF));
Spi_WrByte(0x00);
dat = Spi_WrByte(0xFF);
CS = 1;
return dat;
}
/*
功能:采集单个lora数据
参数:
addres - 操作码
返回:
dat - 接收到的数据
*/
unsigned char Spi_ReChar(unsigned char addres)
{
int count = 0;
unsigned char dat;
CS = 0;
Spi_WrByte(addres);
Spi_WrByte(0xFF);
dat = Spi_WrByte(0xFF);
CS = 1;
return dat;
}
/*
功能:采集lora多位数据
参数:
addres - 操作码
dat_size - 采集长度
返回:
dat - 接收到的数组
*/
unsigned char * Spi_ReData(unsigned char addres,int dat_size)
{
int count = 0;
static unsigned char dat[10];
CS = 0;
//Spi_WrByte(0x1D);
//Spi_WrByte((unsigned char)(((addres&0xFF00)>8)));
Spi_WrByte(addres);
Spi_WrByte(0xFF);
for(count=0;count<dat_size;count++)
{
dat[count] = Spi_WrByte(0xFF);
}
CS = 1;
return dat;
}
/*
功能:配置LORA设备收发频率
参数:
RF - 十进制频率
返回:无
*/
void SX126xSetRfFrequency(unsigned long RF) //频率
{
unsigned char buf[4];
unsigned long freq = 0;
unsigned long stepsInt = 0;
unsigned long SX126X_PLL_STEP_SCALED = (32000000>>(25-14));
unsigned int SX126X_PLL_STEP_SHIFT_AMOUNT = 14;
stepsInt = RF / SX126X_PLL_STEP_SCALED;
freq = RF - (stepsInt * SX126X_PLL_STEP_SCALED);
freq = ( stepsInt << SX126X_PLL_STEP_SHIFT_AMOUNT ) + //移位14
( ( ( freq << SX126X_PLL_STEP_SHIFT_AMOUNT ) + ( SX126X_PLL_STEP_SCALED >> 1 ) ) /
SX126X_PLL_STEP_SCALED );
buf[0] = (unsigned char)((freq>>24)&0xff);
buf[1] = (unsigned char)((freq>>16)&0xff);
buf[2] = (unsigned char)((freq>>8)&0xff);
buf[3] = (unsigned char)((freq)&0xff);
Spi_WrData(0x86,buf,4);
}
void SPI_Init(void)
{
P1M0 = 0x00;
P1M1 = 0x00;
P_SW1 = 0x00;
SPCTL = 0xD0; //使能SPI主机模式
SPSTAT = 0xc0; //清中断标志
}
void lora_Tx_Init(void)
{
unsigned char loraData[10];
Spi_WrChar(0x80,0x00);//配置为RC模式
Spi_WrChar(0x9D,0x01);//配置DIO2为TX模式
Spi_WrChar(0x96,0x01);//配置为TX与RX模式
Spi_WrChar(0x8A,0x01);//启动lora模式
loraData[0] = 0x75;
loraData[1] = 0x81;
Spi_WrData(0x98,loraData,2); //频率配置前要配置这个,不知道是啥 //有问题
// print_char(0x74);
// print_char(Spi_ReChar(0xc0));
SX126xSetRfFrequency(470000000);//配置频率
loraData[0] = 0x04;
loraData[1] = 0x07;
loraData[2] = 0x00;
loraData[3] = 0x01;
Spi_WrData(0x95,loraData,4);//配置占空比功率参数等,后两位是保留参数不能修改,这里是配置为22dBm
loraData[0] = 20;
loraData[1] = 0x02;
Spi_WrData(0x8E,loraData,2);//配置发射功率和不知道什么时间
loraData[0] = 0x00;
loraData[1] = 0x00;
Spi_WrData(0x8F,loraData,2);//配置收发存储地址
//数据发送到暂存区,这个应该可以后面再说?
loraData[0] = 0x07;
loraData[1] = 0x0A;
loraData[2] = 0x01;
loraData[3] = 0x00;
Spi_WrData(0x8B,loraData,4);//配置扩频因子为7,带宽为41,纠错码4/5,关闭低速率优化,所以是配置为1820空中速率
loraData[0] = 0x00;
loraData[1] = 0x08;//前导码长度
loraData[2] = 0x00;//可变数据包长
loraData[3] = 0xFF;//最大包长255
loraData[4] = 0x01;//关闭CRC校验
loraData[5] = 0x00;//标准IQ设置
Spi_WrData(0x8C,loraData,6);//配置数据包最大包长等数据包参数
loraData[0] = 0xFF;
loraData[1] = 0xFF;
loraData[2] = 0xFF;
loraData[3] = 0xFF;
loraData[4] = 0x00;
loraData[5] = 0x00;
loraData[6] = 0x00;
loraData[7] = 0x00;
Spi_WrData(0x08,loraData,8);//配置DIO和IRQ
// print_char(0x81);
// print_char(Spi_ReChar(0xc0));
}
void lora_Rx_Init(void)
{
unsigned char loraData[10];
Spi_WrChar(0x80,0x00);//配置为RC模式
Spi_WrChar(0x9D,0x00);//配置DIO2为RX模式
Spi_WrChar(0x96,0x01);//配置为TX与RX模式
Spi_WrChar(0x8A,0x01);//启动lora模式
loraData[0] = 0x75;
loraData[1] = 0x81;
Spi_WrData(0x98,loraData,2); //频率配置前要配置这个,不知道是啥
SX126xSetRfFrequency(470000000);//配置频率
loraData[0] = 0x00;
loraData[1] = 0x00;
Spi_WrData(0x8F,loraData,2);//配置收发存储地址
loraData[0] = 0x07;
loraData[1] = 0x0A;
loraData[2] = 0x01;
loraData[3] = 0x00;
Spi_WrData(0x8B,loraData,4);//配置扩频因子为7,带宽为41,纠错码4/5,关闭低速率优化,所以是配置为1820空中速率
loraData[0] = 0x00;
loraData[1] = 0x08;//前导码长度
loraData[2] = 0x00;//可变数据包长
loraData[3] = 0xFF;//最大包长255
loraData[4] = 0x01;//关闭CRC校验
loraData[5] = 0x00;//标准IQ设置
Spi_WrData(0x8C,loraData,6);//配置数据包最大包长等数据包参数
loraData[0] = 0xFF;
loraData[1] = 0xFF;
loraData[2] = 0xFF;
loraData[3] = 0xFF;
loraData[4] = 0x00;
loraData[5] = 0x00;
loraData[6] = 0x00;
loraData[7] = 0x00;
Spi_WrData(0x08,loraData,8);//配置DIO和IRQ
Spi_IntWrChar(0x08D8,Spi_IntReChar(0x08D8)|0x1E);//芯片初始化的时候0x08D8的第1位到第四位需要配置为1
Spi_IntWrChar(0x0736,Spi_IntReChar(0x0736)|0x02);//芯片初始化的时候0x08D8的第1位到第四位需要配置为1
}
void lora_Init(void)
{
//unsigned char calFreq[10];
//unsigned char loraData[10];
// loraData[0] = 0x00;
// loraData[1] = 0x00;
// Spi_WrChar(0x0080,0x00);//配置为XOSC模式,不过案例不是这个模式,需要修改可能
// Spi_WrData(0x008F,loraData,2);//配置收发地址
// Spi_WrChar(0x0096,0x01);
// Spi_WrChar(0x0008,0x00);//屏蔽中断
// Spi_WrChar(0x8A,0x01);//启动lora模式
// loraData[0] = 0x34;
// loraData[1] = 0x44;
// Spi_WrData(0x0740,loraData,2);//配置为公共地址
//
// loraData[0] = 0x07;
// loraData[1] = 0x0A;
// loraData[2] = 0x01;
// loraData[3] = 0x00;
// Spi_WrData(0x008B,loraData,4);//配置扩频因子为7,带宽为41,纠错码4/5,关闭低速率优化,所以是配置为1820空中速率
// loraData[0] = 0x00;
// loraData[1] = 0x01;//前导码长度
// loraData[2] = 0x00;//可变数据包长
// loraData[3] = 0xFF;//最大包长255
// loraData[4] = 0x01;//关闭CRC校验
// loraData[5] = 0x00;//标准IQ设置
// Spi_WrData(0x008C,loraData,6);//配置数据包基本参数
// Spi_WrChar(0x08D8,Spi_ReChar(0x08D8)|0x1E);//芯片初始化的时候0x08D8的第1位到第四位需要配置为1
// loraData[0] = 0x04;
// loraData[1] = 0x07;
// loraData[2] = 0x00;
// loraData[3] = 0x01;
// Spi_WrData(0x0095,loraData,4);//配置占空比功率参数等,后两位是保留参数不能修改,这里是配置为22dBm
// loraData[0] = 0x00;
// loraData[1] = 0x04;
// Spi_WrData(0x008E,loraData,2);//配置发射功率和不知道什么时间
// calFreq[0] = 0x75;
// calFreq[1] = 0x81;
// Spi_WrData(0x0098,calFreq,2); //频率配置前要配置这个,不知道是啥
// SX126xSetRfFrequency(475200000); //配置频率
// Spi_WrChar(0x009F,0x00);//接收到前导码就关闭接收超时
// Spi_WrChar(0x08E7,0x38); //电路保护等级设置为140ma,最低是0x18 60ma
// CS = 0;
// calFreq[0] = 0x75;
// calFreq[1] = 0x81;
// Spi_WrData(0x0098,calFreq,2); //频率配置前要配置这个,不知道是啥
// CS = 1;
// SX126xSetRfFrequency(475200000); //配置频率
// loraData[0] = 0x00;
// loraData[0] = 0x00;
// Spi_WrChar(0x08D8, Spi_ReChar( 0x08D8 ) | 0x1E ); //初始化时就是要给他或上1E,不知道为啥,数据手册15节说的
// Spi_WrData(0x008F,loraData,2); //RXTX的地址位
// SX126xSetPaConfig(0x04, 0x07, 0x00, 0x01);
// Spi_WrChar(0x08E7,0x38); //电路保护等级设置为140ma,最低是0x18 60ma
// loraData[0] = 22;
// loraData[1] = 0x00;
// Spi_WrData( 0x008E, loraData, 2 ); //配置功率和不知道啥时间的
}
/*
功能:往FIFO空间写入数据
参数:
dat - 写入数组
dataSize - 数据长度
返回:无
*/
void FIFO_Wr(unsigned char * dat,unsigned int dataSize)
{
int count=0;
CS = 0;
Spi_WrByte(0x0E);
Spi_WrByte(0x00);
for(count = 0; count < dataSize; count++)
{
Spi_WrByte(dat[count]);
}
CS = 1;
}
/*
功能:往FIFO空间读数据
参数:
dat - 存读数的数组
dataSize - 数据长度
返回:无
*/
void FIFO_Re(unsigned char * dat,unsigned int dataSize)
{
int count=0;
CS = 0;
Spi_WrByte(0x1E);
Spi_WrByte(0x00);
Spi_WrByte(0x00);
for(count = 0; count < dataSize; count++)
{
dat[count] = Spi_WrByte(0xFF);
}
CS = 1;
}
void main()
{
int a = 0,b = 0,count=0,mode = 0;//mode 0 发送 1 接收
unsigned char * dat = NULL;
unsigned long RF_data = 0;
unsigned char loraData[10];
unsigned char RxBuffer[10];
P2M0 = 0x00;
P2M1 = 0x00;
CS = 1;
SPI_Init();
// RES = 0;
// Delay1000ms();
// RES = 1;
// Delay1000ms();
Uart2Init();
//lora_Init();
if(mode == 0)
{
lora_Tx_Init();
Spi_IntWrChar(0x0889,Spi_IntReChar(0x0889)|0x02);//发送前需要配置
// loraData[0] = 0xff;
// loraData[1] = 0xff;
// loraData[2] = 0xff;
// Spi_WrData(0x0083,loraData,3);
}
else
{
lora_Rx_Init();
// print_char(0x71);
// print_char(Spi_ReChar(0xc0));
loraData[0] = 0xff;
loraData[1] = 0xff;
loraData[2] = 0xff;
Spi_WrData(0x82,loraData,3);//配置为RX模式
// print_char(0x72);
// print_char(Spi_ReChar(0xc0));
}
while (1)
{
a++;
// print_char(a%2);
// Delay1000ms();
// if(a%2==0)
// {
//
// }
// if(a%2==1)
// {
// CS = 0;
// calFreq[0] = 0x6B;
// calFreq[1] = 0x6F;
// Spi_WrData(0x0098,calFreq,2);
// CS = 1;
// SX126xSetRfFrequency(433000000);
// }
//读写测试
// loraData[0] = a%5;
// loraData[1] = a%5+5;
// Spi_WrData(0x95,loraData,2);
// dat = Spi_ReData(0x95,2);
// print_char(dat[0]);
// print_char(dat[1]);
dat= Spi_ReData(0x12,2);//读取中断情况
if((dat[1] & 0x01) == 0x01)
{
// print_char(0x66);
// print_char(dat[0]);
// print_char(dat[1]);
Spi_WrData(0x02,dat,3);//清除中断
}
else
{
//print_char(dat[0]);
//print_char(dat[1]);
Spi_WrData(0x02,dat,3);//清除中断
//print_char('\n');
}
if(mode == 0)
{
loraData[0] = 0x02;//发送超时
loraData[1] = 0x01;//发送完成
loraData[2] = 0x02;
loraData[3] = 0x01;
loraData[4] = 0x00;
loraData[5] = 0x00;
loraData[6] = 0x00;
loraData[7] = 0x00;
Spi_WrData(0x08,loraData,8);//配置DIO和IRQ
//
// print_char(0x70);
// print_char(Spi_ReChar(0xc0));
loraData[0] = 0x00;
loraData[1] = 0x08;//前导码长度
loraData[2] = 0x00;//可变数据包长
loraData[3] = 0x03;//最大包长255 //根据你发的包来判断,可以隔64字节发一个
loraData[4] = 0x01;//关闭CRC校验
loraData[5] = 0x00;//标准IQ设置
Spi_WrData(0x8C,loraData,6);//配置数据包最大包长等数据包参数
loraData[0] = a%2;
loraData[1] = a%3;
loraData[2] = a%4;
FIFO_Wr(loraData,3); //发送数据
// print_char(0x71);
// print_char(Spi_ReChar(0xc0));
loraData[0] = 0x00;
loraData[1] = 0x00;
loraData[2] = 0x00;
Spi_WrData(0x83,loraData,3);//配置为TX模式
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
FIFO_Re(loraData,3);
print_char(loraData[0]);
print_char(loraData[1]);
print_char(loraData[2]);
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
}
else
{
if((dat[1] & 0x02) == 0x02)
{
Spi_IntWrChar(0x0902,0x00);
Spi_IntWrChar(0x0944,Spi_IntReChar(0x0944)|0x02);
dat = Spi_ReData(0x13,2);//读取接收包长和首地址
print_char(dat[0]);
print_char(dat[1]);
FIFO_Re(RxBuffer,dat[0]);
for(count=0; count<dat[0]; count++)
{
print_char(RxBuffer[count]);
}
loraData[0] = 0x00;
loraData[1] = 0x00;
Spi_WrData(0x8F,loraData,2);//配置收发存储地址
Delay1000ms();
Delay1000ms();
}
}
Delay1000ms();
}
}