基于MC9S12G128的I2C驱动M24M02 EEPROM的实现方案

简介: 基于MC9S12G128的I2C驱动M24M02 EEPROM的实现方案

一、硬件连接配置

MC9S12G128        M24M02
------------      --------
SCL  → SCL (PB2)
SDA  → SDA (PB3)
GND  → GND
VCC  → 3.3V
WP   → VCC (写保护关闭)

二、关键寄存器配置

#include "derivative.h"  // 包含MC9S12G128寄存器定义

#define I2C_BASE_ADDR  0x00  // I2C模块基地址
#define FCLKDIV        (*(volatile unsigned char *)0x0000)  // 时钟分频寄存器
#define FSTAT          (*(volatile unsigned char *)0x0001)  // 状态寄存器
#define FCCOBIX        (*(volatile unsigned char *)0x0002)  // 命令/地址指针
#define FCCOB          (*(volatile unsigned short *)0x0003) // 数据缓冲区

// 设备地址配置(7位地址格式)
#define M24M02_ADDR    0xA0  // A17=0, A16=0, E2=0
#define MEM_ADDR_SIZE  2      // 16位内存地址

三、I2C初始化函数

void I2C_Init() {
   
    // 设置I2C时钟分频(总线频率=总线时钟/(2*(FCLKDIV+1)))
    FCLKDIV = 0x17;  // 24MHz总线时钟 → 100kHz I2C

    // 清除状态标志
    FSTAT = 0x00;

    // 配置I2C为主模式,启用ACK
    // (具体配置需参考MC9S12G128数据手册的I2C章节)
}

四、EEPROM写操作

void EEPROM_Write(uint16_t memAddr, uint8_t *data, uint16_t size) {
   
    uint16_t pageAddr = memAddr & 0xFF00;  // 页地址高位
    uint16_t offset = memAddr & 0x00FF;    // 页内偏移

    while(size > 0) {
   
        uint16_t writeSize = (size > 256) ? 256 : size;  // 单页最大256字节

        // 发送起始条件+设备地址+写命令
        I2C_Start();
        I2C_Write(M24M02_ADDR << 1 | 0);  // 写模式

        // 发送内存地址(高字节在前)
        I2C_Write((pageAddr >> 8) & 0xFF);
        I2C_Write(pageAddr & 0xFF);

        // 写入数据
        for(uint16_t i=0; i<writeSize; i++) {
   
            I2C_Write(data[offset + i]);
        }

        I2C_Stop();

        // 等待写入完成(需根据时序添加延时)
        Delay_ms(5);  // M24M02写入时间≤5ms

        // 更新地址和剩余数据
        size -= writeSize;
        memAddr += writeSize;
        pageAddr += (offset + writeSize) / 256;
        offset = (offset + writeSize) % 256;
    }
}

五、EEPROM读操作

void EEPROM_Read(uint16_t memAddr, uint8_t *buffer, uint16_t size) {
   
    uint16_t pageAddr = memAddr & 0xFF00;
    uint16_t offset = memAddr & 0x00FF;

    // 发送起始条件+设备地址+写命令(发送内存地址)
    I2C_Start();
    I2C_Write(M24M02_ADDR << 1 | 0);

    // 发送内存地址
    I2C_Write((pageAddr >> 8) & 0xFF);
    I2C_Write(pageAddr & 0xFF);

    // 重新发送起始条件+设备地址+读命令
    I2C_Start();
    I2C_Write((M24M02_ADDR << 1) | 1);

    // 读取数据
    for(uint16_t i=0; i<size; i++) {
   
        buffer[i] = I2C_Read(i == size-1);  // 最后一字节发送NACK
    }

    I2C_Stop();
}

六、辅助函数实现

// I2C起始条件
void I2C_Start() {
   
    while(!IBSR_IBIF);  // 等待总线空闲
    IBSR_IBIF = 1;      // 清除中断标志
    IBDR = 0xFF;        // 拉低SDA启动信号
    while(IBSR_IBAL);   // 等待SDA拉低
}

// I2C停止条件
void I2C_Stop() {
   
    while(!IBSR_IBIF);
    IBSR_IBIF = 1;
    IBDR = 0xFF;        // 拉高SDA
    while(IBSR_IBAL);
}

// I2C写字节
uint8_t I2C_Write(uint8_t data) {
   
    while(!IBSR_IBIF);
    IBSR_IBIF = 1;
    IBDR = data;
    while(IBSR_IBAL);
    return IBSR_IBT;    // 返回ACK状态
}

// I2C读字节
uint8_t I2C_Read(uint8_t ack) {
   
    while(!IBSR_IBIF);
    IBSR_IBIF = 1;
    IBSR_IBR = ack;     // 设置ACK/NACK
    while(IBSR_IBAL);
    return IBDR;
}

参考代码 基于9S12G128的I2C驱动并含有EEPROM的M24M02的存储器读写程序 www.youwenfan.com/contentalh/57243.html

七、完整工程结构

M24M02_Driver/
├── Src/
│   ├── main.c
│   ├── i2c.c
│   └── eeprom.c
├── Inc/
│   ├── i2c.h
│   └── eeprom.h
├── Libs/
│   └── MC9S12G128_Driver/
└── Project/
    ├── .project
    └── .ccsproject

八、扩展功能实现

  1. 页写入保护

    void EEPROM_LockPage(uint16_t pageAddr) {
         
        uint8_t data[3] = {
         0x00, (pageAddr>>8)&0xFF, pageAddr&0xFF};
        EEPROM_Write(0x0000, data, 3);  // 写入页锁定位
    }
    
  2. CRC校验功能

    uint16_t EEPROM_CalculateCRC(uint16_t addr, uint16_t size) {
         
        uint16_t crc = 0xFFFF;
        while(size--) {
         
            crc ^= (uint16_t)(*buffer++) << 8;
            for(uint8_t i=0; i<8; i++) {
         
                crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : crc << 1;
            }
        }
        return crc;
    }
    
目录
相关文章
|
8月前
|
人工智能 安全 API
龙虾AI🦞OpenClaw保姆级实战手册:阿里云/本地部署步骤+百炼Coding Plan API配置安全使用避坑指南
2026年开年,开源AI智能体OpenClaw因红色龙虾图标被网友亲切称为「龙虾」,迅速在科技圈和币圈掀起热潮,其GitHub星标数狂飙至21.8万+,跻身总榜第14位,成为现象级的AI工具。这款被定义为「私人AI小秘书」的智能体,打破了传统AI助手仅能「回答问题」的局限,可无缝对接微信、飞书、Telegram等全平台通信工具,支持语音对话与实时面板操控,真正实现了「指令下达,落地执行」的核心能力。但随着工业和信息化部网络安全威胁和漏洞信息共享平台发出安全预警,以及人民日报的温馨提醒,如何正确使用OpenClaw、规避安全风险,同时完成阿里云与本地多系统的部署配置
1396 17
|
4月前
|
人工智能 安全 测试技术
VS Code 使用 Codex 教程:从安装到配置,一篇讲清楚
宇哥带你零基础玩转VS Code+Codex!本教程手把手教你配置API、接入中转服务、分析项目、修复Bug、生成接口与重构代码,安全高效提升开发效率。(238字)
5530 2
VS Code 使用 Codex 教程:从安装到配置,一篇讲清楚
|
3月前
|
缓存 JavaScript 安全
Claude Desktop 国内安装教程(Windows,2026)
官网Claude安装失败?因引导器需从被墙域名下载MSIX包。推荐使用开源Claude Desktop安装器:自动多源回退下载、SHA256校验、静默安装、补全Node.js与claude-code组件、创建快捷方式,全程离线可用,安全可靠。(239字)
14463 6
|
JavaScript 前端开发 测试技术
如何判断网站加载速度是否得到优化?
如何判断网站加载速度是否得到优化?
1455 155
|
Kubernetes 安全 虚拟化
VMware Fusion 13.6.3 发布下载,现在完全免费无论个人还是商业用途
VMware Fusion 13.6.3 发布下载,现在完全免费无论个人还是商业用途
30978 10
VMware Fusion 13.6.3 发布下载,现在完全免费无论个人还是商业用途
|
缓存 网络协议
Jmeter如何对UDP协议进行测试?
`jmeter-plugins`是JMeter的插件管理器,用于管理和组织所有插件。访问[官网](https://jmeter-plugins.org/install/Install/)下载并放置于`lib/ext`目录下,重启JMeter后可在“选项”中看到插件管理器。
802 1
Jmeter如何对UDP协议进行测试?
|
Java Linux 开发者
linux 查看java的安装路径
本指南详细介绍Java环境的安装验证与配置方法,包括检查Java版本、确认环境变量JAVA_HOME是否正确配置,以及通过which和readlink命令手动定位Java安装路径。同时提供系统级环境变量配置步骤,并给出多版本管理建议。适用于Linux系统用户,特别是需要在服务器或Docker容器中部署Java环境的开发者。注意操作时需具备相应权限,确保路径设置准确无误。
|
存储 数据管理 数据处理
处理STM32 DMA方式下的HAL_UART_ERROR_ORE错误
通过正确配置UART和DMA、实现有效的错误处理回调函数以及优化数据处理和缓冲区管理,可以有效处理STM32中DMA方式下的 `HAL_UART_ERROR_ORE`错误。这些方法确保了数据的高效传输和处理,避免了因数据溢出导致的通信中断和数据丢失。希望这些解决方案能够帮助您在实际应用中更好地应对和解决此类问题。
3173 0
|
机器人 Linux 开发工具
小白必看!入门嵌入式你需要了解这些!
【9月更文挑战第23天】在科技迅速发展的今天,嵌入式系统已广泛应用,覆盖了从智能家居到工业自动化等多个领域。本文将向你介绍嵌入式系统的基础概念,其特点,应用范围,并指导你如何掌握必要的知识和技能,包括电路基础、C语言编程、微处理器架构等,以及推荐的学习路径与方法。对于初学者来说,这是一份不错的指南。
1648 1
|
内存技术 存储 Android开发
MCU最小系统电路设计(以STM32F103C8T6为例)-3
MCU最小系统电路设计(以STM32F103C8T6为例)
MCU最小系统电路设计(以STM32F103C8T6为例)-3