使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》

上一篇:使用线上的开发板做开发调试
下一篇:使用AliOS Things快速构建RGB灯应用

使用AliOS Things快速构建温度计应用

本文是基于AliOS Things 3.1快速构建温度计的应用场景。涉及AliOS Things组件开发,构建AliOS Things用户项目,AliOS Things HAL API使用,向AliOS Things中添加并使用组件。用到的硬件设备有半导体开发板、温度传感器、数码管显示器。

背景信息

  • AliOS Things HAL API

AliOS Things向用户提供的统一硬件抽象API,为用户提供标准的对MCU片上硬件操作的能力。使得用户应用在多个不同平台之间迁移时,可以无需考虑硬件平台本身的区别,同时也使外设驱动类组件可以快速地在适配过AliOS Things的不同硬件之间复用,提高开发效率。

  • AliOS Things 组件

AliOS Things提供的功能扩展能力。通过将外设驱动,通信协议,控制算法,数据算法等通用能力封装为符合AliOS Things标准的组件,是各种附加能力可以快速被用户复用于自己的应用中。同时,组件与OS分离设计,按需安装使用,可以有效地控制资源占用。

  • I2C总线

I2C总线用于总线上的器件之间传送信息,是一种简单、双向二线制同步串行总线。发送数据一方称为主器件,被寻址的器件称为从器件,由主器件负责产生定时时钟和终止数据传送。

  • TM1637芯片

TM1637 是一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU 数字接口、数据锁存器、LED 高压驱动、键盘扫描等电路。主要应用于电磁炉、微波炉及小家电产品的显示屏驱动。
整体流程图如下:
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》

  • 物联网系统使用AliOS Things 3.1版本作为基础软件平台。
  • 设备端开发使用AliOS Things的HAL(硬件抽象层) API及组件,实现片上外设的使用及外部传感器的数据采集。
  • 开发板采用意法半导体NUCLEO-F103RB开发板,主控芯片为stm32f103RBT6。AliOS Things已完成对该主板的适配。
  • 温度传感器采用LM75A数字温度传感器,该传感器通过I2C总线与主控MCU通信,可以提供0.125℃精度的温度输出。
  • 数码管采用由TM1637驱动的6位数码管进行显示。

硬件连接图如下:
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》

步骤一:创建AliOS Things用户项目

1.单击左下角+按钮。在弹窗的选项框中选择project
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
2.选择helloworld_demo作为工程构建模板。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
3.选择stm32f103rb-nucleo作为开发板。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
4.输入应用名,按enter键,例如:myapp_wdj。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
5.选择工程存储目录,按enter键生成项目工程。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
6.开发工具Visual Studio Code自动打开生成的用户应用。
用户应用主入口位于appdemo.c文件中。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
7.单击下面的编译图标使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》进行编译。
在控制台中看到编译结果。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
8.单击下面的烧录使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》图标,将编译好的固件烧写到开发板中。
9.单击插头图标,可以打开串口调试工具进行观察。
开发板已在按照模板程序打印hello world字符及打印计数。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
至此,用户应用工程建立完毕。

步骤二:加入温度采集

1.在工程appdemo.c文件中加入如下代码。

#include <aos/hal/i2c.h>                // 包含需要用到的I2C HAL驱动
#define I2C1_PORT_NUM PORT_I2C_1       // 使用开发板的第一路I2C通道
#define I2C_RX_TIMEOUT 10               // 定义接收超时时间宏
i2c_dev_t i2c1;                         // 定义一个I2C设备结构体,用户后续操作具体的I2C接口

/* i2c初始化函数 */

void i2c1_init(void)
{
    int ret = -1;
    /* i2c attr config */
    i2c1.port = PORT_I2C_1;
    i2c1.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
    i2c1.config.freq = I2C_BUS_BIT_RATES_400K;
    i2c1.config.mode = I2C_MODE_MASTER;
    /* init i2c1 with the given settings */
    ret = hal_i2c_init(&i2c1);
}

HAL的其他参数细节请参考文档

2.在方法application_start中加入I2C初始化。

int application_start(int argc, char *argv[])
{

    int count = 0;

    printf("nano entry here!\r\n");
    //fd = board_lcd_create("name");  
    //board_lcd_write(fd,buffer,len);

    i2c1_init();                    // 调用I2C初始化

    while(1) {
        printf("hello world! count %d \r\n", count++);
        aos_msleep(1000);
    };

}

3.加入温度采集及相关数据处理部分到主循环中。

int application_start(int argc, char *argv[])

{

    int count = 0;

    int ret = -1;

    float temp;

    unsigned char
    i2c_data_buf[10];

    uint16_t TempAll;
    int sig = 1;

    int temp_int;

    printf("nano entry here!\r\n");

    i2c1_init();                    // 调用I2C初始化

    while(1) {

        // printf("hello world! count %d \r\n", count++);

        /*通过HAL读取 0x90地址设备的0x00寄存器,读取长度为2字节,返回数据放入i2c_data_buf中*/

        ret = hal_i2c_mem_read(&i2c1, 0x90, 0x00, I2C_MEMADD_SIZE_8BIT,i2c_data_buf,2,I2C_RX_TIMEOUT);

        if(ret != 0)

        {

            printf("read fail!\r\n");
            // return;
        }

        TempAll = ((i2c_data_buf[0] << 8) + i2c_data_buf[1]);   // 根据LM75自身特性拼接温度数据

       
        printf("middle=%d\r\n",TempAll);

        if ((i2c_data_buf[0] & 0x80) != 0)                      // 判断数据的符号

        {

            TempAll = ~(TempAll) + 1;

            sig = -1;

        }

        TempAll >>=5;      // 低5位无效数据除

       
        printf("middle=%d\r\n",TempAll);    // 打印中间数据用于调试

        temp = TempAll * 0.125* sig;       // 计算最终数据

        printf("temp = %.2f\n",temp);       // 打印最终数据

        aos_msleep(1000);

    };
}             

4.再次编译、烧录、串口监控。
在串口调试框中看到数据已完成采集。至此,温度采集部分完成。

步骤三:加入本地显示

1.组件包安装。
在组件包所在目录,输入如下安装命令。

aos install comp -L aos_TM1637-1.0.3.zip

aos-cube工具会把组件安装到AliOS Things源码目录。
输入以下命令查看安装的组件。

aos list comp

使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
2.在应用中加入组件。

  • 在应用中进行组件的头文件引用。

加入的代码如下:

#include <aos_TM1637.h>                 // 包含组件头文件
  • 在应用中加入组件提供的相关API,完成显示设备驱动输出。

加入的代码如下:

aos_drv_TM1637_init(1,0);       // 组件初始化,PA1=clk;PA0=data
aos_drv_TM1637_SetBrightness(3);    // 通过组件设置数码管亮度
temp_int = temp * 100;              // 数码管不支持小数显示,先将温度转为整数
aos_drv_TM1637_DisplayDecimal(temp_int,2);  // 通过组件API使数码管显示,并将小数点定到第二位以匹配真实数据

3.再次编译、烧录、进行串口监控。
看到温度数据显示到了数码管上,和串口输出一致。
使用AliOS Things快速构建温度计应用 |《AliOS Things快速开发指南》
appdemo.c文件的完整代码如下:

/*
 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
 */

#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include "aos/init.h"
#include "board.h"
#include <k_api.h>

#include <aos/hal/i2c.h>                // 包含需要用到的I2C HAL驱动

#include <aos_TM1637.h>                 // 包含组件头文件

#define I2C1_PORT_NUM  PORT_I2C_1       // 使用开发板的第一路I2C通道
#define I2C_RX_TIMEOUT 10               // 定义接收超时时间宏

i2c_dev_t i2c1;                         // 定义一个I2C设备结构体,用户后续操作具体的I2C接口

/* i2c初始化函数 */
void i2c1_init(void)
{
    int ret = -1;

    /* i2c attr config */
    i2c1.port                 = PORT_I2C_1;
    i2c1.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
    i2c1.config.freq          = I2C_BUS_BIT_RATES_400K;
    i2c1.config.mode          = I2C_MODE_MASTER;
    /* init i2c1 with the given settings */
    ret = hal_i2c_init(&i2c1);
}

int application_start(int argc, char *argv[])
{
    int count = 0;
    int ret = -1;
    float temp;
    unsigned char i2c_data_buf[10];
    uint16_t TempAll;
    int sig = 1;
    int temp_int;
    printf("nano entry here!\r\n");

    i2c1_init();                    // 调用I2C初始化
    aos_drv_TM1637_init(1,0);       // 组件初始化,PA1=clk;PA0=data
    aos_drv_TM1637_SetBrightness(3);    // 通过组件设置数码管亮度
    while(1) {
        // printf("hello world! count %d \r\n", count++);
        /*通过HAL读取 0x90地址设备的0x00寄存器,读取长度为2字节,返回数据放入i2c_data_buf中*/
        ret = hal_i2c_mem_read(&i2c1, 0x90, 0x00, I2C_MEMADD_SIZE_8BIT,i2c_data_buf,2, I2C_RX_TIMEOUT);
        if(ret != 0)
        {
            printf("read fail!\r\n");
            // return;
        }
        TempAll = ((i2c_data_buf[0] << 8) + i2c_data_buf[1]);   // 根据LM75自身特性拼接温度数据
        printf("middle=%d\r\n",TempAll);
        if ((i2c_data_buf[0] & 0x80) != 0)                      // 判断数据的符号
        {
            TempAll = ~(TempAll) + 1;
            sig = -1;
        }
        TempAll >>= 5;      // 低5位无效数据除
        printf("middle=%d\r\n",TempAll);    // 打印中间数据用于调试
        temp = TempAll * 0.125 * sig;       // 计算最终数据
        printf("temp = %.2f\n",temp);       // 打印最终数据
        temp_int = temp * 100;              // 数码管不支持小数显示,先将温度转为整数
        aos_drv_TM1637_DisplayDecimal(temp_int,2);  // 通过组件API使数码管显示,并将小数点定到第二位以匹配真实数据
        aos_msleep(1000);
    };
}
上一篇:Linux萌芽 | 计算机百年趣味史(下)第11篇


下一篇:HDOJ 1501 Zipper 【DP】【DFS+剪枝】