项目背景:基于LORA的遥控器
项目器件清单:
- 正点原子LORA模块(资料多)
- 摇杆模块(电位器)
- 主控stm32
实现流程:摇杆数据的读取、通信协议、从设备解开数据包。
1、摇杆数据的读取
上图就是我选取的摇杆(独立按键不涉及),摇杆就相当于电位器,AD读取电压即可。
对于比较初级的使用AD,我们需要明确几个方面:
- 明确所用引脚 -----> 配置引脚
- ADC的转换周期 = 采样时间 + 转换时间
- 通过总线驱动外设,总线配置的时钟频率要小于ADC的最大频率(一般需要分频)
- 采样时间,SMP寄存器配置
- 转换时间取决于ADC的位数
- 如果用库函数开发,计算完需要的参数,配置就行了。其余的模式、通道等若用到也可以修改。
- 我们设置一个全局变量存放数据就好。
2、通信协议
正点原子给出了一个接受的通信协议。所有的接受数据以0x0d 0x0a结束。
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了 ,标记完15位后,等待被其他程序清零
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
下面画个树状图理解一下
协议里如果数据包正确,按照,(1)、(2)、(3)进行接受数据。
3、从设备解开数据包
我们如果不使用上文的协议(正文数据左右放置固定参数),也可以自己写个数据包。
- 因为串口是8位数据完成一次传输,且AD的数据为16位的,所以我们需要定义一个8位的数组,并且将16位的数据放进去。
date[i++] =(AD>>8)&0xff;//数据高位 date[i++] = AD&0xff;//数据低位
-
但是这样也不能保证数据的正确性,所以我们还要放入两个AD数据加和的值。
- 我们将数据传输过去后,还需要拆包,并将16进制数据转为10进制,方便验证。
x = (USART3_RX_BUF[0]/16)*(16*16*16)+(USART3_RX_BUF[0]%16)*16*16+(USART3_RX_BUF[1]/16)*16+USART3_RX_BUF[1]%16; y = (USART3_RX_BUF[2]/16)*(16*16*16)+(USART3_RX_BUF[2]%16)*16*16+(USART3_RX_BUF[3]/16)*16+USART3_RX_BUF[3]%16; xADDy = (USART3_RX_BUF[4]/16)*(16*16*16)+(USART3_RX_BUF[4]%16)*16*16+(USART3_RX_BUF[5]/16)*16+USART3_RX_BUF[5]%16;
到这里也就完成了。