Rtthread学习笔记(八)RT-Thread Studio的软件I2C驱动开发

23 篇文章 78 订阅

RT-Thread 的 I2C 设备驱动框架即支持硬件 I2C 也支持软件模拟 I2C。
由于软件用起来比较方便,随便设置引脚,这里尝试开启一下软件I2C。

一、步骤

1.打开RT-Thread Setting中软件模拟I2C

加粗样式

2.开启board.h中关于I2C的宏定义

在这里插入图片描述

3.直接仿照官方例程初始化读写所需的I2C设备

例子:

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-04-18     CRJ       the first version
 */
#include "stm32f1xx_hal.h"
#include <board.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "app_i2c.h"

#define AHT10_I2C_BUS_NAME          "i2c1"  /* 传感器连接的I2C总线设备名称 */
#define AHT10_ADDR                  0x38    /* 从机地址 */
#define AHT10_CALIBRATION_CMD       0xE1    /* 校准命令 */
#define AHT10_NORMAL_CMD            0xA8    /* 一般命令 */
#define AHT10_GET_DATA              0xAC    /* 获取数据命令 */

static struct rt_i2c_bus_device *i2c_bus = RT_NULL;     /* I2C总线设备句柄 */
static rt_bool_t initialized = RT_FALSE;                /* 传感器初始化状态 */
/* 写传感器寄存器 */
static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t *data)
{
    rt_uint8_t buf[3];
    struct rt_i2c_msg msgs;

    buf[0] = reg; //cmd
    buf[1] = data[0];
    buf[2] = data[1];

    msgs.addr = AHT10_ADDR;
    msgs.flags = RT_I2C_WR;
    msgs.buf = buf;
    msgs.len = 3;

    /* 调用I2C设备接口传输数据 */
    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
    {
        return RT_EOK;
    }
    else
    {
        return -RT_ERROR;
    }
}

/* 读传感器寄存器数据 */
static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf)
{
    struct rt_i2c_msg msgs;

    msgs.addr = AHT10_ADDR;
    msgs.flags = RT_I2C_RD;
    msgs.buf = buf;
    msgs.len = len;

    /* 调用I2C设备接口传输数据 */
    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
    {
        return RT_EOK;
    }
    else
    {
        return -RT_ERROR;
    }
}

static void read_temp_humi(float *cur_temp, float *cur_humi)
{
    rt_uint8_t temp[6];

    write_reg(i2c_bus, AHT10_GET_DATA, 0);      /* 发送命令 */
    rt_thread_mdelay(400);
    read_regs(i2c_bus, 6, temp);                /* 获取传感器数据 */

    /* 湿度数据转换 */
    *cur_humi = (temp[1] << 12 | temp[2] << 4 | (temp[3] & 0xf0) >> 4) * 100.0 / (1 << 20);
    /* 温度数据转换 */
    *cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20) - 50;
}

static void aht10_init(const char *name)
{
    rt_uint8_t temp[2] = {0, 0};

    /* 查找I2C总线设备,获取I2C总线设备句柄 */
    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);

    if (i2c_bus == RT_NULL)
    {
        rt_kprintf("can't find %s device!\n", name);
    }
    else
    {
        write_reg(i2c_bus, AHT10_NORMAL_CMD, temp);
        rt_thread_mdelay(400);

        temp[0] = 0x08;
        temp[1] = 0x00;
        write_reg(i2c_bus, AHT10_CALIBRATION_CMD, temp);
        rt_thread_mdelay(400);
        initialized = RT_TRUE;
    }
}


void Init_I2CAht10(void)
{
    float humidity, temperature;

    humidity = 0.0;
    temperature = 0.0;

    if (!initialized)
    {
        /* 传感器初始化 */
        aht10_init(AHT10_I2C_BUS_NAME);
    }
    if (initialized)
    {
        /* 读取温湿度数据 */
        read_temp_humi(&temperature, &humidity);

        rt_kprintf("read aht10 sensor humidity   : %d.%d %%\n", (int)humidity, (int)(humidity * 10) % 10);
        if( temperature >= 0 )
        {
            rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(temperature * 10) % 10);
        }
        else
        {
            rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(-temperature * 10) % 10);
        }
    }
    else
    {
        rt_kprintf("initialize sensor failed!\n");
    }

}

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
RT-Thread是一个开源的实时操作系统,支持多种平台和多种编译器。在STM32平台上,RT-Thread可以运行并提供实时任务调度和多线程支持。在STM32上使用RT-Thread时,通常会在main函数中调用rtthread_startup()函数作为统一的入口点,开始执行RT-Thread的任务调度和线程管理。\[2\] RT-Thread的线程调度是通过上下文切换来实现的。上下文切换是通过rt_hw_context_switch_interrupt函数来完成的。这个函数会将当前线程的栈指针保存到rt_interrupt_from_thread中,并将要切换到的线程的栈指针保存到rt_interrupt_to_thread中。同时,将rt_thread_switch_interrupt_flag设置为1,表示需要进行上下文切换。然后,通过触发PendSV异常来触发上下文切换。\[3\] 在上下文切换中,为什么只保存了要切换到的线程的栈指针而没有保存当前线程的栈指针呢?这是因为在上下文切换时,当前线程的栈指针已经保存在当前线程的线程控制块中,不需要额外保存。而要切换到的线程的栈指针需要保存在rt_interrupt_to_thread中,以便在切换完成后能够正确恢复该线程的执行。\[3\] #### 引用[.reference_title] - *1* *3* [RT-Thread内核学习记录](https://blog.csdn.net/qq_36439722/article/details/125629548)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [RTthread学习笔记————第3章 内核基础](https://blog.csdn.net/Kk_01110001B/article/details/83718608)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值