上次購買XL2400是在10月份, 那時候還是XL2400, 但是最近這個型號已經被XL2400P代替了, 再買收到的就是XL2400P. 這兩個型號的差異不小, 在遷移到 XL2400P 的過程中遇到了一些坑, 因此把這些坑記錄一下, 避免後面使用的人浪費時間. ...
目錄
- 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU簡介
- 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode開發環境
- 普冉PY32系列(三) PY32F002A資源實測 - 這個型號不簡單
- 普冉PY32系列(四) PY32F002A/003/030的時鐘設置
- 普冉PY32系列(五) 使用JLink RTT代替串口輸出日誌
- 普冉PY32系列(六) 通過I2C介面驅動PCF8574擴展的1602LCD
- 普冉PY32系列(七) SOP8,SOP10,SOP16封裝的PY32F002A/PY32F003管腳復用
- 普冉PY32系列(八) GPIO模擬和硬體SPI方式驅動無線收發晶元XN297LBW
- 普冉PY32系列(九) GPIO模擬和硬體SPI方式驅動無線收發晶元XL2400
- 普冉PY32系列(十) 基於PY32F002A的6+1通道遙控小車I - 綜述篇
- 普冉PY32系列(十一) 基於PY32F002A的6+1通道遙控小車II - 控制篇
- 普冉PY32系列(十二) 基於PY32F002A的6+1通道遙控小車III - 驅動篇
- 普冉PY32系列(十三) SPI驅動WS2812全彩LED
- 普冉PY32系列(十四) 從XL2400遷移到XL2400P
這個話題貌似和PY32沒什麼關係, 只是我用到XL2400以及現在改成XL2400P都是在PY32F002A的板子上, 代碼是基於PY32F0xx的, 所以也就放到這個系列里. 對應的XL2400庫文件是通用的, 要遷移到其它的MCU也非常容易.
上次購買XL2400是在10月份, 那時候還是XL2400, 但是最近這個型號已經被XL2400P代替了, 再買收到的就是XL2400P. XL2400去年7月的價格是0.9, 今年10月的價格是0.7, 現在換成XL2400P之後, 價格又降到了0.65, 幾乎算是現在市面上價格最低的一款2.4GHz無線收發晶元了.
這兩個型號的差異不小, 在遷移到 XL2400P 的過程中遇到了一些坑, 因此把這些坑記錄一下, 避免後面使用的人浪費時間.
XL2400P
- https://www.xinlinggo.com/
芯嶺的網站, 資料下載頁上的 XL2400P規格書V1.0a.pdf, 以及XL240X應用說明v2.1a.pdf - https://pan.baidu.com/s/1GJoXbWn9oOyeqGn6Igg5DA?pwd=6688
百度盤的鏈接在資料下載頁上有, 鏈接如果變了可以去資料下載頁上找, 現在還是能訪問的. 百度盤裡的資料比較豐富.
這裡有一個坑: XL2400P規格書V1.0a.pdf 上面的寄存器表格是錯的, 這個表格是XL2400的寄存器設置, 不是XL2400P的.
那麼哪裡能找到XL2400P的寄存器說明呢? 在百度盤裡找這個文件 XL2409 package v1.03.zip, 解開後, 在 XLtool 目錄下有 XL2400P_Register Map_V1.1.xlsx, 這個才是 XL2400P 正確的寄存器說明.
XL2400P 對比 XL2400
首先說相同點
- 封裝相同, PIN腳佈局相同, PIN腳定義相同, 電路相同, 因此硬體上是相容的, 電路不用改
- 頻點, 調製方式和地址機制都相同, TX頻點都比RX頻點要高1MHz. 因此這兩個型號之間可以互相通信, 如果你用的是 250Kbps 和 1Mbps, 可以無縫過渡
再說有差異的地方
- 寄存器不一樣, 一些常用的寄存器改動還挺大
- XL2400P 上電後並不進入工作狀態
- XL2400P 取消了125Kbps速率, 可用頻點數量比XL2400多
驅動代碼上的差異
PY32F0模板庫里的XL2400驅動已經更新, 通過巨集判斷實現對兩個型號的相容, 使用時, 修改頭文件中的#define USE_XL2400P
, 改為USE_XL2400P
或USE_XL2400
就能實現對兩個型號的切換.
- GPIO模擬SPI驅動: https://github.com/IOsetting/py32f0-template/blob/main/Examples/PY32F0xx/LL/GPIO/XL2400_Wireless/xl2400.c
- 硬體SPI驅動: https://github.com/IOsetting/py32f0-template/blob/main/Examples/PY32F0xx/LL/SPI/XL2400_Wireless/xl2400.c
在上面的源碼中能直接看到差異, 具體有以下幾處
CE高低切換
XL2400
// 拉低
XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_CFG_TOP, cbuf, 2);
*(cbuf + 1) &= 0xBF;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, cbuf, 2);
// 拉高
XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_CFG_TOP, cbuf, 2);
*(cbuf + 1) |= 0x40;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, cbuf, 2);
XL2400P, 在 XL2400P 中控制CE的是寄存器的第一個位元組的第一位, 最多只需要讀寫一個位元組
// 拉低
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0xEE);
// 拉高
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0xEF);
初始化
XL2400
// Analog config
XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_ANALOG_CFG0, xbuf, 13);
*(xbuf + 4) &= ~0x04;
*(xbuf + 12) |= 0x40;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG0, xbuf, 13);
// Switch to software CE control, wake up RF
*(xbuf + 0) = 0x7E;
*(xbuf + 1) = 0x82;
*(xbuf + 2) = 0x0B;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, xbuf, 3);
XL2400_CE_Low();
XL2400_ClearStatus();
XL2400P
// Reset EN_PM, POWER_UP
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0x02);
LL_mDelay(2);
// Set EN_PM, POWER_UP
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0x3E);
LL_mDelay(2);
XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_ANALOG_CFG3, xbuf, 6);
xbuf[5] = (xbuf[5] | 0x6d);
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG3, xbuf, 6);
需要註意的是, 在XL2400P上如果未初始化, 地址寄存器只讀, 要初始化(POWER_UP)後才可以寫入地址, 因此庫文件中的 XL2400_SPI_Test()
方法要加上初始化的步驟
設置頻點
XL2400
if (channel > 80) channel = 80;
// AFC reset
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG0, 0x06);
// AFC on
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG0, 0x0E);
// Frequency(MHz) 2400:0x960 -> 2480:0x9B0
*(cbuf + 0) = 0x60 + channel;
*(cbuf + 1) = 0x09;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_RF_CH, cbuf, 2);
// AFC Locked
*(cbuf + 1) |= 0x20;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_RF_CH, cbuf, 2);
XL2400P
if (channel > 80) channel = 80;
*cbuf = XL2400_ReadReg(XL2400_CMD_R_REGISTER | XL2400_REG_EN_AA);
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_EN_AA, *cbuf & ~0x40);
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_RF_CH, 0x60 + channel);
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_EN_AA, *cbuf | 0x40);
設置功率
XL2400
XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RF_CH, xbuf, 3);
*(xbuf + 2) = power;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_RF_CH, xbuf, 3);
XL2400P
XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RF_SETUP, xbuf, 2);
*(xbuf + 1) = power;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_RF_SETUP, xbuf, 2);
休眠
XL2400
XL2400_CE_Low();
XL2400_ClearStatus();
*(xbuf + 0) = 0x7C;
*(xbuf + 1) = 0x82;
*(xbuf + 2) = 0x03;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, xbuf, 3);
XL2400P
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0x00);
切換收發模式
XL2400
// 切換髮送模式
XL2400_CE_Low();
XL2400_ClearStatus();
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0x7E);
XL2400_RxCalibrate();
LL_mDelay(1);
// 切換接收模式
XL2400_CE_Low();
XL2400_ClearStatus();
XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0x7F);
XL2400_CE_High();
LL_mDelay(1);
XL2400P
// 切換髮送模式
cbuf[0] = 0xee;
cbuf[1] = 0x80;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, cbuf, 2);
XL2400_ClearStatus();
LL_mDelay(1);
// 切換接收模式
cbuf[0] = 0xee;
cbuf[1] = 0xc0;
XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, cbuf, 2);
XL2400_ClearStatus();
XL2400_CE_High();
LL_mDelay(1);
其它問題
關於通信速率, XL2400P實際上 125Kbps 也能通信, 但是手冊上並沒有將這個速率列入, 從實際測試上看, 125Kbps 和 2Mbps 的通信效果都不太好, 在開啟ACK時, 很容易出現錯誤的重發, 因此在實際使用中, 建議只使用 250Kbps 和 1Mbps, 或者不要開 ACK