基于CC2530的Zstack协议栈的SX1278调试记录

2023-11-05


只是写个自己调试SX1278模块的记录!

串口调试代码

在串口处已经编写了,解析串口命令的代码,直接输入相关命令可以直接操作寄存器。
在协议栈串口MT_UART.c文件中RX处代码如下:

//这里面接收串口数据读取,串口传过来数据解析成对应的处理函数!
//最终实现使用串口命令:
//1.F1获取帮助信息
//2.A1设置寄存器,读取寄存器
//3.A2发送数据 (hex 和 字符串)
//4.A3取得数据 清空数据

void serial_process( uint8 port, uint8 event )
{
    (void)port;

    if ((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT)))
    {
        if (SerialApp_TxLen < 80)
        {
            SerialApp_TxLen = HalUARTRead(port, Serial_Lora_Control_Buff, 80);
            if (SerialApp_TxLen)
            {
				if(Serial_Lora_Control_Buff[0] == 0xF1)LORA_Help();
                if(Serial_Lora_Control_Buff[0] == 0xA1)
                {
                    if(SerialApp_TxLen >= 2)存在数据
                    {
                        LORA_A1(Serial_Lora_Control_Buff,SerialApp_TxLen);
                    } 
                    else
                    {
                        LORA_Help_A1();
                    }
                }
                if(Serial_Lora_Control_Buff[0] == 0xA2)//A2
                {
                     if(SerialApp_TxLen >= 2)//存在数据
                     {
                        LORA_A2(Serial_Lora_Control_Buff,SerialApp_TxLen,0);
                     }
                     else
                     {
                        LORA_Help_A2();
                     }
                }
                if (Serial_Lora_Control_Buff[0] == 65 && Serial_Lora_Control_Buff[1] == 50)//字符A2
                {
                  if(Serial_Lora_Control_Buff[2] == '"')
                  {
                     LORA_A2(Serial_Lora_Control_Buff,SerialApp_TxLen,1);
                  }
                  else 
                  {
                     LORA_Help_A2_str();
                  }
                }
                if(Serial_Lora_Control_Buff[0] == 0xA3)//A3
                {
                  if(SerialApp_TxLen >= 2)//存在数据
                  {
                    LORA_A3(Serial_Lora_Control_Buff,SerialApp_TxLen);
                  }
                  else
                  {
                    LORA_Help_A3();
                  }
                }

处理函数如下:

/*
配合串口命令,反馈、帮助、配置
*/
void LORA_Help(void)
{
    HalUARTWrite(0, "\nSend_Hex_Format", strlen("\nSend_Hex_Format"));
    HalUARTWrite(0, "\nA1-Set-Reg", strlen("\nA1-Set-Reg"));
    HalUARTWrite(0, "\nA2", strlen("\nA2"));
    HalUARTWrite(0, "->", strlen("->"));
    HalUARTWrite(0, "\nA3", strlen("\nA3"));
    HalUARTWrite(0, "<-", strlen("<-"));
}
void LORA_Help_A1(void)
{
    HalUARTWrite(0, "\nSend_Hex_Format", strlen("\nSend_Hex_Format"));
    HalUARTWrite(0, "\nA1空格ADR空格DATA", strlen("\nA1空格ADR空格DATA"));
    HalUARTWrite(0, "\nA1空格ADR", strlen("\nA1空格ADR"));
}
void LORA_Help_A2(void)
{
    HalUARTWrite(0, "\nSend_Hex_Format", strlen("\nSend_Hex_Format"));
    HalUARTWrite(0, "\nA2空格DATA", strlen("\nA2空格DATA"));
    HalUARTWrite(0, "\nA2“字符串”", strlen("\nA2“字符串”"));
}
void LORA_Help_A2_str(void)
{
    HalUARTWrite(0, "\nSend_Char_Format", strlen("\nSend_Char_Format"));
    HalUARTWrite(0, "\nA2“字符串”", strlen("\nA2“字符串”"));
}
void LORA_Help_A3(void)
{
    HalUARTWrite(0, "\nSend_Hex_Format", strlen("\nSend_Hex_Format"));
    HalUARTWrite(0, "\nA3空格01/00", strlen("\nA3空格空格01/00"));
}
/*
配合串口命令 A1 配置
格式:A1 adress data
*/
void LORA_A1(uint8 *lora_Order_buff,uint16 SerialApp_TxLen)
{
  if(SerialApp_TxLen == 3 )
  {
    SX1278WriteBuffer(lora_Order_buff[1],lora_Order_buff[2]);
    //SX1278ReadBuffer(lora_Order_buff[1]);
  }
  else
  {
    SX1278ReadBuffer(lora_Order_buff[1]);
  }  
}

/*
配合串口命令 A2 send
格式:A2"字符串" OR A2空格DATA
*/
void LORA_A2(uint8 *lora_Order_buff,uint16 SerialApp_TxLen,bool state)
{
  if(state == 1)//A2"字符串" 
  {
    if (lora_Order_buff[2] == '"' && lora_Order_buff[SerialApp_TxLen-1] == '"')
    {
        HalUARTWrite(0, "\nA2“字符串OK”\n", strlen("\nA2“字符串OK”\n"));
        HalUARTWrite(0, ":", strlen(":"));
        HalUARTWrite(0, lora_Order_buff+3, SerialApp_TxLen-4);//
        FUN_RF_SENDPACKET(lora_Order_buff+2,SerialApp_TxLen-2);//2个双引号和数据留下
        HalUARTWrite(0, "\nSend_Done!\n", strlen("\nSend_Done!\n"));
    }
  }
  if(state == 0)//A2空格DATA
  {
      uint8 i;
      HalUARTWrite(0, "\nA2“HexOK”\n", strlen("\nA2“HexOK”\n"));
      for(i = 1;i<SerialApp_TxLen;i++)
      {
          HexToChar(lora_Order_buff[i],HEX_String_Value);//转为字符
          HalUARTWrite(0, HEX_String_Value,2);
          HalUARTWrite(0, " ", 1);
      }
      FUN_RF_SENDPACKET(lora_Order_buff+1,SerialApp_TxLen-1);//hex发送
      HalUARTWrite(0, "\nSend_Done!\n", strlen("\nSend_Done!\n"));
      FIFO_Flag_String = 0;
  }
}

void LORA_A3(uint8 *lora_Order_buff,uint16 SerialApp_TxLen)
{
  if(lora_Order_buff[1]==0x01)
  {
    if(DIO0 == 1 && FIFO_Flag == 0)//lora 中断触发 未读取数据
    {  
          spi_receiver();
          FIFO_Flag = 1;
    }
    else if(FIFO_Flag == 1 && FIFO_Flag_String == 0)//第二次读
    {
        HalUARTWrite(0, recv_dest_hex, RF_REC_RLEN_i*3);//-16-》字符数据地址 数据间有空格
    }
    else if(FIFO_Flag == 1 && FIFO_Flag_String == 1)
    {
        HalUARTWrite(0, recv_dest+1, RF_REC_RLEN_i-2);//--数据地址
    }
  }
  if(lora_Order_buff[1]==0x00)
  {
      SX1278LoRaSetOpMode(Sleep_mode);//清空13rx获取的字节数
      SX1278LoRaSetOpMode(Stdby_mode);//FIFO指向地址不变、地址内容不变、
      RF_RECEIVE();
      SX1278ReadBuffer(0x0E);
      HalUARTWrite(0, "\nClear_FIFO_Done!\n", strlen("\nClear_FIFO_Done!\n"));
      HalUARTWrite(0, "\nNothing!\n", strlen("\nNothing!\n"));
      FIFO_Flag = 0;

  }  
}

串口获取调试信息

//写入或读取寄存器时,发送信息
void SEND_UART_Information(unsigned char *dst_V,unsigned char *dst_A,u8 addr,u8 value,bool state)
{
  if(state == 0)
  {
    HalUARTWrite(0, "\nR:", strlen("\nR:"));
    HexToChar(addr,dst_A);//读取地址:dst_A 数据为:dst_V
    HalUARTWrite(0, HEX_String_Addr,2);
    HalUARTWrite(0, "-:", strlen("-:"));
    HexToChar(value,dst_V);
    HalUARTWrite(0, HEX_String_Value,2);
  }
  if(state == 1)
  {
    HalUARTWrite(0, "\n-W:", strlen("\n-W:"));
    HexToChar(addr,dst_A);//写入地址:dst_A 数据为:dst_V
    HalUARTWrite(0, HEX_String_Addr,2);
    HalUARTWrite(0, "-:", strlen("-:"));
    HexToChar(value,dst_V);
    HalUARTWrite(0, HEX_String_Value,2);
  }
  //转为字符
  static bool HexToChar(u8 temp,unsigned char *dest)
{
    u8 hb,lb;
    char buf[2] = {0};
    hb=(temp&0xf0)>>4;  	//保留高位,右移去掉低位   

    if( hb<=9 )
      hb += 0x30;  				//相当于+'0'转为字符了
    else if( hb>=10 &&hb <=15 )  
      hb = hb -10 + 'A';	//转成字符A--F  
    else  
      return 0; 
    
    lb = temp&0x0f;

    if( lb<=9 )
      lb += 0x30;//decimal  48 
    else if( lb>=10 && lb<=15 )
      lb = lb - 10 + 'A';
    else
      return 0;
    
    buf[0] = hb;
    buf[1] = lb;
    memcpy(dest,buf,2);
    return 1;
}

//SX1278读写
@fn SX1278写入 
*/
void  SX1278WriteBuffer(u8 addr,u8 buffer) 
{
	SPI_Write(addr | 0x80);//MSB=1 WRITE
	SPI_Write(buffer);//写入数据	 
	NSS = 1; //不使能 NSS = 1;
    SEND_UART_Information(HEX_String_Value,HEX_String_Addr,addr,buffer,1);//调试用--写入-发送到串口
}

/*
@fn SX1278读取 
*/
unsigned char  SX1278ReadBuffer(unsigned char addr) //读取寄存器中的数据
{
	unsigned char Value;
	SPI_Write(addr & 0x7F);//WRITE写入一个字节数据  MSB=0-->read_data 
  	Value = SPI_Read();
	NSS = 1;
  	SEND_UART_Information(HEX_String_Value,HEX_String_Addr,addr,Value,0);//调试用--读取-发送到串口
	return Value;
}

SPI驱动IO口模拟,加深理解用

SPI通讯时序
具体可参考:https://blog.csdn.net/weixin_42509369/article/details/83096349
时钟极性CPOL=1则时钟初始为高电平,0则低电平
时钟相位CPHA=1则第二个时钟沿采集数据,0则第一个时钟沿
以上都是设置为1则:时钟第一个沿为下降沿,第二个为上升沿,此时采集数据

SPI 1

SX1278的通讯时序

SCK初始为低电平,第一个沿为上升,读取数据
若使用标准SPI驱动需要设置:CPOL=0,CPHA=0
在这里插入图片描述

SX1278 SPI通讯间隔要求

SX1278 SCK TIME
SX1278 SCK TIME2
则SPI驱动代码如下:

#define NSS  P0_4 //使能引脚
#define MISO P1_7 //MISO
#define SCLK P1_5 //SCLK
#define MOSI P1_6 //MOSI
#define DIO0 P1_3 //DIO0 RX接收done TX done中断标志
#include "lora.h"
/*******************************************************************************
MOSI, Master out slave in,主出从进。主控端发数据,从端接收,用于主控端写。
MISO, Master in slave out.主进从出。主控端接收数据,从端发送数据,用于主控端读。
时钟口==上升沿读取数据,下降沿写入数据
低高复位芯片
write:wnr[1] 6 5 4 3 2 1 0  自定义写数据(字节) read:wnr[0] 6 5 4 3 2 1 0 读取此地址数据(字节) MSB先传
Fsclk=MAX_10Mhz 100ns 最低允许间隔上50ns下50ns
*******************************************************************************/  

  
/*SPI-init*/
void SPI_INIT(void)
{
    P1DIR &= ~BV(7);//MISO配置为输入
    P1DIR &= ~BV(3);//P1_3配置为输入,采集DIO0-LORA数据接收中断标志
    P1INP &= ~BV(3);//打开P1.3上下拉模式
    P2INP |=  BV(6);//打开P1端口下拉
    P1DIR |= BV(5);//SCLK配置为输出
    P1DIR |= BV(6);//MOSI 配置为输出
    P0DIR |= BV(4);//NSS配置为输出
    NSS = 1;//不使能模块
    SCLK = 0;
}
/********************************

从SPI器件写入一个字节数据,NSS不在此停止使能,由调用程序段停止

********************************/
void SPI_Write(unsigned char data)
{
    unsigned char i;
    NSS = 0;//NSS=0 使能
    for(i = 0;i < 8;i++)
    {
        SCLK = 0;//SCLK=0
        if((data & 0x80)==0x80)MOSI = 1;
        else MOSI = 0;       
        _Delay_nus(100);
        SCLK = 1 ;
        data =(data<<1);
        _Delay_nus(100);
    }
    //NSS = 1; //不使能
}
/********************************

从SPI器件读出一个字节数据,由调用程序段使能NSS,结束后本函数自动停止

********************************/
unsigned char SPI_Read(void)
{
    unsigned char i,SPI_DATA;
    for(i = 0; i<8 ;i++)
    {
        SCLK = 0;
        _Delay_nus(100);
        SPI_DATA = (SPI_DATA<<1);
        SCLK = 1;
        _Delay_nus(100);
        if(MISO == 1)SPI_DATA |=0x01;
        else SPI_DATA &=~0x01;
    }
    SCLK = 0;
    NSS = 1;
    return SPI_DATA;
}

SX1278 寄存器设置,实例

/*
@fn 运行模式切换 
    寄存器地址0x01
*/
#define REG_LR_OPMODE   0x01
typedef enum 
{
   Sleep_mode	        = (u8)0x00, 
   Stdby_mode	        = (u8)0x01, 
   TX_mode 	        	= (u8)0x02,
   Transmitter_mode		= (u8)0x03,
   RF_mode 				= (u8)0x04,
   Receiver_mode		= (u8)0x05,
   receive_single		= (u8)0x06,
   CAD_mode				= (u8)0x07,
}RFMode_SET;

void  SX1278LoRaSetOpMode(RFMode_SET opMode)//运行模式选择 
{
	u8 opModePrev;
	opModePrev = SX1278ReadBuffer(REG_LR_OPMODE);//寄存器地址0X01
	opModePrev &= 0xf8;
	opModePrev |= (u8) opMode;
	SX1278WriteBuffer( REG_LR_OPMODE, opModePrev);
}

实际调试

使2个设备初始化!
1
2
使用串口命令:
F1获取帮助信息
A1设置寄存器
A2发送数据
A3取得数据
3
使用串口命令:A1获取设置寄存器命令格式:
A1空格地址空格数据 –》这是设置
A1空格地址 –》这是读取
寄存器地址:
0D 读取FIFO-ptr地址
00 获取0D指向地址的数据
13 读取RX到的字节数
10 获取最后一包数据的首地址(只发了一包很长的的数据,10内数据为00首地址)
12 获取中断标志位
01 获取运行模式,其值设置为: 88为睡眠、89为待机、8D为持续接收、8B为使能发送
4
使用串口命令:A2 发送数据
A2空格数据 –》这是发送16进制数据
A2”字符串” –》这是发送非16进制数据
5
使用串口命令A3获取数据或清除数据
A3空格01 –》这是获取数据
A3空格00 –》这是清除数据
6
示范:设置接收端 0D 为00首地址
7
发送端也设置
8
发送端发送数据 55 55 55 三个字节的16进制数:
9
接收端收到数据:
10
获取数据包长度:
11
获取最后一包数据首地址:
12
获取数据:
13
这时再看下地址变化:自动增加了1,代表下次访问00内数据是访问指向01这个里面的数据
14
我们再次访问00获取数据:还是55这个字节
15
这时再看下地址变化:自动增加了1,代表下次访问00内数据是访问指向02这个里面的数据
我们可以通过命令 A1 0D 03 改变00指向的地址,从而获取指定地址数据!
也可:不修改0D,直接读取00,这时是未读数据地址(不是最新数据!)
16

LORA信道划分建议

PS此处摘取新浪文档:原文地址
lora划分信道
实际操作:
1、设置寄存器地址:0x01 = 0x88 睡眠
2、设置寄存器地址:0x06至0x08 设置相应频率数值 具体计算方法参考手册page:112典型的32Mhz晶振,分辨率为61.035hz(Fstep=Focsc/2^19 == Fstep = 32 000 000 Hz / 524 288 = 61.035 Hz)
3、频率是Fstep这个数x Frf(0x06至0x08设置的值,hex=6c8000十进制=7110656)即434 000 000 Hz, 即频率为434 MHz
calc

关于带宽

PS此处参考其他博主文档:原文地址
关于LORA的CAD检测参考其他博主文档:原文地址
关于LORA的更多功能参考其他博主文档:原文地址

END!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于CC2530的Zstack协议栈的SX1278调试记录 的相关文章

  • Layui学习笔记,隔壁都馋哭了

    添加一个Tab 切换用户管理 删除商品管理 删除所有tab 简单风格的Tab 网站设置 用户管理 权限分配 商品管理 订单管理 高度默认自适应 也可以随意固宽 2 Tab进行了响应式处理 所以无需担心数量多少 内容2 内容3 内容4 内容5
  • 【Unity Shader】unity海边波浪效果的实现

    效果图如下 GIF因为为了把图压小所以删掉了一些帧导致后面速度突然很快 实际效果并不是这样 PS 对于移动端 参考该文章 http www lsngo net 2018 03 22 unity seawave vertexcolor 之前在

随机推荐

  • react(56)——在项目中使用开发者工具redux-devtools-extension

    1 谷歌安装插件 需要访问外网 在谷歌商店中下载 也可以自己格外找资源 2 项目中添加redux devtools extension库 在终端运行cnpm add redux devtools extension即可 3 在store j
  • 使用cookie和session实现登录(简单原理解析)

    cookie 浏览器在客户端电脑硬盘中开辟的一块空间 主要用来存储服务端数据 比如sessionId cookie中的数据是以域名的形式进行区分的 cookie中的数据是有过期时间的超过时间会被浏览器自动删除 cookie中的数据可以随着请
  • 2023网络安全面试题(附答案)+面经

    前言 随着国家政策的扶持 网络安全行业也越来越为大众所熟知 相应的想要进入到网络安全行业的人也越来越多 为了拿到心仪的Offer之外 除了学好网络安全知识以外 还要应对好企业的面试 所以在这里我归纳总结了一些网络安全方面的常见面试题 希望能
  • 读磁盘概述

    磁盘结构 磁道C 磁头H 扇区S 一个磁盘有很多个盘面 上面是其中一个盘面 每个盘面对应一个磁头 磁盘的最小单元是扇区 通过CHS可以定位到一个确定的扇区 每个扇区一般是512个字节 CHS寻道方式 设置好寄存器的值 然后一个int 13就
  • [笔记]MySQL 删除重复数据

    通过内连接 INNER JOIN 方式删除重复数据 场景复现 CREATE TABLE user id bigint 11 AUTO INCREMENT name varchar 64 PRIMARY KEY id engine InnoD
  • Google guava之SortedMultiset简介说明

    转自 Google guava之SortedMultiset简介说明 下文笔者讲述guava中SortedMultiset集合的简介说明 如下所示 guava之SortedMultiset集合简介 SortedMultiset集合 可用于按
  • Android Context完全解析与各种获取Context方法

    Context类型 我们知道 Android应用都是使用Java语言来编写的 那么大家可以思考一下 一个Android程序和一个Java程序 他们最大的区别在哪里 划分界限又是什么呢 其实简单点分析 Android程序不像Java程序一样
  • Gnuradio+uhd驱动软件安装流程

    工作时一部分内容 需要用到gnuradio软件配置 属于软件无线电USRP的内容 不属于计算机视觉 只作为记录 一样的花费了较长时间 大概两周 终于安装成功 虽然有点脱离了自己的兴趣爱好 但也算近期的一个成果 将它分享出来 网上资料很杂乱
  • 二十四.刷题.14

    一个数如果恰好等于它的因子之和 这个数就称为 完数 例如6 1 2 3 编程找出1000以内的所有完数 include
  • 解决报错: PostCSS received undefined instead of CSS string

    解决方案1 可能本地有多个nodeJS版本 本地使用了nvm 之前切到另一个版本编译node sass后 再切换到另外一个nodeJS版本 导致的问题 注意 node sass是一个绑定libsass sass的一种版本 的nodeJS库
  • golang 协程的实现原理

    核心概念 要理解协程的实现 首先需要了解go中的三个非常重要的概念 它们分别是G M和P 没有看过golang源代码的可能会对它们感到陌生 这三项是协程最主要的组成部分 它们在golang的源代码中无处不在 G goroutine G是go
  • 一文概括常用图像处理算法

    本文总结了11种常用的图像处理算法 包含了预处理算法以及检测算法 并介绍了一些常用的开发库 一 算法 预处理算法 检测算法 在采集完图像后 首先会对图像进行预处理操作 保证图像的对比度清晰 水平 方便后续图像处理 常用的图像处理算法 1 图
  • 数学建模专栏 - 聚类分析入门:基本概念和MATLAB实现

    摘要 本文将介绍聚类分析的基本概念和MATLAB的实现方法 我们将先介绍聚类分析的概念和应用场景 然后介绍聚类算法的基本原理 最后用一个实际案例来演示如何使用MATLAB进行聚类分析 1 简介 聚类分析是一种无监督学习方法 用于将数据集分成
  • 关于servlet上传图片,显示不出来报 Get http://localhost:9095/assets/img/head/1656901332651.jpg 404错误

    目录 第一种解决方法 第二种解决方法 第三种方法 配置虚拟路径 不建议尝试 上传图片的工具类 我的tomcat是放在E liulanqi apache tomcat 9 0 62 webapps 第一种解决方法 将上传的图片路径改为上到到t
  • Java知识点汇总--多态

    Java多态 1 多态 1 1 多态的概述 1 2 多态中的成员访问特点 1 3 多态的好处和弊端 1 4 多态中的转型 1 5 多态的案例 1 多态 1 1 多态的概述 什么是多态 同一个对象 在不同时刻表现出来的不同形态 多态的前提 要
  • openGL增强表面细节----法线贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 具体实现思路 二 代码 主程序c 着色器程序 效果 源码下载 前言 凹凸贴图的一种替代方法是使用查找表来替换法向量 这样我们就可以在不依赖数学函 数的情况下 对凸起进行
  • 【运维篇】四、服务日志控制

    文章目录 1 日志基础 2 记录日志 3 快速创建日志对象 4 日志级别更改 5 日志输出格式控制 6 日志记录到文件 1 日志基础 日志的作用 编程期调试代码 记录日常运营重要信息 峰值流量 平均响应时长 记录应用报错信息 错误堆栈 运营
  • 游戏开发jenkins杂谈系列:使用Extended Choice Parameter参数化构建

    可以查看 https blog csdn net qq1105273619 article details 91352562
  • IDEA打包jar包详尽流程

    打包流程 1 打开菜单栏File Project Structure 2 点击Artifacts 3 点击 JAR From module with depenencies 4 后弹出如下界面 自此开始 各种问题就来了 首先Module中
  • 基于CC2530的Zstack协议栈的SX1278调试记录

    SX1278Lora模块串口调试记录 串口调试代码 串口获取调试信息 SPI驱动IO口模拟 加深理解用 SX1278的通讯时序 SX1278 SPI通讯间隔要求 SX1278 寄存器设置 实例 实际调试 LORA信道划分建议 关于带宽 只是