stm32L476基于platformIO控制LORA芯片SX1280 SPI通信

· 更新于

LORApioSPIstm32

硬件:

下载3D打印文件

软件:

  • vscode
  • platformIO+arduino框架
  • 库:jgromes/RadioLib@^6.3.0

引脚接口:

  • NSS pin:   PA4
  • DIO1 pin:  PA9
  • NRST pin:  PB0
  • BUSY pin:  PA1
  • SPI MOSI:PA7
  • SPI MISO:PA6
  • SPI SCK:PA5
  • TX EN:PB8
  • RX EN:PB9
  • led1:PC0
  • led2:PC1

主测试代码

使用LORA_MASTER切换发射端还是接收端

`#include <Arduino.h> #include <SPI.h> #include <EEPROM.h> #include <RadioLib.h>  //1=TX,0=RX #define LORA_MASTER 1  #if LORA_MASTER==1 /************block send***************/  SX1280 radio = new Module(PA4, PA9, PB0, PA1); void setup() {   Serial.begin(115200);    Serial.print(F("[SX1280] Initializing ... "));   int state = radio.begin(2412, 1625, 10, 5);   if (state == RADIOLIB_ERR_NONE) {     Serial.println(F("success!"));   } else {     Serial.print(F("failed, code "));     Serial.println(state);     while (true);   }   radio.setRfSwitchPins(PB9, PB8); } int count = 0;  void loop() {   Serial.print(F("[SX1280] Transmitting packet ... "));   String str = "Hello World! #" + String(count++);   int state = radio.transmit(str);    // you can also transmit byte array up to 256 bytes long   /*     byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};     int state = radio.transmit(byteArr, 8);   */    if (state == RADIOLIB_ERR_NONE) {     Serial.println(F("success!"));   } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {     Serial.println(F("too long!"));   } else {     Serial.print(F("failed, code "));     Serial.println(state);   }   delay(1000); } /************************block send***************************/ #else /************************block REV***************************/ SX1280 radio = new Module(PA4, PA9, PB0, PA1); void setup() {   Serial.begin(115200);    Serial.print(F("[SX1280] Initializing ... "));   int state = radio.begin(2412, 1625, 10, 5);   if (state == RADIOLIB_ERR_NONE) {     Serial.println(F("success!"));   } else {     Serial.print(F("failed, code "));     Serial.println(state);     while (true);   }   radio.setRfSwitchPins(PB9, PB8); }  void loop() {   Serial.print(F("[SX1280] Waiting RXRXRXRXRXRXRX ... "));    // you can receive data as an Arduino String   String str;   int state = radio.receive(str);    // you can also receive data as byte array   /*     byte byteArr[8];     int state = radio.receive(byteArr, 8);   */    if (state == RADIOLIB_ERR_NONE) {     // packet was successfully received     Serial.println(F("success!"));      // print the data of the packet     Serial.print(F("[SX1280] Data:\t\t"));     Serial.println(str);      // print the RSSI (Received Signal Strength Indicator)     // of the last received packet     Serial.print(F("[SX1280] RSSI:\t\t"));     Serial.print(radio.getRSSI());     Serial.println(F(" dBm"));      // print the SNR (Signal-to-Noise Ratio)     // of the last received packet     Serial.print(F("[SX1280] SNR:\t\t"));     Serial.print(radio.getSNR());     Serial.println(F(" dB"));      // print the Frequency Error     // of the last received packet     Serial.print(F("[SX1280] Frequency Error:\t"));     Serial.print(radio.getFrequencyError());     Serial.println(F(" Hz"));    } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {     // timeout occurred while waiting for a packet     Serial.println(F("timeout!"));    } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {     // packet was received, but is malformed     Serial.println(F("CRC error!"));    } else {     // some other error occurred     Serial.print(F("failed, code "));     Serial.println(state);    } } /************************block REV***************************/ #endif`

遇到的坑:

1,引脚设置

`// NSS pin:   PA4 // DIO1 pin:  PA9 // NRST pin:  PB0 // BUSY pin:  PA1 SX1280 radio = new Module(PA4, PA9, PB0, PA1);`

2,stm32duino的默认设置

spi默认就是PA5 PA6 PA7,不需要设置

3,如果自定义SPI引脚

`//          MOSI  MISO  SCLK   SSEL SPIClass myspi2(PA_7, PA_6, PA_5); SPISettings spiSettings(2000000, MSBFIRST, SPI_MODE0); SX1280 radio = new Module(PA4, PA9, PB0, PA1, myspi2, spiSettings);`

4,lora设置

`//param freq Carrier frequency in MHz. Defaults to 2400.0 MHz. //param bw LoRa bandwidth in kHz. Defaults to 812.5 kHz. //param sf LoRa spreading factor. Defaults to 9. //param cr LoRa coding rate denominator. Defaults to 7 (coding rate 4/7). //param syncWord 2-byte LoRa sync word. Defaults to 0x12 //param pwr Output power in dBm. Defaults to 10 dBm. //param preambleLength LoRa preamble length in symbols. Defaults to 12 symbols.        radio.begin(2412, 1625, 10, 5);//我只设置前4个`

5,关于频段和通道

2.4G允许的范围是2400Mhz~2483.5Mhz,lora的最小间隔是400KHZ

所以理论上,支持208个设备同时使用。

实际lora间隔1M比较好,稳定在80个设备

但是wifi 蓝牙都在这个区间

概念:

频率频段(中心频段):2400Mhz~2483.5Mhz

带宽只单信道范围:lora2.4G支持4个(203,406,812,1625KHZ)

扩频因子sf

编码了cr

计算:

例子:

如果设置设备1 freq=2400mhz,bw=1625khz,

min=freq-bw/2,max=freq+bw/2

则设备1的频率范围是2399.1875MHz~2400.8125MHz

则下一个设备的freq(next)=freq(last)+bw

下一个设备中心频率=2400MHz+1625kHz=2401.625MHz

计算2:

若希望频谱间隔仅为带宽的一倍,则

总占用频谱宽度为2×1625 kHz=3250 kHz

83.5Mhz/3250khz=25个设备1625

50个设备812,100个设备406,200个设备203

实际上还有扩频因子sf和编码了cr

相关链接

arduino官方SPI文档:https://www.arduino.cc/reference/en/language/functions/communication/spi/

stm32duino关于SPI的说明:https://github.com/stm32duino/Arduino_Core_STM32/wiki/API#spi

RadioLIb文档:https://github.com/jgromes/RadioLib