请选择 进入手机版 | 继续访问电脑版
查看: 175|回复: 0

[应用笔记] AN-1104 LoRa模组调试小白手册

[复制链接]

43

主题

74

帖子

494

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
494
发表于 2022-5-16 10:18:49 | 显示全部楼层 |阅读模式
  背景

  LoRa模组使用中过程中经常遇到初始化失败、SPI读写异常、模块发送不了数据包、模块接收不到数据包等异常现象,最后查明多是因为软件没有正确控制MCU操作模组造成的。

  在模组出现异常时,先需要确定出是不模组本身有问题,异常的产生是软件问题还是硬件问题。使用本文这种小白操作方式主要用确认模组在用户的板子上能否正常工作。

  通常模组应用中会涉及用户MCU的定时器,硬件SPI,中断,和IO操作等功能。而模组出现异常也多是因为这些功能的加入产生的,所以本文的核心思想就是:只使用用户MCU上的最基础的普通IO功能来完成模组的操作和使用,用来先确认模组是否可以正常使用。所以操作时只使用普通IO的输出和输出功能,硬件SPI功能改为软件模拟SPI操作,中断功能改为扫描IO电平操作,定时器功能改为使用软件延时来代替。

  这种排查模块异常的方式,适用于所有的SPI接口的无线模组。

  本文选用一款SX1268的型号为LSD4RF_2R717N40模组和瑞萨的一款型号为R7FA2L1AB2DFL低功耗MCU为例,进行说明演示操作,实际操作者请根据自己实际使用的MCU和RF模组参考如下流程操作即可。

  过程

  一、MCU使用到的资源
  只使用MCU的最基础的普通的IO输出输入功能,其他的的定时器,DIO中断,硬件SPI等功能全都不用,把所有中断都关闭掉。
  保证模组的所有操作都在while(1)中运行。

  二、接线方式
  本次MCU和模组的硬件连接本次采用如下接线方式:(使用者实际操作时根据自己方便随便指定即可)
  MCU的P104接LED1的正极,使用输出模式
  MCU的P103接LED2的正极,使用输出模式
  MCU的P112接模组的NRST,使用输出模式
  MCU的P208接模组的SWCLT1,使用输出模式
  MCU的P207接模组的SWCTL2,使用输出模式
  MCU的P101接模组的MOSI,使用输出模式
  MCU的P102接模组的SCK,使用输出模式
  MCU的P002接模组的NSS,使用输出模式
  MCU的P100接模组的MISO,使用输入模式
  MCU的P302接模组的BUSY,使用输入模式
  MCU的P301接模组的DIO1,使用输入模式
  MCU的P015接一个按键KEY1,使用输入模式
  便于查看生成接线原理图如下:
  三、IO功能调试
  注意:先不要把模块接到板子上,先只调试IO的输入输出是否都是好使的了/
  先用一个按键和2个LED先验证IO的输入输出功能是否调通。
  然后先按照(二、接线方式)中的IO的状态配置好所有的IO端口,此处P100接模组的MISO不用配置内部上拉也可以。

  const ioport_pin_cfg_t g_bsp_pin_cfg_data[] =
  {

  { .pin = BSP_IO_PORT_00_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_00_PIN_15, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) },
  { .pin = BSP_IO_PORT_01_PIN_00, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT| (uint32_t) IOPORT_CFG_PULLUP_ENABLE) },
  { .pin = BSP_IO_PORT_01_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_01_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT| (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_01_PIN_03, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_01_PIN_04, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT| (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_01_PIN_12, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_02_PIN_07, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT| (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_02_PIN_08, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT| (uint32_t) IOPORT_CFG_PORT_OUTPUT_LOW) },
  { .pin = BSP_IO_PORT_03_PIN_01, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) },
  { .pin = BSP_IO_PORT_03_PIN_02, .pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT) },

  };

  然后让这些配置生效。
  接下来先试下两个LED和按键。
  主函数里先运行下如下代码,如果P104和P103有对应电平变化,LED灯对应的有亮有灭即可判断输出IO为正常的。

  ///////////////////////P104=LED1
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  ///////////////////////P103=LED2
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  主函数里先运行下如下代码,如果按键按下和抬起能读取到正确的IO状态,即可判断输入的IO的为正常的。

  //P015=KEY1 IN
  R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_15, &p_port_value_port15);
  if(p_port_value_port15)//未按下
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03,BSP_IO_LEVEL_LOW );
  else
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH);

  然后,主函数里跑如下代码:

  ///////////////////////P112=NRST OUT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_12, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_12, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  ///////////////////////P208=SWCLT1 OUT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_08, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_08, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  ///////////////////////P207=SWCTL2 OUT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  ///////////////////////P101=MOSI OUT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_01, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_01, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  ///////////////////////P102=SCK OUT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  ///////////////////////P002=NSS OUT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, BSP_IO_LEVEL_HIGH);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, BSP_IO_LEVEL_LOW);
  R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT

  如下

  P112=NRST OUT
  P208=SWCLT1 OUT
  P207=SWCTL2 OUT
  P101=MOSI OUT
  P102=SCK OUT
  P002=NSS OUT

  上都能用万用表测到对应的电平变化,即可判断MCU和即将连接模块的输出IO都正常。

  主函数里运行如下代码:

  //P301=DIO1 IN
  R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_03_PIN_01, &p_port_value_port15);
  if(p_port_value_port15)//未按下
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03,BSP_IO_LEVEL_LOW );
  else
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH);

  //P302=BUSY IN
  R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_03_PIN_02, &p_port_value_port15);
  if(p_port_value_port15)//未按下
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03,BSP_IO_LEVEL_LOW );
  else
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH);

  //P100=MISO IN
  R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_00, &p_port_value_port15);
  if(p_port_value_port15)//未按下
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04,BSP_IO_LEVEL_LOW );
  else
  R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_HIGH);

  如下
  P100=MISO IN
  P302=BUSY IN
  P301=DIO1 IN

  串入一个电阻后飞线接到VCC和GND上都能在仿真状态下读取到对应的电平,即可判断MCU和即将连接的模块的输入IO都正常。

  四、软件移植
  这时再按照(二、接线方式)中说明把MCU和模组连接好,模组的天线口一定要接上天线。把我司的如下文件加入软件工程中。
  把我司的代码中的最底层的PSI读写函数改为软件模拟的SPI方式如下:有箭头的地方都是需要用到IO的地方,延时的地方实际可以根据情况加调整,实际中一般控制SPI速率在4M以下,常用2M左右,速度太快容易出现读写错误。

  然后把所有牵扯到NSS,RST,SWCTL1和SWCTL2的地方都修改一下,改为适合本案例中MCU的操作函数,这些地方是即使使用硬件SPI也要改动的地方。举例如下箭头的地方。




  修改软件中的模块版本,如下图:版本改成对应模组的型号。然后

  然后在主函数里加入模块初始化函数,先不加入发送和接收等函数,先只把模块初始化函数加进来,然后编译一下,哪里有错误就对应修改一下。

  然后运行模组初始化函数,先看模块的RST引脚上是否有对应电平变化(判断模块复位有没有执行)。再主要查看下图中的SPI验证的地方,是否随便读写都是正常的。常用的读写验证值无非就是0xFF 0x00 0x55 0xAA 和随便取一个值。

  这里还要用一起看NSS在操作SPI时有没有正确的电平变化。

  如果这里SPI读写不正常,请从本文开头开始查哪里有操作疏忽的地方。如果这里SPI已经可以随便读写,调试就已经基本完成90%了,可以继续下边的操作了。

  然后做两块相同的板子。

  A板子用来调试发射流程,代码的while(1)按照如下方式操作。发送端调试时加入个延时,比如每隔4秒发一包。发送完成判断采用扫描DIO1的电平的方式判断。

  B板子用来调试接收流程,代码的while(1)按照如下方式操作。接收到包的判断采用扫描DIO1的方式判断。

  到这里,模块在板子上的调试就完成了,这里应该可以看到模块发送和接收都能正常实现了,如果到这里接收不到数据包,请从本文开头仔细检查哪里有操作疏忽的地方。

  结论

  只要模块安装到了板子上,就一定要接天线,不要不接天线就开始调试模块,因为不接天线调试模块存在把模块搞坏的风险。

  如果出现了BUSY一直为1卡住的现象,不要惊慌,请参考另外一篇《R系列LoRa模组Busy卡住的处理》。

  调试模组时请使用和实际频点适配好的天线。

  如上调试方法,不用MCU和定时器,不用MCU的中断,也不用硬件SPI,只用最基础的IO的输入输出,目的是验证模组在使用者板子上是否正常。如果使用者如此调试模组都正常,改成了硬件SPI模组就异常了,请使用者检查硬件SPI问题。

  如果加入DIO1的中断功能,但是接收发送数据不进中断请使用者检查MCU的中断问题。如果假如定时器模组出现了异常,请检使用模组时的逻辑问题。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表