I2C系列(三):软件模拟I2C读写24C02

目录

一.目标

二.硬件简述

2.1 24C02硬件参数

2.2 RS-485简述

三.控制命令定义

四.C代码

4.1 I2C基础时序模拟

4.1.1 引脚初始化

4.1.2 延时函数

4.1.3 起始信号模拟

4.1.4 停止信号模拟

4.1.5 应答信号模拟

4.1.6 写一个字节数据

4.1.7 读一个字节数据

4.2 I2C读写数据

4.2.1 向任意地址写单字节数据

4.2.2 从任意地址读单字节数据

4.2.3 写n字节数据到任意地址

4.2.4 从任意地址读n字节数据

4.3 串口中断服务函数

4.3.1 接收中断处理函数

4.3.2 发送中断处理函数

4.4 宏定义和声明

4.5 主处理函数main

五.测试结果


一.目标

        PC 端的串口调试软件通过 RS-485 与单片机通信,控制单片机利用软件模拟 I2C 总线对 EEPROM(24C02) 进行任意读写。 

二.硬件简述

2.1 24C02硬件参数

        24C02器件地址为0x50,存储容量为256字节,存储单元地址位数为8。地址发送方法如下图所示。

2.2 RS-485简述

        在工业控制领域,传输距离越长,要求抗干扰能力也越强。由于 RS-232 无法消除共模干扰,且传输距离只有 15m 左右,无法满足要求。
        工业标准组织提出了 RS-485 接口标准。 RS-485 标准采用差分信号传输方式,因此具有很强的抗共模干扰能力。 RS-485 接口芯片 SP485E 的封装及引脚说明如下图 1。

        RS-485 的逻辑电平为:

①当 A 的电位比 B 高 200mV 以上时, 为逻辑 1;

②当 B 的电位比 A 电位高200mA 以上时为逻辑 0,传输距离可达 1200m。由于是差分传输,因此无需公共地,在 RS-485 总线上仅需连接两根线 A 和 B。
       单片机与 RS-485 接口芯片的电路连接图如下图 2。

三.控制命令定义

        定义如下命令:

①c——串口接收数据函数初始化
②s——单片机将接收到的数据发送到串口调试终端显示,以确认单片机是否已正确接收数据
③w——将接收缓冲区 wbuf 中的数据写入 EEPROM 中
④r——将刚才写入 EEPROM 中的数据读出到缓冲区 rbuf 中,并发送到串口调试终端显示

四.C代码

        本代码注重功能实现,以期达到理解I2C协议和24C02读写方法的目的。实际项目还须考虑代码质量,如可读性、可维护性等。

4.1 I2C基础时序模拟

4.1.1 引脚初始化

void i2cinit(void)
{
	sdaout;/*引脚输出模式*/
	sclout;
	sda = 1; /*释放总线*/
	scl = 1;
}

4.1.2 延时函数

1.SCL 时序控制延时函数

        78K0指令的最短时钟周期为2个,一条NOP指令即为2个时钟周期,若使用内部8MHz时钟,则执行一条NOP指令需0.25us。

void delay(void)
{
	UCHAR i;
	for(i = 0;i < NOP_num;i++)
		NOP();
}

2.长延时函数

void delay_long(UINT a)
{
	UINT i,j;
	for(i = 0;i < a;i++)
	    for(j = 0;j < 100;j++);
}

4.1.3 起始信号模拟

        SCL 线为高电平期间, SDA 线由高电平向低电平的变化表示起始信号。

void i2cstart(void)
{
	sdaout;	
	sclout;
	/*1.初始化SDA为高电平:在SCL低电平期间拉高SDA*/
	scl = 0;
	delay();
	sda = 1;
	delay();
	
	/*2.模拟一个起始信号*/
	scl = 1;
	delay();
	sda = 0;
	delay();
}

4.1.4 停止信号模拟

        SCL 线为高电平期间, SDA 线由低电平向高电平的变化表示终止信号。

void i2cstop(void)
{
	sdaout;
	sclout;
	
	/*1.初始化SDA为低电平:在SCL低电平期间拉低SDA*/
	scl=0;
	delay();
	sda=0; 
	delay();
	
	/*2.模拟一个停止信号*/
	scl=1;
	delay();
	sda=1;
	delay();
} 

4.1.5 应答信号模拟

        每一个字节必须保证是 8 位长度。数据传送时,先传送最高位(MSB),每一个被传送的
字节后面都必须跟随一位应答位(即一帧共有 9 位)。

     &

03-13
### 关于24C02的相关IT信息 #### 1. 设备简介 24C02 是一种常见的 EEPROM 存储芯片,具有 I²C 接口。它支持的标准模式速度为 100 kHz 和快速模式下的 400 kHz 数据传输速率[^3]。 #### 2. Linux 驱动程序实现 在 Linux 系统中,为了使能对 24C02 的访问功能,通常通过定义 `i2c_driver` 结构体来完成驱动注册。以下是典型的结构体填充方式: ```c static const struct i2c_device_id FM24C02A_id[] = { { "FM24C02A", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, FM24C02A_id); static struct i2c_driver FM24C02A_driver = { .driver = { .name = "FM24C02A", }, .probe = FM24C02A_probe, .remove = FM24C02A_remove, .id_table = FM24C02A_id, // 这里用于设备匹配 }; ``` 上述代码片段展示了如何创建一个静态常量数组 `FM24C02A_id` 来描述设备 ID 表格,并将其赋值给 `i2c_driver` 中的 `.id_table` 字段以便进行设备匹配[^1]。 #### 3. STM32 HAL 库中的 I²C 实现 对于基于 STM32 微控制器的应用场景,可以借助 HAL (Hardware Abstraction Layer) 库简化硬件操作流程。例如,向 24C02 写入数据可以通过调用以下函数实现: ```c HAL_StatusTypeDef status; uint8_t data_to_write = 0xFF; // 假设要写入的数据为 0xFF status = HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)(DEVICE_ADDRESS << 1), &data_to_write, sizeof(data_to_write), HAL_MAX_DELAY); if (status != HAL_OK) { // 错误处理逻辑 } ``` 此代码片段演示了如何使用 `HAL_I2C_Master_Transmit()` 函数发送单字节数据到目标地址 `(DEVICE_ADDRESS << 1)` 处[^2]。 #### 4. 使用 CubeMX 工具配置 I²C 功能 STM32CubeMX 提供了一种图形化界面工具帮助开发者轻松设置外设参数并生成初始项目框架文件。当涉及到具体型号如 STM32F407 芯片时,集成好的 I²C 控制器可以直接被启用而无需深入研究其内部工作原理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈工程师修炼日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值