找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 804|回复: 1
打印 上一主题 下一主题
收起左侧

求BL25CM1A驱动代码

[复制链接]
跳转到指定楼层
楼主
ID:958702 发表于 2024-12-25 14:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大佬们,有没有BL25CM1A这个EEPROM的驱动代码呀,单片机是STM32F407的
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:404160 发表于 2024-12-25 23:15 | 只看该作者
以下是一个简单的STM32F407单片机对BL25CM1A EEPROM的驱动代码示例,使用I2C通信协议:

```c
#include "stm32f4xx.h"
#include "stm32f4xx_i2c.h"

// 定义EEPROM的I2C地址
#define EEPROM_ADDR 0xA0  

// 初始化I2C1
void I2C1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    I2C_InitTypeDef I2C_InitStruct;

    // 使能I2C1和GPIO的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    // 配置SCL和SDA引脚
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    // 将引脚连接到I2C1的AF功能
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);

    // 配置I2C1
    I2C_InitStruct.I2C_ClockSpeed = 100000;
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStruct.I2c_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStruct.I2C_OwnAddress1 = 0x00;
    I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C1, &I2C_InitStruct);

    // 使能I2C1
    I2C_Cmd(I2C1, ENABLE);
}

// 向EEPROM写一个字节
void EEPROM_WriteByte(uint16_t address, uint8_t data)
{
    // 等待I2C空闲
    while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

    // 发送起始条件
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    // 发送EEPROM地址和写命令
    I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    // 发送高字节地址
    I2C_SendData(I2C1, (address >> 8) & 0xFF);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    // 发送低字节地址
    I2C_SendData(I2C1, address & 0xFF);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    // 发送数据
    I2C_SendData(I2C1, data);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    // 发送停止条件
    I2C_GenerateSTOP(I2C1, ENABLE);
}

// 从EEPROM读一个字节
uint8_t EEPROM_ReadByte(uint16_t address)
{
    uint8_t data = 0;

    // 等待I2C空闲
    while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

    // 发送起始条件
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    // 发送EEPROM地址和写命令
    I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    // 发送高字节地址
    I2C_SendData(I2C1, (address >> 8) & 0xFF);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    // 发送低字节地址
    I2C_SendData(I2C1, address & 0xFF);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    // 重新发送起始条件
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    // 发送EEPROM地址和读命令
    I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    // 读取数据
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
    data = I2C_ReceiveData(I2C1);

    // 发送停止条件
    I2C_GenerateSTOP(I2C1, ENABLE);

    return data;
}
```

**代码解释**:
1. **I2C1_Init函数**:
    - 首先使能I2C1和相应GPIO的时钟。
    - 配置I2C1的SCL和SDA引脚(这里使用GPIOB的引脚6和7)为复用功能、开漏输出、上拉电阻。
    - 将这些引脚连接到I2C1的复用功能。
    - 配置I2C1的参数,如时钟速度为100kHz,I2C模式、占空比、自身地址、ACK使能等。
    - 最后使能I2C1。
2. **EEPROM_WriteByte函数**:
    - 等待I2C总线空闲。
    - 发送起始条件,等待主模式选择事件。
    - 发送EEPROM地址和写命令,等待发送器模式选择事件。
    - 发送要写入数据的高字节地址,等待字节传输完成事件。
    - 发送低字节地址,等待字节传输完成事件。
    - 发送要存储的数据,等待字节传输完成事件。
    - 发送停止条件结束传输。
3. **EEPROM_ReadByte函数**:
    - 等待I2C总线空闲。
    - 发送起始条件,等待主模式选择事件。
    - 发送EEPROM地址和写命令,等待发送器模式选择事件。
    - 发送要读取数据的高字节地址,等待字节传输完成事件。
    - 发送低字节地址,等待字节传输完成事件。
    - 重新发送起始条件,等待主模式选择事件。
    - 发送EEPROM地址和读命令,等待接收器模式选择事件。
    - 读取数据,等待字节接收事件。
    - 发送停止条件结束传输。


**使用说明**:
- 在使用这些函数之前,确保已经正确配置了STM32F407的系统时钟。
- 在`main`函数中调用`I2C1_Init()`来初始化I2C1。
- 使用`EEPROM_WriteByte(uint16_t address, uint8_t data)`函数将一个字节数据写入EEPROM的指定地址,例如:`EEPROM_WriteByte(0x0000, 0x55);`。
- 使用`EEPROM_ReadByte(uint16_t address)`函数从EEPROM的指定地址读取一个字节数据,例如:`uint8_t value = EEPROM_ReadByte(0x0000);`。


请注意,这只是一个基础的驱动代码示例,实际使用中可能需要根据BL25CM1A EEPROM的数据手册进行更细致的调整,比如处理不同的页写操作、块擦除操作,以及添加错误处理代码等。并且,不同的STM32开发环境可能需要调整头文件的包含和一些函数的调用方式,例如使用STM32CubeMX生成的代码可能会使用`HAL`库,而这里使用的是标准外设库。如果遇到问题,可以根据具体的开发环境和芯片手册进行调试和修改。

```

这个代码是使用C语言为STM32F407单片机生成的BL25CM1A EEPROM的驱动代码。首先,通过`I2C1_Init`函数初始化I2C1接口,包括使能相关时钟,配置I2C引脚和I2C的参数。`EEPROM_WriteByte`函数用于向EEPROM写入一个字节的数据,它遵循I2C协议的传输步骤,先等待I2C总线空闲,发送起始条件,发送EEPROM地址和写命令,接着发送要写入数据的地址,最后发送数据并发送停止条件。`EEPROM_ReadByte`函数用于从EEPROM读取一个字节的数据,其流程和写操作类似,但在发送地址后需要重新发送起始条件并发送读命令,然后读取数据。最后给出了代码的使用说明,指导用户如何调用这些函数进行数据的读写操作,同时也提醒用户根据具体情况可能需要进一步完善和调整代码。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表