国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

RT-Thread在STM32硬件I2C的踩坑記錄

這篇具有很好參考價(jià)值的文章主要介紹了RT-Thread在STM32硬件I2C的踩坑記錄。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


參考文章:
1.將硬件I2C巧妙地將“嫁接”到RTT原生的模擬I2C驅(qū)動(dòng)框架
2.基于STM32F4平臺(tái)的硬件I2C驅(qū)動(dòng)實(shí)現(xiàn)筆記
3.《rt-thread驅(qū)動(dòng)框架分析》- i2c驅(qū)動(dòng)

0.前言

??最近打算用RT-Thread做一個(gè)小demo玩玩,其中需要用I2C通信驅(qū)動(dòng)一個(gè)oled屏幕,但是找了一圈也沒找到RTT中對(duì)硬件I2C的支持方式以及使用案例,好像大家都心照不宣的用這個(gè)好用又不好用的軟件I2C。這里還是忍不住吐槽兩句,連硬件SPI都已經(jīng)支持了,甚至支持SPI DMA模式了,硬件I2C這么多年了也沒適配。也希望有大佬能貢獻(xiàn)一份力量,做出一份能讓DIY玩家湊合用的第三方硬件I2C驅(qū)動(dòng)也行。

一、軟硬件I2C區(qū)別

??有關(guān)I2C通信協(xié)議的原理部分就不多介紹了,這個(gè)算是很常見的通信協(xié)議了,CSDN論壇一搜一大把,RT Thread文檔中心也有較詳細(xì)的介紹。
??軟件I2C是使用GPIO的電平翻轉(zhuǎn)模擬出I2C信號(hào),它的好處是方便移植,下至51單片機(jī),上至linux平臺(tái),只要有GPIO都能適用(當(dāng)然linux下也不會(huì)有人用這個(gè))。缺點(diǎn)則是速率很低,軟件操作GPIO電平翻轉(zhuǎn)不可避免的有時(shí)延以及毛刺,為了消除這種現(xiàn)象的影響,模擬的I2C信號(hào)之間就需要稍微大點(diǎn)的時(shí)間間隔。軟件I2C的信號(hào)頻率一般在30KHz ~ 50KHz,即便優(yōu)化相當(dāng)好的情況也差不多在這個(gè)量級(jí)。用來操作128x64的oled屏幕,幀率基本在2幀左右。
??硬件I2C則是通過操作芯片自帶的寄存器進(jìn)行I2C通信,缺點(diǎn)就是不同芯片間驅(qū)動(dòng)不通用,優(yōu)點(diǎn)則是速度更快,并且可以適配DMA模式,降低CPU負(fù)載。筆者使用的STM32RCT6,硬件I2C標(biāo)準(zhǔn)模式信號(hào)頻率為100KHz,快速模式400KHz,一些性能較好的芯片還有1MHz的極速模式。400kHz情況下操作128x64的oled幀率在25幀左右,可以說是提升巨大了。

二、RT Thread中的I2C驅(qū)動(dòng)

??關(guān)于RT Thread中的I2C驅(qū)動(dòng)框架的實(shí)現(xiàn)方式,可以參考上述的第三篇參考文章,個(gè)人覺得寫的很詳細(xì)也好懂。RT Thread為類Linux的實(shí)時(shí)操作系統(tǒng),所以I2C框架的實(shí)現(xiàn)方式和linux中的也比較相像:I2C驅(qū)動(dòng)提供一些操作相關(guān)的ops函數(shù),并注冊(cè)到內(nèi)核中,I2C設(shè)備則可以通過probe函數(shù)掛載到總線上,通過ops操作函數(shù)進(jìn)行I2C通信。
RT-Thread在STM32硬件I2C的踩坑記錄,RT Thread筆記,stm32,單片機(jī),RT-Thread,硬件I2C
并且在該篇文章中,該作者跳過原本的bit_ops,重新設(shè)計(jì)了一個(gè)硬件I2C的實(shí)現(xiàn)方式,將驅(qū)動(dòng)直接掛載到內(nèi)核core中,也實(shí)現(xiàn)了作為master設(shè)備的硬件I2C驅(qū)動(dòng)。不過筆者認(rèn)為這種方式對(duì)通用結(jié)構(gòu)的兼容性不太好,所以又找了一些其他方式。
RT-Thread在STM32硬件I2C的踩坑記錄,RT Thread筆記,stm32,單片機(jī),RT-Thread,硬件I2C

三、嘗試適配硬件I2C

參考文章1和2中,通過修改I2C總線的實(shí)現(xiàn)函數(shù),“嫁接”一個(gè)硬件的I2C驅(qū)動(dòng)實(shí)現(xiàn)方式。這里就先放上代碼,首先在原drv_soft_i2c.c和drv_soft_i2c.h的同級(jí)目錄下,分別創(chuàng)建drv_hard_i2c.c和drv_hard_i2c.h:
drv_hard_i2c.h:

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-08     balanceTWK   first version
 */

#ifndef __DRV_I2C__
#define __DRV_I2C__

#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>

#ifdef BSP_USING_HARD_I2C

/* stm32 config class */
typedef void (*pI2cConfig)(void);
struct stm32_hard_i2c_config
{
    rt_uint8_t scl;                     /* scl pin */
    rt_uint8_t sda;                     /* sda pin */
    const pI2cConfig pFunc;             /* i2c init function */
    const char* pName;                  /* i2c bus name */
    I2C_HandleTypeDef* pHi2c;           /* i2c handle */
    struct rt_i2c_bus_device i2c_bus;   /* i2c bus device */
};
/* stm32 i2c dirver class */
struct stm32_i2c
{
    struct rt_i2c_bit_ops ops;
    struct rt_i2c_bus_device i2c2_bus;
};

#define HARD_I2C_CONFIG(x)  \
{
    .scl        = BSP_I2C##x##_SCL_PIN,    \
    .sda        = BSP_I2C##x##_SDA_PIN,    \
    .pFunc      = MX_I2C##x##_Init,         \
    .pHi2c      = &hi2c##x,                 \
    .pName      = "i2c"#x,                  \
    .i2c_bus    = {
            .ops = &i2c_bus_ops,
    },
}
    
int rt_hw_i2c_init(void);

#endif

#endif /* RT_USING_I2C */

其中stm32_hard_i2c_config可以理解為i2c實(shí)例對(duì)象,屬性包括scl和sda引腳、總線名稱及初始化函數(shù)等。(注:在參考文章2中的總線速度、信號(hào)量及互斥鎖則不需要,因?yàn)槭褂肅ubeMx生成的初始化函數(shù)中已有總線速度,HAL庫中的I2C操作函數(shù)內(nèi)部已有總線鎖)
stm32_i2c則封裝了設(shè)備操作函數(shù)及總線,用于與內(nèi)核對(duì)接。
函數(shù)宏HARD_I2C_CONFIG(x)則用來后續(xù)創(chuàng)建I2C設(shè)備對(duì)象。

drv_hard_i2c.c:

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-08     balanceTWK   first version
 */

#include <board.h>
#include "drv_hard_i2c.h"
#include "drv_config.h"
#include<rtthread.h>
#include<rtdevice.h>

#ifdef BSP_USING_HARD_I2C

//#define DRV_DEBUG
#define LOG_TAG              "drv.i2c"
#include <drv_log.h>

static const struct stm32_hard_i2c_config hard_i2c_config[] =
{
#ifdef BSP_USING_HARD_I2C1
    HARD_I2C_CONFIG(1),
#endif
#ifdef BSP_USING_HARD_I2C2
    HARD_I2C_CONFIG(2),
#endif
#ifdef BSP_USING_HARD_I2C3
    HARD_I2C_CONFIG(3),
#endif
#ifdef BSP_USING_HARD_I2C4
    HARD_I2C_CONFIG(4),
#endif
};

static struct stm32_i2c i2c_obj[sizeof(hard_i2c_config) / sizeof(hard_i2c_config[0])];

/**
 * This function initializes the i2c pin.
 *
 * @param Stm32 i2c dirver class.
 */
static void stm32_i2c_gpio_init(struct stm32_i2c *i2c)
{
    struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)i2c->ops.data;

    rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
    rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);

    rt_pin_write(cfg->scl, PIN_HIGH);
    rt_pin_write(cfg->sda, PIN_HIGH);
}

/**
 * The time delay function.
 *
 * @param microseconds.
 */
static void stm32_udelay(rt_uint32_t us)
{
    rt_uint32_t ticks;
    rt_uint32_t told, tnow, tcnt = 0;
    rt_uint32_t reload = SysTick->LOAD;

    ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
    told = SysTick->VAL;
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow;
            }
            else
            {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                break;
            }
        }
    }
}

/**
 * if i2c is locked, this function will unlock it
 *
 * @param stm32 config class
 *
 * @return RT_EOK indicates successful unlock.
 */
static rt_err_t stm32_i2c_bus_unlock(const struct stm32_soft_i2c_config *cfg)
{
    rt_int32_t i = 0;

    if (PIN_LOW == rt_pin_read(cfg->sda))
    {
        while (i++ < 9)
        {
            rt_pin_write(cfg->scl, PIN_HIGH);
            stm32_udelay(100);
            rt_pin_write(cfg->scl, PIN_LOW);
            stm32_udelay(100);
        }
    }
    if (PIN_LOW == rt_pin_read(cfg->sda))
    {
        return -RT_ERROR;
    }

    return RT_EOK;
}

/* I2C initialization function */
int rt_hw_i2c_init(void)
{
    rt_int8_t ret = RT_ERROR;
    rt_size_t obj_num = NR(hard_i2c_config);
    rt_err_t result;

    for (int i = 0; i < obj_num; i++)
    {
        //GPIO初始化
        stm32_i2c_gpio_init(&hard_i2c_config[i]);

        //檢測(cè)SDA是否為低電平,低電平則通過管腳模擬9個(gè)CLK解鎖
        stm32_i2c_bus_unlock(&hard_i2c_config[i]);

        //調(diào)用Hal庫MX_I2Cx_Init(),配置硬件I2C
        hard_i2c_config[i].pFunc();

        //向內(nèi)核注冊(cè)I2C Bus設(shè)備
        if(rt_i2c_bus_device_register(&(hard_i2c_config[i].i2c_bus), hard_i2c_config[i].pName) != RT_EOK)
        {
            LOG_E("%s bus init failed!\r\n", hard_i2c_config[i].pName);
            ret |= RT_ERROR;
        }
        else
        {
            ret |= RT_EOK;
            LOG_I("%s bus init success!\r\n", hard_i2c_config[i].pName);
        }
    }
    return ret;
}
//INIT_BOARD_EXPORT(rt_hw_i2c_init);

#endif /* BSP_USING_HARD_I2C */

此文件中則主要根據(jù)宏定義開關(guān)創(chuàng)建I2C實(shí)例對(duì)象,并對(duì)其進(jìn)行初始化。主要函數(shù)為rt_hw_i2c_init(),此函數(shù)中所需要的gpio init、delay函數(shù)等,則保留軟件i2c中的初始化操作。

user_i2c.h:

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-08-27     14187       the first version
 */
#ifndef DRIVERS_HARD_I2C_H_
#define DRIVERS_HARD_I2C_H_

//硬件i2c宏開關(guān)
//#define     BSP_USING_HARD_I2C
#ifdef      BSP_USING_HARD_I2C
//      #define BSP_USING_HARD_I2C1
//      #define BSP_USING_HARD_I2C2
//      #define BSP_USING_HARD_I2C3
//      #define BSP_USING_HARD_I2C4

        #if defined(BSP_USING_HARD_I2C1 || BSP_USING_HARD_I2C2 || BSP_USING_HARD_I2C3 || BSP_USING_HARD_I2C4)
            //#define BSP_USING_DMA_I2C_TX
            //#define BSP_USING_DMA_I2C_RX
        #endif
#endif

#endif /* DRIVERS_HARD_I2C_H_ */

為了不在每次保存RT Thread Settings時(shí),自己的配置被覆蓋刷新,所以額外定義了一個(gè)頭文件,用于保存自定義的I2C宏開關(guān),這樣每次刷新后只需要重新在board.h中包含此頭文件即可。

至此自定義的硬件I2C宏開關(guān)及設(shè)備對(duì)象創(chuàng)建已完成,剩下的則只需要替換內(nèi)核中的bit_ops操作函數(shù)即可。

四、i2c-bit-ops操作函數(shù)替換

在rt thread項(xiàng)目根目錄下的 rt-thread/components/drivers/i2c/ 目錄下,有一個(gè)i2c-bit-ops.c文件,其中則保存了i2c驅(qū)動(dòng)框架中注冊(cè)的ops操作函數(shù):

static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
                              struct rt_i2c_msg         msgs[],
                              rt_uint32_t               num)
{
    struct rt_i2c_msg *msg;
    struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
    rt_int32_t i, ret;
    rt_uint16_t ignore_nack;

    if (num == 0) return 0;

    for (i = 0; i < num; i++)
    {
        msg = &msgs[i];
        ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
        if (!(msg->flags & RT_I2C_NO_START))
        {
            if (i)
            {
                i2c_restart(ops);
            }
            else
            {
                LOG_D("send start condition");
                i2c_start(ops);
            }
            ret = i2c_bit_send_address(bus, msg);
            if ((ret != RT_EOK) && !ignore_nack)
            {
                LOG_D("receive NACK from device addr 0x%02x msg %d",
                        msgs[i].addr, i);
                goto out;
            }
        }
        if (msg->flags & RT_I2C_RD)
        {
            ret = i2c_recv_bytes(bus, msg);
            if (ret >= 1)
            {
                LOG_D("read %d byte%s", ret, ret == 1 ? "" : "s");
            }
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_EIO;
                goto out;
            }
        }
        else
        {
            ret = i2c_send_bytes(bus, msg);
            if (ret >= 1)
            {
                LOG_D("write %d byte%s", ret, ret == 1 ? "" : "s");
            }
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_ERROR;
                goto out;
            }
        }
    }
    ret = i;

out:
    if (!(msg->flags & RT_I2C_NO_STOP))
    {
        LOG_D("send stop condition");
        i2c_stop(ops);
    }

    return ret;
}
...
static const struct rt_i2c_bus_device_ops i2c_bit_bus_ops =
{
    i2c_bit_xfer,
    RT_NULL,
    RT_NULL
};

這段代碼中實(shí)現(xiàn)了對(duì)每個(gè)i2c設(shè)備發(fā)送對(duì)應(yīng)的i2c msg流程,將其修改為硬件i2c的發(fā)送方式:

static rt_size_t i2c_xfer(struct rt_i2c_bus_device *bus,
                              struct rt_i2c_msg     msgs[],
                              rt_uint32_t           num)
{
    rt_uint32_t i;
    struct rt_i2c_msg *msg;
    struct stm32_hard_i2c_config *Pconfig = rt_container_of(bus, struct stm32_hard_i2c_config, i2c_bus);

    fot(i = 0;i < num;i++)
    {
        msg = &msgs[i];
        if(msg->flags & RT_I2C_RD)
        {
#if defined(BSP_USING_DMA_I2C_RX)
            HAL_I2C_Master_Receive_DMA(Pconfig->pHi2c, (msg->addr)<<1, msg->buf, msg->len);
            rt_hw_us_delay(100);
#else
            HAL_I2C_Master_Receive(Pconfig->pHi2c, (msg->addr)<<1, msg->buf, msg->len, 100);
#endif
        }
        else
        {
#if defined(BSP_USING_DMA_I2C_TX)
            HAL_I2C_Master_Transmit_DMA(Pconfig->pHi2c, (msg->addr)<<1, msg->buf, msg->len);
            rt_hw_us_delay(100);
#else
            HAL_I2C_Master_Transmit(Pconfig->pHi2c, (msg->addr)<<1, msg->buf, msg->len, 100);
#endif
        }
    }
    return i;
}

static const struct rt_i2c_bus_device_ops i2c_bit_bus_ops =
{
    i2c_xfer,
    RT_NULL,
    RT_NULL
};

參考軟件i2c的發(fā)送方式,創(chuàng)建一個(gè)新的發(fā)送函數(shù)rt_size_t i2c_xfer(),并將rt_i2c_bus_device_ops 中對(duì)應(yīng)的發(fā)送方式修改為此方式。

至此,硬件I2C的驅(qū)動(dòng)則算是完成了一部分,可以通過與軟件i2c一樣的聲明及掛載方式,將設(shè)備掛載到硬件I2C總線上。

五、Attention Please!

問題1:在上述的實(shí)現(xiàn)方式中,可以根據(jù)宏定義通過HAL_I2C_Master_Transmit()或HAL_I2C_Master_Transmit_DMA()方式發(fā)送I2C消息,但并未對(duì)是否發(fā)送成功做出判斷。
問題2:ST官方的HAL庫中,I2C發(fā)送消息共有三種方式,polling模式(輪詢)、中斷模式、DMA模式,HAL_I2C_Master_Transmit()則對(duì)應(yīng)輪詢模式,此模式相對(duì)于軟件I2C雖然速率有所提升,但實(shí)際的提升效果其實(shí)不是特別大。而對(duì)于中斷模式,則需要移植并實(shí)現(xiàn)對(duì)應(yīng)的中斷處理函數(shù),可以按照參考文章2進(jìn)行實(shí)現(xiàn),不過筆者認(rèn)為該篇需要注意的地方很多,比如在中斷處理函數(shù)中釋放信號(hào)量的操作,可能會(huì)造成一些隱患(可以直接去除信號(hào)量)。對(duì)于DMA模式,理論上也需要移植一些中斷處理函數(shù),但筆者目前沒有用這種方式,所以也沒有細(xì)究。所以理論上只能停留在polling模式。
問題3:在drv_hard_i2c.c中,INIT_BOARD_EXPORT(rt_hw_i2c_init);這個(gè)注冊(cè)步驟,需要根據(jù)實(shí)際情況而定,如果想要使用DMA模式,則在此注冊(cè)步驟之前,需要先注冊(cè)MX_DMA_Init(),此函數(shù)為CubeMX生成,用來初始化DMA功能。中斷模式同理。

六、總結(jié)

??目前看來,移植ST的硬件I2C驅(qū)動(dòng)還是困難重重,所以筆者選則了更換平臺(tái)(我逃避。。。)將oled的電路修改成了SPI模式,并更換了芯片平臺(tái),手頭還有一個(gè)LPC54110和一個(gè)CH32的開發(fā)板,這兩個(gè)板子的RTT BSP支持包好像有適配硬件I2C驅(qū)動(dòng),ST再見,希望下次回來有大佬適配了硬件I2C。文章來源地址http://www.zghlxwxcb.cn/news/detail-680980.html

到了這里,關(guān)于RT-Thread在STM32硬件I2C的踩坑記錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32 SHT40驅(qū)動(dòng)源碼(使用硬件I2C)

    STM32 SHT40驅(qū)動(dòng)源碼(使用硬件I2C)

    目錄 簡介: SHT40.c: SHT40.h 測(cè)試結(jié)果: ? ? ? ? SHT40是瑞士Sensirion公司推出的第四代溫濕度傳感器,內(nèi)部集成加熱器用于去除表面微小液滴。集成I2C接口,典型的相對(duì)濕度精度1.8%RH,典型溫度精度0.2℃,運(yùn)行在0-100%RH和-40-125℃的環(huán)境中。 主控:STM32H7B0VBT6 平臺(tái):STM32CubeIDE SHT4

    2024年03月19日
    瀏覽(131)
  • STM32F407系列硬件I2C筆記

    STM32F407系列有3個(gè)硬件I2C: I2C1:該接口位于GPIOB引腳上,包括PB6(I2C1_SCL)和PB7(I2C1_SDA)。 I2C2:該接口位于GPIOB引腳上,包括PB10(I2C2_SCL)和PB11(I2C2_SDA)。 I2C3:該接口位于GPIOA和GPIOC引腳上,包括PA8(I2C3_SCL)和PC9(I2C3_SDA)。 ? 硬件I2C的速度比軟件I2C更快,硬件I2C通??梢?/p>

    2024年02月04日
    瀏覽(34)
  • 【STM32】STM32學(xué)習(xí)筆記-硬件I2C讀寫MPU6050(35)

    【STM32】STM32學(xué)習(xí)筆記-硬件I2C讀寫MPU6050(35)

    I2C(Inter-Integrated Circuit)總線是一種由NXP(原PHILIPS)公司開發(fā)的兩線式串行總線,用于連接微控制器及其外圍設(shè)備。多用于主控制器和從器件間的主從通信,在小數(shù)據(jù)量場(chǎng)合使用,傳輸距離短,任意時(shí)刻只能有一個(gè)主機(jī)等特性。 串行的 8 位雙向數(shù)據(jù)傳輸位速率在標(biāo)準(zhǔn)模式下可

    2024年01月25日
    瀏覽(33)
  • STM32F030硬件I2C代碼及解析

    STM32F030硬件I2C代碼及解析

    剛接觸STM32的時(shí)候,第一個(gè)學(xué)習(xí)的就是I2C,當(dāng)時(shí)去網(wǎng)上學(xué)習(xí)別人寫得I2C代碼,雖然能用,但是當(dāng)時(shí)并不理解為什么要這么配置,特別希望有人把代碼掰碎了講講看,今天突然想起來,就把以前寫的I2C代碼拿出來掰碎了捋捋,希望對(duì)新手有些幫助。 先說說STM32的I2C: ST的M3系列還

    2024年02月08日
    瀏覽(28)
  • 【STM32學(xué)習(xí)】——STM32-I2C外設(shè)&硬件讀寫MPU6050&軟硬件讀寫波形對(duì)比

    目錄 前言 一、I2C外設(shè) 二、硬件I2C操作流程 1.主機(jī)發(fā)送時(shí)序 3.其他時(shí)序

    2024年02月10日
    瀏覽(30)
  • STM32 硬件IIC 控制OLED I2C卡死問題

    STM32 硬件IIC 控制OLED I2C卡死問題

    #更新通知:2023-09-06 STM32L151 固件庫 使用I2C 太難了,又宕機(jī)了,建議不要在固件庫版本上嘗試硬件IIC 了,一般人真用不了,直接使用軟件模擬的,或者不要使用固件庫了,用HAL 庫吧,據(jù)說HAL 庫沒這么多問題,不死心的我還是死心了,等有空再研究吧 3.1 I2C模式,我這里選的

    2024年02月09日
    瀏覽(33)
  • 01_STM32軟件+硬件I2C讀取MPU6050(HAL庫)

    01_STM32軟件+硬件I2C讀取MPU6050(HAL庫)

    目錄 1、I2C簡介 2、I2C時(shí)序單元 2.1 起始條件 2.2 終止條件 2.3 發(fā)送一個(gè)字節(jié) 2.4 接收一個(gè)字節(jié) 2.5 發(fā)送應(yīng)答 2.6 接收應(yīng)答 3、I2C完整時(shí)序 3.1 指定地址寫一個(gè)字節(jié) 3.2 當(dāng)前地址讀一個(gè)字節(jié) 3.2?指定地址讀一個(gè)字節(jié) 4、簡單軟件I2C代碼(HAL) 4.1 軟件I2C 4.2 軟件I2C讀MPU6050寄存器 5、ST

    2024年04月17日
    瀏覽(28)
  • STM32配合cubeMX硬件I2C驅(qū)動(dòng)0.96寸OLED

    STM32配合cubeMX硬件I2C驅(qū)動(dòng)0.96寸OLED

    目錄 一、簡單介紹 1.1? ?OLED 1.2? ?I2C協(xié)議 二、實(shí)戰(zhàn) 2.1 工程配置 2.2 測(cè)試工程 2.3 波形分析 三、驅(qū)動(dòng)OLED 3.1?初始化代碼 3.2 清屏函數(shù) 3.3 設(shè)置坐標(biāo)函數(shù) 3.4 顯示字符函數(shù) 3.5 顯示字符串函數(shù) 3.6 顯示圖片函數(shù) 附錄 驅(qū)動(dòng)代碼文件 oled.c oled.h f6x8.h 有機(jī)發(fā)光二極管 (英語:Organic

    2024年02月08日
    瀏覽(39)
  • STM32F407硬件I2C實(shí)現(xiàn)MPU6050通訊(CUBEIDE)

    STM32F407硬件I2C實(shí)現(xiàn)MPU6050通訊(CUBEIDE)

    工程代碼 https://download.csdn.net/download/weixin_52849254/87886714 I2C1通道可選擇三種不同的通訊協(xié)議:I2C、SMBus-Alert-mode、SMBus-two-wire-Interface。 SMBus (System Management Bus,系統(tǒng)管理總線), 為系統(tǒng)和電源管理這樣的任務(wù)提供了一條控制總線,SMBus與I2C總線之間在時(shí)序特性上存在一些差別 修改

    2024年02月09日
    瀏覽(18)
  • 【STM32】AT24C256硬件I2C讀寫,基于HAL庫

    【STM32】AT24C256硬件I2C讀寫,基于HAL庫

    目錄 一、簡單介紹 二、配置工程 打開CubeMX,配置時(shí)鐘,調(diào)試接口,工程名,目錄等 配置iic 配置串口用于顯示信息 三、硬件連接 四、代碼編寫 一、隨機(jī)寫入一個(gè)字節(jié) 測(cè)試代碼 波形如下 代碼編寫 二、連續(xù)寫入 代碼如下 三、隨機(jī)讀取 測(cè)試代碼 波形如下 代碼編寫 四、連續(xù)

    2024年02月03日
    瀏覽(41)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包