目录

点击这里查看所有博文

  本系列博客所述资料均来自合宙官方,并不是本人原创(只有博客是自己写的),csdk只是得到了口头的允许公开授权。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。

  本系列博客基于紫光展锐的RDA8910 LTE Cat 1 bis芯片平台开发。理论上适用于合宙的Air720U、Air724U、广和通L610以及安信可的cat-01模块。

  各个厂家的部分配置文件可能不一样,也许会导致设备出现奇怪的问题,其他的模块我也不确定能不能用,自行测试。但是有一点编译下载和监视流程基本一样,可供参考。

  先不管支不支持,如果你用的模块是是紫光展锐的RDA8910,那都不妨一试,也许会有意外收获(也有可能变砖,慎重!!!)。

  我使用的是Air724UG开发板,如果在其他模块上不能用,那也不要强怼,也许是开发包不兼容吧。这里的代码是没有问题的。例程仅供参考!

一、前言

  大概在一个月之前吧,群里就有小伙伴问:“咱们的CAT1能不能读取到单总线数据啊?比如说DS18B20这些传感器”。当时我就说这些传感器对时序的要求比较高,都是us级别的。驱动放在lua层还真不一定行,csdk的问题应该不大。

  又问:“那小哥哥什么时候安排一波呢?”

  答:“别别别,我可是钢铁直男,对男的没兴趣。要不这样吧,我周末看看吧,有时间的话搞一下”

  然而这一个周末看看,就鸽了将近一个月。

  想了想就这么一直鸽下去也不是个事情。于是乎最近几天抽时间看了下,虽然中间也遇到了一点波折。但是这都不影响结果,好在是搞出来了。既然搞出来了那好东西就要和大家分享。

二、单总线时序

  虽然DS18B20和DHT11都叫做单总线通讯,但是他们的时序要求却不太一样,包括读时序的位置也不一样。不过好在它们基本的交互逻辑都是差不多的,这里就拿ds18b20的驱动时序随便讲一下。

2.1、初始化时序

  在初始化序列期间,总线控制器拉低总线并保持 480us 以发出(TX)一个复位脉冲,然后释放总线,进入接收状态(RX)。单总线由 5K 上拉电阻拉到高电平。当DS18B20 探测到 I/O 引脚上的上升沿后,等待 15-60us,然后发出一个由 60-240us低电平信号构成的存在脉冲。

2.2、写时序

  ds18b20的写时序又分为写0时序和写1时序,总线控制器通过写 1 时序写逻辑 1 到DS18B20,写 0 时序写逻辑 0 到 DS18B20。所有写时序必须最少持续 60us,包括两个写周期之间至少1us 的恢复时间。当总线控制器(单片机)把数据线从逻辑高电平拉到低电平的时候,写时序开始。

  总控制器要生成一个写 0 时序,必须把数据线拉到低电平并持续保持(至少 60us)。然后释放。

  总控制器要生成一个写 1时序,必须把数据线拉到低电平,然后在15us内释放总线,并持续保持(至少 60us)。然后释放。

2.3、读时序

  ds18b20的读时序又分为读0时序和读1时序,总线控制器在发出读暂存器指令[BEh]或读电源模式指令[B4H]后必须立刻开始读时序。所有读时序必须最少 60us,包括两个读周期间至少 1us 的恢复时间。当总线控制器把数据线从高电平拉到低电平时(数据线必须至少保持 1us),读时序开始。

  当传输逻辑 0 结束后,总线将被释放,通过上拉电阻回到上升沿状态。从 DS18B20 输出的数据在读时序的下降沿出现后 15us 内有效。因此,总线控制器在读时序开始后必须停止把 I/O 脚驱动为低电平 15us,以读取I/O 脚状态。

三、OneWire驱动库

  学习完ds18b20的读时序后,介绍下本文开头提到的OneWire库。

  在编写DS18B20和DHT11驱动后,发现类似这种的单总线传感器。都有一个共同的特点,想要完成它们的读取过程,那就需要有us级别的延时,需要能够快速切换gpio的输入/输出状态以及读取/设置gpio的状态。单个操作都必须在极短的时间内完成。整个读取过程中除了需要操作gpio就不依赖任何其他的库函数。

3.1、基础库

  我将这些共同点整理了下,提供了OneWire库,其中包含基础库函数6个,分别是:

/**
@description: 输出调试信息
*/

  • OneWire_printf(fmt,…);

/**
*@description: 设置单总线信号线为输入。默认上拉
*@param :pin{uint8}:要操作的引脚
*@return: TRUE:正确
    FALSE:引脚不在允许范围
*/

  • OneWire_IO_IN(uint8 pin);

/**
*@description: 设置单总线信号线为输出。默认输出高定平
*@param :pin{uint8}:要操作的引脚
*@return: 无
*/

  • OneWire_IO_OUT(uint8 pin);

/**
*@description: 单总线输出高低电平
*@param : pin{uint8}:要操作的引脚
    level{uint8}}:要输出的电平。0或者1
*@return: 无
*/

  • OneWire_DQ_OUT(uint8 pin, uint8 level);

/**
*@description: 读取单总线的高低电平信号
*@param : pin{uint8}:要操作的引脚
*@return: 0或者1
*/

  • OneWire_DQ_IN(uint8 pin);

/**
*@description: 单总线1us延时函数
*@param : us{uint32}:调用的次数。
*@return: 无
*/

  • OneWire_Delay_1us(volatile uint32 us);

3.2、扩展库

  然后又在RDA8910平台上,基于OneWire库开发了DS18B20的驱动以及DHT11的驱动。这两个驱动完全依赖于OneWire库函数,不依赖其他文件,整个驱动基于platform提供的6个函数制作。

  移植在不同的平台只需要修改这上图所示的六个函数,即可直接调用扩展库中提供的ds18b20和dht11的驱动。

3.2.1、DS18B20

  其中DS18B20提供了两个读取函数,分别是:

/**
*@description: 从ds18b20得到温度值数字,精确到0.0625。结果被扩大10000倍
*@param : pin{uint8}:要操作的引脚
    TempNum{int *}:输出温度值
*@return 0:正常获取
    2:传入的pin不在允许范围
    3:未检测到ds18b20
*/

  • uint8 DS18B20_GetTemp_Num(uint8 pin, int *TempNum);

/**
*@description: 从ds18b20得到温度值字符串
*@param : pin{uint8}:要操作的引脚
    TempNum{char *}:输出温度字符串
*@return 0:正常获取
    1:TempStr=NULL
    2:传入的pin不在允许范围
    3:未检测到ds18b20
*/

  • uint8 DS18B20_GetTemp_String(uint8 pin, char *TempStr);

3.2.2、DHT11

  其中DHT11提供了两个读取函数,分别是:

/**
*@description: 从dht11得到温/湿度值数字
*@param : pin{uint8}:要操作的引脚
    HumNum{uint8 *}:输出温度值
    TemNum{uint8 *}:输出湿度值
*@return 0:正常获取
    2:传入的pin不在允许范围
    3:未检测到dht11
    4:数据校验错误
*/

  • uint8 DHT11_GetData_Num(uint8 pin, uint8 *HumNum, uint8 *TemNum);

/**
*@description: 从dht11得到温/湿度值字符串
*@param : pin{uint8}:要操作的引脚,可选范围0、1、2、3、7
    HumStr{char *}:输出温度值字符串
    TemStr{char *}:输出湿度值字符串
*@return 0:正常获取
    1:HumStr == NULL || TemStr == NULL
    2:传入的pin不在允许范围
    3:未检测到dht11
    4:数据校验错误
*/

  • uint8 DHT11_GetData_String(uint8 pin, char *HumStr, char *TemStr);

  主要是我手上就只有这两种传感器,只能在初始版本内置两个驱动的具体实现。有兴趣的同学可以一起来参与此仓库的贡献。

  上述OneWire操作库,已经在码云开源,获取地址:

git clone https://gitee.com/chenxiahuaxu/onewire_driver_library

四、测试DS18B20驱动

4.1、编写程序

  这一部分是本例程的核心,目的是读取DS18B20的值。

static void ds18b20_task(PVOID pParameter)
{iot_os_sleep(3000);while (1){if (DS18B20_GetTemp_Num(7, &TempNum) == 0){iot_debug_print("[ds18b20]DS18B20_GetTemp_Num : %d", TempNum);}iot_os_sleep(1000);if (DS18B20_GetTemp_String(7, &TempStr[0]) == 0){iot_debug_print("[ds18b20]DS18B20_GetTemp_String : %s", TempStr);}iot_os_sleep(1000);}
}

  这一部分是本例程的彩蛋,将读取到的值显示在OLED-SSD1306上。

static void oled_task(PVOID pParameter)
{if (OLED_Init() == FALSE) //初始化OLED{while (1){iot_debug_print("[oled]OLED_Init FALSE!");iot_os_sleep(1000);}}OLED_ShowString(0, 0, "LUAT CSDK", 24);OLED_ShowString(0, 24, "DEMO DS18B20", 16);OLED_ShowString(0, 40, "Tempera:", 12);OLED_ShowString(0, 52, "num:", 12);while (1){OLED_ShowString(50, 40, TempStr, 12); //显示ASCII字符OLED_ShowNum(50, 52, TempNum, 6, 12); //显示ASCII字符OLED_Refresh_Gram();                  //更新显示到OLEDiot_os_sleep(1000);iot_debug_print("[oled]demo_oled run!");}
}

4.2、完整程序

  完整的demo在这里,可以复制直接用。

/***************demo_ds18b20
****************/#include "iot_debug.h"
#include "iot_os.h"
#include "am_openat.h"
#include "oled.h"
#include "ds18b20.h"int TempNum = 0;
char TempStr[10] = {0};static void oled_task(PVOID pParameter)
{if (OLED_Init() == FALSE) //初始化OLED{while (1){iot_debug_print("[oled]OLED_Init FALSE!");iot_os_sleep(1000);}}OLED_ShowString(0, 0, "LUAT CSDK", 24);OLED_ShowString(0, 24, "DEMO DS18B20", 16);OLED_ShowString(0, 40, "Tempera:", 12);OLED_ShowString(0, 52, "num:", 12);while (1){OLED_ShowString(50, 40, TempStr, 12); //显示ASCII字符OLED_ShowNum(50, 52, TempNum, 6, 12); //显示ASCII字符OLED_Refresh_Gram();                  //更新显示到OLEDiot_os_sleep(1000);iot_debug_print("[oled]demo_oled run!");}
}static void ds18b20_task(PVOID pParameter)
{iot_os_sleep(3000);while (1){if (DS18B20_GetTemp_Num(7, &TempNum) == 0){iot_debug_print("[ds18b20]DS18B20_GetTemp_Num : %d", TempNum);}iot_os_sleep(1000);if (DS18B20_GetTemp_String(7, &TempStr[0]) == 0){iot_debug_print("[ds18b20]DS18B20_GetTemp_String : %s", TempStr);}iot_os_sleep(1000);}
}int appimg_enter(void *param)
{iot_os_sleep(2000);iot_debug_print("[oled]appimg_enter");iot_os_create_task(oled_task, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "oled_task");iot_os_create_task(ds18b20_task, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "ds18b20_task");return 0;
}void appimg_exit(void)
{iot_debug_print("[oled]appimg_exit");
}

4.3、下载测试

  传感器信号线接在了GPIO7。可以通过程序设定。

五、测试DHT11驱动

4.1、编写程序

  这一部分是本例程的核心,目的是读取DHT11的值。

static void dht11_task(PVOID pParameter)
{iot_os_sleep(3000);while (1){if (DHT11_GetData_String(7, &HumStr, &TemStr) == 0){iot_debug_print("[dht11]HumStr: %s,TemStr: %s", HumStr, TemStr);}iot_os_sleep(3000);}
}

4.2、完整程序

  完整的demo在这里,可以复制直接用。

/***************demo_dht11
****************/#include "iot_debug.h"
#include "iot_os.h"
#include "am_openat.h"
#include "oled.h"
#include "dht11.h"char HumStr[10] = {0};
char TemStr[10] = {0};static void oled_task(PVOID pParameter)
{if (OLED_Init() == FALSE) //初始化OLED{while (1){iot_debug_print("[oled]OLED_Init FALSE!");iot_os_sleep(1000);}}OLED_ShowString(0, 0, "LUAT CSDK", 24);OLED_ShowString(0, 24, "DEMO DHT11", 16);OLED_ShowString(0, 40, "Humidity:", 12);OLED_ShowString(0, 52, "Tempera:", 12);uint8 t = 0;while (1){OLED_ShowString(60, 40, HumStr, 12); //显示ASCII字符OLED_ShowString(60, 52, TemStr, 12); //显示ASCII字符OLED_Refresh_Gram();                 //更新显示到OLEDiot_os_sleep(1000);iot_debug_print("[oled]demo_oled run!");}
}static void dht11_task(PVOID pParameter)
{iot_os_sleep(3000);while (1){if (DHT11_GetData_String(7, &HumStr, &TemStr) == 0){iot_debug_print("[dht11]HumStr: %s,TemStr: %s", HumStr, TemStr);}iot_os_sleep(3000);}
}int appimg_enter(void *param)
{iot_os_sleep(2000);iot_debug_print("[oled]appimg_enter");iot_os_create_task(oled_task, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "oled_task");iot_os_create_task(dht11_task, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "dht11_task");return 0;
}void appimg_exit(void)
{iot_debug_print("[oled]appimg_exit");
}

4.3、下载测试

  传感器信号线也接在了GPIO7。可以通过程序设定。

不会下载的点击这里,进去查看我的RDA8910 CSDK二次开发入门教程专题第一篇博文1、RDA8910CSDK二次开发:环境搭建里面讲了怎么下载
这里只是我的学习笔记,拿出来给大家分享,欢迎大家批评指正,本篇教程到此结束

15、RDA8910(4GCAT1)CSDK二次开发:通过OneWire驱动库获取DS18B20/DHT11的数据相关推荐

  1. 4、RDA8910(4GCAT1)CSDK二次开发:期待已久的ADC采集

    目录 点击这里查看所有博文   本系列博客所述资料均来自合宙官方,并不是本人原创(只有博客是自己写的),csdk只是得到了口头的允许公开授权.出于热心,本人将自己的所学笔记整理并推出相对应的使用教程, ...

  2. 1、RDA8910(4GCAT1)CSDK二次开发:环境搭建

    https://blog.csdn.net/weixin_44570083/article/details/106210592 目录 点击这里查看所有博文   本系列博客所述资料均来自合宙官方,并不是 ...

  3. 方维团购系统二次开发,order、order_goods、goods表的数据

    方维团购系统二次开发,order.order_goods.goods表的数据 select * from fanwe_order; 数据库查询结果 [ 返回12条查询记录 耗时:0.000805s ] ...

  4. 合宙Air724UG Cat1(4G)CSDK 二次开发总结(DNS TCP)

    最近项目要用到cat1模块,之前使用过这个模块,但是是有MCU的,所以只需要知道如何发送正确的AT指令即可. 现在是需要对这个cat1模块进行二次开发,在这个过程中学到了什么进行总结. 这次使用的合宙 ...

  5. postek二次开发_使用PX4的ECL进行多传感器数据融合的后处理

    写在前边ecl是开源无人机项目PX4使用的算法库,使用ekf(扩展卡尔曼滤波)进行imu等多种传感器的数据融合 然而ecl不提供数据后处理功能 能使用ecl进行多传感器数据融合的后处理是很有必要的,这 ...

  6. ANSA二次开发 - 安装外部python库(以xlrd为例)

      Python由于其易用性和良好的可扩展性以及丰富的第三方库,而被越来越多的CAX软件作为二次开发的脚本语言.   ANSA前处理软件得二次开发语言就是Python语言,但其与常规Python发行版 ...

  7. GoogleEarth二次开发平台指南(3) ---如何获取点坐标、绘制线路和区域、沿指定线路三维漫游

    上一文讲解了谷歌地球二次开发中遇到如何把图片.模型导入到谷歌地球的指定位置的问题.除了用户将自己的图片.模型导入到谷歌地球中来构建自己的三维场景外,获取点坐标.标注点位置.绘制线条和区域界线.沿指定线 ...

  8. UG NX二次开发(C#)-建模-获取曲面的法矢

    文章目录 1.前言 2.曲面的法矢示例 3.获取曲面的法矢 3.1 采用 uFModl.AskFaceProps实现 3.2采用 uFSo实现 4.结论 1.前言 在UG NX二次开发过程中,我们想获 ...

  9. CAD二次开发(c#)利用选择集获取标注尺寸

    1.目的 本文的目的是利用C#中选择集GetSelection函数得到CAD中标注尺寸 2.实现代码 using Autodesk.AutoCAD.ApplicationServices; using ...

最新文章

  1. Oracle 10.2.0.5.4 Patch Set Update (PSU) – Patch No: p12419392
  2. 2018几大主流的 UI/JS 前端框架
  3. 剖析boot.img的制作流程
  4. 让用户来决定Windows任务管理器的CPU占用率
  5. 每次调试都必须clean_如何使用“ The Clean Architecture”每次编写健壮的应用程序...
  6. 结构体与共用体05 - 零基础入门学习C语言57
  7. Nodejs 英雄管理系统
  8. 深入研究java.lang.ThreadLocal类
  9. Excel 2010 VBA 入门 109 获取某列最后非空单元格行号
  10. AlertDialog.Builder setPositiveButton 点击时不关闭dialog
  11. 阿里云oss中解决IE浏览器下载中文文件时乱码问题
  12. 智能手机与个人计算机有什么区别,请问智能手机与非智能手机的区别!
  13. 不一样的课程表,不一样的Excle--用Excle进行设计(12):网状结构
  14. 使用 ktra 搭建私人 Cargo registry
  15. 如何书写一手优雅的代码之小刚有话说
  16. 【关于理想】别让你的理想显得太掉价,每个人都很值钱
  17. VC++保存和读取文件中的汉字出现乱码
  18. ps cc 生成html,ps cc中怎么生成图像资源?
  19. 中国最懒城市,这里的人不想赚钱,只想躺平
  20. Web 实现前后端分离,前后端解耦

热门文章

  1. 弘辽科技:抖音小店差评如何补救?
  2. java玫瑰花代码_教小白用Html代码做玫瑰花
  3. 基本模型计算机框架原理设计 题目分析,计算机销售论文大纲模板 计算机销售论文框架怎么写...
  4. 计算机应用技术的论文如何写,计算机应用技术专业论文大纲模板范本 计算机应用技术专业论文大纲怎么写...
  5. STM32-SWD仿真时PB3,PB4,PA15使用问题
  6. 计算机视觉的应用,计算机视觉新手指南
  7. Translational Psychiatry:重度抑郁障碍的神经进行性特征:内在连接组分析
  8. NLP之PTM:自然语言处理领域—预训练大模型时代的各种吊炸天大模型算法概述(Word2Vec→ELMO→Attention→Transfo→GPT系列/BERT系列等)、关系梳理、模型对比之详细攻略
  9. Ubuntu系统输入密码无法进入桌面
  10. U-boot中控制台命令