項目背景:基於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;
到這裏也就完成了。