对LORA想入非非已久, 可惜工作任务重, 一直未能找到机会.
正好原子哥出了模块, 而工作中又刚好需要数传, 哈~~~马上出手.
之前已买了排针版, 放着吃尘, 10号原子哥发布新品, 有了邮票孔版本.
图中红色PCB是自己打的转接板, 说起这个板, 心里苦吖
其实这模块真的很简单,只是明白简单前, 倍受磨难.
刚开始调试明, 用先买的排针版本,
A方=开发板+排线, B方=工作PCB+排线,
原以为串口收发数据, 很容易调好, 天天打交道, 寄存器都能背七七八八的, 结果…
差点从入门到放弃.
硬是没调好, 找原因呗, 硬件, 资料, PDF, 还是时通时断的,
后来, 火大了, 丢掉开发板和排线, 爷打个板, 专门服侍这模块,
板子回来后, OK, 命令, 参数, 收, 发 , 各种简单清晰, 砍柴还是要磨刀的,
F-U-C-K !!! 只能怨自己喽.
苦水吞完, 说说重点:
1: 使用真的很简单, 想成高大上不好,
2: USART接收和发送, 和用USART输出数据到串口助手一个道理,
3: 原子哥的模块例程, 主要在LCD显示 和 设置命令 这些地方, 可用性不大, 别花大把时间 ,
4: 下面把代码贴出来, 其中把设置命令的代码全弃掉了(最麻烦就这部分), 反正我不用, 也用不到
5: 硬件连线: 模块TX <> usart_RX, 模块RX<>usart_TX, 接上3.3v, 接上GND
6: 编程步骤: 初始化GPIO > 初始化USART > 写发送函数 > 写接收中断 >
7: 接收中断这里, 这一秒收到的, 和下一秒收到的是不是同一串数据呢? 如何判断一组数据的结束, 要处理好, 原子哥例程中的处理, 转来转去, 我不太好理解, 也改了, 也用0xD和0xA作为接收结束标志, 和原子哥的顺序有点反, 感觉这样处理换行更合理, 也好理解. 另外, 用TIM7作时间判断, 有80ms没收到, 这一组就结束,
* @file LoRa.c AUX MD0
* @author L 通信 0 0
* @version 配置 0 1
* @date 2019-7-13 升级 1 1
* @brief 初始化 LoRa
**************************************************************************************************/
#include "lora.h"
#include "led.h"
#include "delay.h"
char T7_count=0;
static char RxOldChar=0; // 上一个字符
static u16 RxState=0; // 接收状态 [15]:0_没有接收到数据; 1_接收到了一批数据; [14:0]:接收到的数据长度
static u8 RxBuf[100]="0"; // 接收缓冲, 最大USART3_MAX_RECV_LEN个字节.
/************************************************
1 * @Fun LORA_RX_OK
* @brief 已完成一组字符串的接收, 开始处理
* @arg
*/
void LORA_RX_OK() // 注意:这个函数是我自己工作中的特定功能, 你们可以改成自己的功能
{
TIM7->CR1 &=~ (1<<0); // 停止
TIM7->CNT =0;
T7_count=0;
RxOldChar=0;
RxState =0;
vLed_BlueOff ();
if((RxBuf[2]=='-') && (RxBuf[3]=='-'))
{
u8 c=RxBuf[0];
u8 i=RxBuf[1];
if(RxBuf[0]=='I') // 数据:调试_U32 格式:I1--453
ulDebug[i]=RxBuf[4];
if(RxBuf[0]=='F') // 数据:调试_float 格式:F1--3.4
fDebug[i]= RxBuf[4];
if(c=='B') // 数据:电池组电压 格式:B1--35.4
fBattery[i]=RxBuf[4];
}
else
printf("%s",RxBuf);
for(char i=0;i<100;i++) // 接收缓冲清0
RxBuf[i] =0;
}
/************************************************
1 * @Fun TIM7_Init
* @brief 计时器初始化 (时钟为APB1的2倍,而APB1为45M )
* @arg
* psc 分频系数 控制脉冲时间
* arr 自动重载值 控制周期
*/
void TIM7_Init(u16 psc, u16 arr)
{
RCC->APB1ENR|=1<<5; // TIM7时钟使能
TIM7->ARR=arr; // 设定计数器自动重装值
TIM7->PSC=psc; // 预分频器
TIM7->CNT=0; // 计数器清零
TIM7->DIER|=1<<0; // 允许更新中断
//TIM7->CR1|=0x01; // 使能定时器7
NVIC_Config(TIM7_IRQn,2,2); // 抢占0,子优先级1,组2
}
/************************************************
1 * @Fun TIM7_IRQHandler
* @brief 定时器7 中断 (用于处理LoRa接收完成_超时)
*
*/
void TIM7_IRQHandler(void)
{
TIM7->SR&=~(1<<0); // 清除标志
T7_count++;
if(T7_count ==8) // 80 ms
LORA_RX_OK();
}
/************************************************
1 * @Fun LoRa_Init
* @brief LoRa 初始化
* @arg
*
* @return
*/
char cLora_Init()
{
//u8 retry=0;
u8 temp=1;
float T;
u16 M,F;
vSys_GPIOSet(LORA_MD0_GPIOx , LORA_MD0_PINx , 1, 1, 3, 2, 0); // MD0 下拉输出
vSys_GPIOSet(LORA_AUX_GPIOx , LORA_AUX_PINx , 0, 0, 0, 2, 0); // AUX 下拉输入
vSys_GPIOSet (LORA_TX_GPIOx , LORA_TX_PINx , 2, 0, 2, 1 ,LORA_USART_AFx ); // TX
vSys_GPIOSet (LORA_RX_GPIOx , LORA_RX_PINx , 2, 0, 2, 1, LORA_USART_AFx ); // RX
Lora_AUX (0);
Lora_MD0 (0);
while((LORA_AUX_GPIOx ->IDR) & LORA_AUX_PINx)//确保LORA模块在空闲状态下(LORA_AUX=0)
{
printf("模块正忙,请稍等!!\n");
vDelay_ms(500);
}
T=(float)(LORA_USART_CLK *1000000)/(LORA_USART_BRR *16);//得到USARTDIV,OVER8设置为0
M=T; //得到整数部分
F=(T-M)*16; //得到小数部分,OVER8设置为0
M<<=4;
M=M+F;
LORA_USART_CLOCK_CMD ; // 使能 USART时钟
LORA_USARTx ->BRR = M; // 设置波特率因子
// 默认 过采样_16位、字长_8位、停止位_1位、校验_禁止
LORA_USARTx ->CR1 = 1<<2; // 接收
LORA_USARTx ->CR1 |= 1<<3; // 发送
LORA_USARTx ->CR1 |= 1<<5; // 使能接收缓冲区非空中断
LORA_USARTx->CR1 |= 1<<10; // 校验
LORA_USARTx->CR1 |= 1<<12; // 字长
LORA_USARTx ->CR1 |= 0<<15; // 过采样 0=16
LORA_USARTx ->CR1 |= 1<<13; // 使能
NVIC_Config(LORA_USART_IRQN,2,2); // 抢占3,子优先级2,组2
TIM7_Init (9000-1,100-1); // 10ms
p(" LoRa 配置完成... 透传信息已发送!\n");
return temp;
}
/************************************************
* @Fun LoRa_Send
* @brief 发送 字符串
* @arg char c 需要发送的字符串
* @note
* @date 2019.4.2
*/
void vLora_Send(char *c)
{
vDelay_ms(150);
while(*c!=0)
{
while((LORA_USARTx ->SR & 0x40)==0);
LORA_USARTx ->DR = *c;
c++;
}
}
/************************************************
* @Fun LORA_USART_IRQHANDLER
* @brief 接收缓冲非空 中断
*
* @note 原来在原子哥的接收中断上作修改,
* 后来越改越乱, 发现换行处理得不好,
* 而且LORA的空中速率和USART速率协调不好
* 推倒重来,自己写一个, 换个思路收发
* @date 2019.7.16
*/
void LORA_USART_IRQHANDLER(void)
{
u8 nowTem;
vLed_BlueOn ();
if(LORA_USARTx ->SR&(1<<5)) // 接收到数据
{
TIM7->CNT =1; // 更新TIM7状态(喂小狗)
TIM7->CR1 |= 1<<0;
nowTem= LORA_USARTx ->DR;
if((RxOldChar==10)&&(nowTem==13)) // 收到 回车 ,检查是否 连续的 10+13,
LORA_RX_OK();
else
{
RxBuf[RxState]=nowTem;
RxState++;
RxOldChar=nowTem ;
}
}
}
/************************************************
* @Fun AUX
* @brief AUX高低电平设置
* @note
* @date 2019.7.13
*/
void Lora_AUX(u8 u)
{
if(u==0)
LORA_AUX_GPIOx->ODR &=~LORA_AUX_PINx ;
else
LORA_AUX_GPIOx ->ODR |= LORA_AUX_PINx ;
}
/************************************************
* @Fun MD0
* @brief MD0高低电平设置
* @note
* @date 2019.7.13
*/
void Lora_MD0(u8 u)
{
if(u==0)
LORA_MD0_GPIOx ->ODR &=~LORA_MD0_PINx;
else
LORA_MD0_GPIOx->ODR |= LORA_MD0_PINx;
}