LoRa节点开发——SDK整体设计思路
LoRa节点SDK看着代码多、工程大,但是如果我们从宏观上把握了SDK的思路,那么很快就能拿下它。
1、硬件连接
从sx1276的参考设计https://os.mbed.com/media/uploads/GregCr/sx1276mb1las_e311v02a_sch.pdf中我们可以看出:
sx1276与mcu需要连接的io口,SPI(SCK、MISO、MOSI、NSS)、DIO0~DIO5;SPI口用于通讯,DIO~DIO5用于产生外部中断。实际上DIO0~DIO5可以根据软件设计取舍,查看datasheet可以看到DIO0~DIO5分别对应不同的功能:
2、外部中断
从上面的图,我们可以看出,DIOx Mapping被设置为不同的值,DIOx产生的中断(电平跳变)对应不同的状态。
基本的思路:将DIOx连接到MCU--->对应的mcu口设置为外部中断模式--->设置DIOx Mapping的模式--->事件发生(RxDone接受完成、TxDone发送完成)--->产生外部中断--->回调事件函数。
以DIO0为例说明:
DIO0连接到了PA10,我们知道PA10对应的外部中断函数是
void EXTI15_10_IRQHandler( void )
注册过程,依次调用如下函数:
SX1276IoInit( );
GpioInit( &SX1276.DIO0, RADIO_DIO_0, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
SX1276IoIrqInit( DioIrq );
//DioIrq是函数指针数组, SX1276OnDio0Irq、 SX1276OnDio1Irq等是成员,分别是DIO0、DIO1等的外部中断回调函数。
GpioSetInterrupt( &SX1276.DIO0, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[0] );
//设置DIO0为上升沿触发,高优先级,中断回调函数为irqHandlers[0];
GpioMcuSetInterrupt( obj, irqMode, irqPriority, irqHandler );
GpioIrq[( obj->pin ) & 0x0F] = obj; //注册回调函数
中断发生后,依次回调如下函数:
EXTI15_10_IRQHandler( );//外部中断的中断函数
HAL_GPIO_EXTI_Callback( uint16_t gpioPin ) //HAL库回调函数
GpioIrq[callbackIndex]->IrqHandler( GpioIrq[callbackIndex]->Context );//回调
3、定时器链表
SDK中用RTC作为定时器,调度整个系统的运行。
基本的思路:初始化RTC定时器,定义一个时间事件定时器、设置定时时长、启动时间事件定时器、设置RTC闹钟时间、RTC闹钟时间到、调用对应的事件回调函数。
看一下结构体时间事件定时器的结构体,其中struct TimerEvent_s *Next;指向下一个时间事件。
/*!
* brief Timer object description
*/
typedef struct TimerEvent_s
{
uint32_t Timestamp; //! Current timer value
uint32_t ReloadValue; //! Timer delay value
bool IsStarted; //! Is the timer currently running
bool IsNext2Expire; //! Is the next timer to expire
void ( *Callback )( void* context ); //! Timer IRQ callback function
void *Context; //! User defined data object pointer to pass back
struct TimerEvent_s *Next; //! Pointer to the next Timer object.
}TimerEvent_t;
时间事件定时器链表:SDK中以静态的方式创建了多个时间事件定时器,每个时间事件定时器作为链表的一个节点。
多个时间事件定时器处理:遍历定时器链表,设置定时时长最小的事件为当前RTC的闹钟时间,RTC闹钟时间到,处理当前事件,遍历定时器链表、再设置定时时长最小的事件为当前RTC的闹钟时间。
一个典型的时间事件定时器使用方法:
static TimerEvent_t LedRedTimer; //定义时间事件定时器节点
void LED_TipInit(void )
{
TimerInit( &LedRedTimer, LedRedTimerEvent ); //初始化时间事件
TimerSetValue( &LedRedTimer, 4000);//设置定时时长
}
static void LedRedTimerEvent(void)
{
TimerStop( &LedRedTimer );
LED_RED_OFF();
}
void LedRedTipOn(void) //启动定时器
{
TimerStart( &LedRedTipTimer );
LED_RED_ON();
}
上面示例了一个简单的LED灯闪的时间事件定时器的用法。
4、休眠
SDK中使用的stop模式,只能通过外部中断,或者RTC闹钟唤醒。
外部中断:SX1276的DIOx、用户应用的外部中断;
RTC闹钟:进入休眠后射频是关闭的,因此进入休眠之前至少要确保有一个时间事件定时器在跑,负责进入休眠之后,将没法唤醒。通常情况下进入休眠之后,会有一个周期发送的时间事件定时器在跑的,SDK中的周期发送数据的时间事件定时器是TxNextPacketTimer。
总结:如果需要移植到其他的平台,主要的工作就是修改spi驱动、定时器、外部中断、休眠这几个部分。
- 使用View Model从表现层分离领域模型
- 代码实现WordPress点击进入随机一篇文章的方法
- UE4新手编程之创建空白关卡和添加碰撞体
- Office Web Apps
- hadoop: hive 1.2.0 在mac机上的安装与配置
- ASP.NET 5运行时升级到Beta5
- WordPress免插件仅代码实现“返回顶部、返回底部、评论”效果(样式二)
- jQuery/asp.net mvc DateTime 的处理
- WordPress主题下funtions.php的一段“恶意”代码
- eclipse/intellij idea 远程调试hadoop 2.6.0
- Jexus 5.8.2 正式发布为Asp.Net Core进入生产环境提供平台支持
- 区块链技术发展前景可观,银链原子链已开始投入正常交易
- 分布式服务框架 dubbo/dubbox 入门示例
- SmtpClient发送邮件遭遇The specified string is not in the form required for a subject.
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android:源码解析 Dialog的窗口机制
- Java|获取图片rgb值
- (数据科学学习手札93)利用geopandas与PostGIS进行交互
- 设计模式(三):旅行的角度理解抽象工厂模式
- 机器学习中的优化算法!
- 【进阶篇】Python+Go——带大家一起另寻途径提高计算性能
- 爬取豆瓣高分电影。
- 快速带你上手Hyperledger Fabric环境搭建+开发测试
- 尝鲜使用微众银行WeCross实现基于哈希时间锁定的跨链转账
- Flutter 富文本第三方库 rich_text_widget
- 程序员的数学:线性代数之可视化
- 基于七牛SDK构建的Vue单页图片管理应用
- [Electron]仿写一个课堂随机点名小项目
- SyntaxError: (unicode error) 错误解决
- 理解CSS布局和块格式化上下文