铁电存储器(FM24W256)I2C读写驱动(3):基于HAL库实现硬件I2C读写

news2024/12/25 13:55:49

0 参考资料

FM24W256(Cypress公司生产)数据手册

1 基于HAL库实现硬件I2C读写

1.1 硬件I2C初始化

FM24W256支持最高1MHz的I2C频率,本例也配置为1MHz,相关初始化代码如下:

/**
 * @brief 使用硬件I2C的E2P初始化
 *
 * @return int 0:成功 -1:失败
 */
int bsp_i2c_e2p_init(void)
{
    u8 test_buff;

    /* 速度配置为1MHz,FM24W256支持最高1MHz速率 */
    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x00401242;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
        Error_Handler(__FILE__, __LINE__);
        return -1;
    }

    /** Configure Analogue filter
     */
    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
    {
        Error_Handler(__FILE__, __LINE__);
        return -1;
    }

    /** Configure Digital filter
     */
    if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
    {
        Error_Handler(__FILE__, __LINE__);
        return -1;
    }

    /*
        检查E2P是否能够正常读取
    */
    if (i2c_fram_read(&test_buff, 0, 1) != HAL_OK)
    {
        Error_Handler(__FILE__, __LINE__);
        return -1;
    }

    return 0;
}
/**
 * @brief I2C底层初始化
 *
 * @param hi2c I2C句柄
 */
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    if (hi2c->Instance == I2C1)
    {
        /* USER CODE BEGIN I2C1_MspInit 0 */

        /* USER CODE END I2C1_MspInit 0 */

        /** Initializes the peripherals clock
         */
        PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C12;
        PeriphClkInit.I2c12ClockSelection = RCC_I2C12CLKSOURCE_PCLK1;
        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
        {
            Error_Handler(__FILE__, __LINE__);
            return;
        }

        __HAL_RCC_GPIOD_CLK_ENABLE();
        /**I2C1 GPIO Configuration
        PD3     ------> I2C1_SDA
        PD12     ------> I2C1_SCL
        */
        GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_12;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF5_I2C1;
        HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

        /* Peripheral clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();

        /* USER CODE BEGIN I2C1_MspInit 1 */

        /* USER CODE END I2C1_MspInit 1 */
    }
}

/**
 * @brief I2C底层去初始化
 *
 * @param hi2c I2C句柄
 */
void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
{
    if (hi2c->Instance == I2C1)
    {
        /* USER CODE BEGIN I2C1_MspDeInit 0 */

        /* USER CODE END I2C1_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_I2C1_CLK_DISABLE();

        /**I2C1 GPIO Configuration
        PD3     ------> I2C1_SDA
        PD12     ------> I2C1_SCL
        */
        HAL_GPIO_DeInit(GPIOD, GPIO_PIN_3);

        HAL_GPIO_DeInit(GPIOD, GPIO_PIN_12);

        /* USER CODE BEGIN I2C1_MspDeInit 1 */

        /* USER CODE END I2C1_MspDeInit 1 */
    }
}

1.2 硬件I2C读取数据

/**
 * @brief 从铁电存储器读取n字节
 *
 * @param pBuffer 读取buffer
 * @param ReadAddr 读取地址
 * @param length 长度
 * @return int 0:成功 -1:失败
 */
int i2c_fram_read(uint8_t *pBuffer, uint16_t ReadAddr, uint16_t length)
{
    u8 addr_buffer[2];
    HAL_StatusTypeDef status = HAL_OK;

    /* 构造读取写入buffer */
    addr_buffer[0] = (ReadAddr >> 8) & 0xff;
    addr_buffer[1] = (ReadAddr >> 0) & 0xff;

    status = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, addr_buffer, 2, 100);
    if (status != HAL_OK)
    {
        return -1;
    }

    status = HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS, pBuffer, length, 100);
    if (status != HAL_OK)
    {
        return -1;
    }

    return 0;
}

这里使用的是FM24W256的随机读取方式,时序图如下:
在这里插入图片描述

1.3 硬件I2C写入数据

/**
 * @brief 向铁电存储器写入n字节
 * 写入长度不得大于EEPROM_WRITE_MAX_LENGTH
 * @param pBuffer 写buffer
 * @param WriteAddr 写首地址
 * @param length 长度
 * @return int 0:成功 -1:失败
 */
int i2c_fram_write(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t length)
{
    uint16_t i, j = 2;
    uint8_t write_buffer[2 + EEPROM_WRITE_MAX_LENGTH];
    HAL_StatusTypeDef status = HAL_OK;
    /* 单次写入长度超过限制 */
    if (length > EEPROM_WRITE_MAX_LENGTH)
    {
        return -1;
    }

    /* 构造写入buffer */
    write_buffer[0] = (WriteAddr >> 8) & 0xff;
    write_buffer[1] = (WriteAddr >> 0) & 0xff;
    for (i = 0; i < length; i++)
    {
        write_buffer[j++] = pBuffer[i];
    }

    status = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, write_buffer, 2 + length, 100);
    if (status != HAL_OK)
    {
        return -1;
    }

    return 0;
}

这里使用的FM24W256写入时序图如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2048632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】yum、vim、gcc/g++的使用

目录 一、Linux 软件包管理器 yum 什么是软件包 关于 rzsz 查看软件包★ 如何安装软件★ 如何卸载软件★ Linux 开发工具 二、Linux编译器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 vim末行模式命令集 vim操作总结 如果在vim界面不小心按了Ctrl …

[Meachines] [Medium] solidstate Apache JAMES RCE+POP3邮件泄露+定时任务权限提升

信息收集 IP AddressOpening Ports10.10.10.51TCP:22&#xff0c;25&#xff0c;80&#xff0c;110&#xff0c;119&#xff0c;4555 $ nmap -p- 10.10.10.51 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.4p1 Debian 10deb9u…

Processing练习之变换颜色

案例代码如下&#xff1a; import generativedesign.*; import processing.pdf.*; import java.util.Calendar; boolean savePDFfalse; int tileCountX 2; //jianbianshuliang int tileCountY10;//hangshu color[] colorsLeft new color[tileCountY]; color[] colorsRightne…

管道与信号量

一、基本知识 1、管道&#xff0c;是特殊的文件&#xff08;基于内核&#xff08;内存&#xff09;上创建&#xff09;&#xff1b;以前的文件是在硬盘上创建。 2、工作方向 单工&#xff1a;数据方向单一&#xff0c;广播 半双工&#xff1a;同一时刻只能有一个方向&#…

算法【Java】 —— 滑动窗口

滑动窗口 在上一篇文章中&#xff0c;我们了解到了双指针算法&#xff0c;在双指针算法中我们知道了前后指针法&#xff0c;这篇文章就要提到前后指针法的一个经典的使用 —— 滑动窗口&#xff0c;在前后指针法中&#xff0c;我们知道一个指针在前&#xff0c;一个指针在后&a…

Page与自定义Components生命周期

自定义组件 自定义组件一般可以用@component,装饰,在结构体里面用build方法定义UI,或者用@builder装饰一个方法,来作为自定义组件的构造方法 而页面page一般用@Entry,和@component结合起来使用 页面生命周期方法: onPageShow:页面每次显示时触发 onPageHide:页面每次隐藏时…

【LeetCode每日一题】——662.二叉树最大宽度

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 广度优先搜索 二【题目难度】 中等 三【题目编号】 662.二叉树最大宽度 四【题目描述】 给…

《python语言程序设计》2018版第7章第05题几何:正n边形,一个正n边形的边都有同样的长度。角度同样 设计RegularPolygon类

结果和代码 这里只涉及一个办法 方法部分 def main():rX, rY eval(input("Enter regular polygon x and y axis:"))regular_num eval(input("Enter regular number: "))side_long eval(input("Enter side number: "))a exCode07.RegularPol…

C++入门——01类与对象

1.类 1.1.类的引入 C语言中&#xff0c;结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体内不仅可以定义变量&#xff0c;也可以定义函数。 struct Student {void SetStudentInfo(const char* name, const char* gender, int age){strcpy(_name, name);strcpy(_gen…

微信公众号批量上传、发布文章管理系统(Python版)

功能亮点 一键批量操作文章自动排版支持自定义文章数量适用于多号操作支持文章管理、查询、查看支持查询当前状态 适用对象 公众号运营批量文章上传发布矩阵号管理 部分关键代码及步骤 微信公众号后台的设置与开发栏目中的基本配置里获取appid和appsecret。 获取微信公众号…

软件测试 - 测试用例(设计测试用例的思路、万能公式、测试用例设计的方法)

一、测试用例 1.1 概念 测试用例&#xff08; Test Case &#xff09;是为了实施测试而向被测试的系统提供的一组集合&#xff0c;这组集合包含&#xff1a;测试环 境、操作步骤、测试数据、预期结果等要素。 1.2 编写测试用例 1&#xff09;excel 表格编写 笔试题的测试用例…

【Nginx】Nginx 安装(平滑升级和回滚)

一、 Nginx 概述 Nginx 介绍 Nginx &#xff1a; engine X &#xff0c; 2002 年开发&#xff0c;分为社区版和商业版 (nginx plus ) 2019 年 3 月 11 日 F5 Networks 6.7 亿美元的价格收购 Nginx 是免费的、开源的、高性能的 HTTP 和反向代理服务器、邮件代理服务器、以…

路由器VLAN配置(H3C)

路由器VLAN配置&#xff08;H3C&#xff09; 控制页面访问 路由器默认处于192.168.1.1网段&#xff08;可以短按reset重置&#xff09;&#xff0c;如果要直接使用需要设置静态IP处于同一网段&#xff1b; 对路由器进行配置也要将电脑IP手动设置为同一网段&#xff1b; 默…

音频剪辑软件哪个好用?五大音频剪辑软件分享

如果你正打算在家自学视频制作&#xff0c;那么恭喜你&#xff0c;你已经踏上了一段充满魔法与惊喜的旅程&#xff01;不过&#xff0c;别忘了&#xff0c;视频的灵魂不仅仅在于画面&#xff0c;更在于那直击心灵的音效。 想象一下&#xff0c;一个精心剪辑的片段&#xff0c;…

如何拯救非正常专利申请?

在无忧专利微信公众号2023年年初的一篇文章中提到&#xff0c;出于提质增效的考虑&#xff0c;专利局加大了对非正常申请的打击力度。 专利局打击非正常申请的方式包括&#xff1a;建立黑名单、启用新的业务办理系统、使用大数据识别技术、惩罚非正常申请和非正常代理行为。 …

Vehicle Perception from Satellite(2024 TPAMI 卫星视频车流量监控)

Vehicle Perception from Satellite&#xff08;2024 TPAMI 卫星视频车流量监控&#xff09; 前言1.1 动机1.2 概述1.3 贡献 2 相关工作2.1 遥感中的目标检测2.2 计算机视觉中的相关任务2.3 卫星交通监控 3 TMS 数据集3.1 数据收集与预处理3.2 数据统计3.3 应用任务 4 实验4.1 …

C++奇迹之旅:手写vector模拟实现与你探索vector 容器的核心机制与使用技巧

文章目录 &#x1f4dd;基本框架&#x1f320; 构造和销毁&#x1f309;vector()&#x1f309;vector(const vector& v)&#x1f309;vector(size_t n, const T& value T())&#x1f309;赋值拷贝构造&#xff1a;vector<T>& operator(vector<T> v)&a…

XSS的DOM破坏

目录 1、DOM破坏案例解释 1.1先写一个demo.html文件 1.2、执行demo&#xff0c;看到是否将全部移除%20scr1%20οnerrοralert(1)> 分析&#xff1a; 解决&#xff1a;把两个for不在同一个数组进行操作 1.3、接下来我们要想办法让第二个for循环不能删除&#xff0c;留下…

android FD_SET_chk问题定位

android FD_SET_chk问题定位 一、FD报错二、问题定位2.1 APM定位2.2 adb定位2.3. 代码获取FD数 三、FD优化 一、FD报错 App在运行中记录报错如下&#xff0c;FD_SET&#xff0c;这个问题大概是文件描述符&#xff08;File Descriptor&#xff0c;简称FD&#xff09;超过了最大…

首款会员制区块链 Geist 介绍

今天&#xff0c;Pixelcraft Studios 很高兴地宣布即将推出 Geist&#xff0c;这是一个由 Base、Arbitrum、Alchemy 以及 Aavegotchi 支持的全新 L3。 Geist 之前的代号为 “Gotchichain”&#xff0c;是首个专为游戏打造的会员专用区块链。 为什么选择 Geist&#xff1f; …