驱动所有外设
This commit is contained in:
225
STM32F103C8T6/Drivers/BSP/AT24C02/at24c02.c
Normal file
225
STM32F103C8T6/Drivers/BSP/AT24C02/at24c02.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 模块名称:AT24C02 EEPROM 驱动
|
||||
* 模块功能:提供AT24C02的读写操作接口,基于STM32 HAL I2C
|
||||
* 适用平台:STM32F103C8T6
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-07-14
|
||||
* 修改记录:
|
||||
* 2026-07-14 王建锋 创建初始版本
|
||||
*/
|
||||
|
||||
#include "at24c02.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* 引用CubeMX生成的I2C句柄 */
|
||||
extern I2C_HandleTypeDef hi2c1;
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02字节写入
|
||||
* 入口参数:addr - 目标地址(0~255)
|
||||
* data - 要写入的数据
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:先发送写命令,再等待内部写周期完成
|
||||
*/
|
||||
int at24c02_write_byte(uint8_t addr, uint8_t data)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
HAL_StatusTypeDef hal_ret;
|
||||
|
||||
buf[0] = addr;
|
||||
buf[1] = data;
|
||||
|
||||
hal_ret = HAL_I2C_Master_Transmit(&hi2c1, AT24C02_ADDR_WRITE,
|
||||
buf, 2, AT24C02_I2C_TIMEOUT);
|
||||
if (hal_ret != HAL_OK) {
|
||||
return AT24C02_ERR_I2C;
|
||||
}
|
||||
|
||||
/* 等待内部写周期完成 */
|
||||
return at24c02_wait_ready();
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02随机读取
|
||||
* 入口参数:addr - 目标地址(0~255)
|
||||
* 返回值:>=0=读取的数据,负值=错误码
|
||||
* 函数说明:假写操作设定地址,再重新发送读命令读取
|
||||
*/
|
||||
int at24c02_read_byte(uint8_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
HAL_StatusTypeDef hal_ret;
|
||||
|
||||
/* 假写:发送设备地址 + 字地址 */
|
||||
hal_ret = HAL_I2C_Master_Transmit(&hi2c1, AT24C02_ADDR_WRITE,
|
||||
&addr, 1, AT24C02_I2C_TIMEOUT);
|
||||
if (hal_ret != HAL_OK) {
|
||||
return AT24C02_ERR_I2C;
|
||||
}
|
||||
|
||||
/* 重发起始条件 + 读 */
|
||||
hal_ret = HAL_I2C_Master_Receive(&hi2c1, AT24C02_ADDR_READ,
|
||||
&data, 1, AT24C02_I2C_TIMEOUT);
|
||||
if (hal_ret != HAL_OK) {
|
||||
return AT24C02_ERR_I2C;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02页写入
|
||||
* 入口参数:addr - 起始地址(0~255)
|
||||
* p_data - 数据缓冲区指针
|
||||
* len - 写入长度(≤8)
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:页写入,自动等待写周期完成
|
||||
*/
|
||||
int at24c02_write_page(uint8_t addr, const uint8_t *p_data, uint8_t len)
|
||||
{
|
||||
uint8_t buf[AT24C02_PAGE_SIZE + 1];
|
||||
HAL_StatusTypeDef hal_ret;
|
||||
uint8_t i;
|
||||
|
||||
/* 参数校验 */
|
||||
if ((p_data == NULL) || (len == 0) || (len > AT24C02_PAGE_SIZE)) {
|
||||
return AT24C02_ERR_PARAM;
|
||||
}
|
||||
if (addr + len > AT24C02_SIZE) {
|
||||
return AT24C02_ERR_PARAM;
|
||||
}
|
||||
|
||||
buf[0] = addr;
|
||||
for (i = 0; i < len; i++) {
|
||||
buf[i + 1] = p_data[i];
|
||||
}
|
||||
|
||||
hal_ret = HAL_I2C_Master_Transmit(&hi2c1, AT24C02_ADDR_WRITE,
|
||||
buf, len + 1, AT24C02_I2C_TIMEOUT);
|
||||
if (hal_ret != HAL_OK) {
|
||||
return AT24C02_ERR_I2C;
|
||||
}
|
||||
|
||||
/* 等待内部写周期完成 */
|
||||
return at24c02_wait_ready();
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02连续写入(跨页自动拆分)
|
||||
* 入口参数:addr - 起始地址(0~255)
|
||||
* p_data - 数据缓冲区指针
|
||||
* len - 写入长度
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:自动处理跨页边界,逐页写入
|
||||
*/
|
||||
int at24c02_write_buf(uint8_t addr, const uint8_t *p_data, uint16_t len)
|
||||
{
|
||||
uint8_t page_remaining;
|
||||
int ret;
|
||||
|
||||
if ((p_data == NULL) || (len == 0)) {
|
||||
return AT24C02_ERR_PARAM;
|
||||
}
|
||||
if (addr + len > AT24C02_SIZE) {
|
||||
return AT24C02_ERR_PARAM;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
/* 当前页剩余空间 */
|
||||
page_remaining = AT24C02_PAGE_SIZE - (addr % AT24C02_PAGE_SIZE);
|
||||
if (page_remaining > len) {
|
||||
page_remaining = (uint8_t)len;
|
||||
}
|
||||
|
||||
ret = at24c02_write_page(addr, p_data, page_remaining);
|
||||
if (ret != AT24C02_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
addr += page_remaining;
|
||||
p_data += page_remaining;
|
||||
len -= page_remaining;
|
||||
}
|
||||
|
||||
return AT24C02_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02连续读取
|
||||
* 入口参数:addr - 起始地址(0~255)
|
||||
* p_buf - 接收缓冲区指针
|
||||
* len - 读取长度
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:从指定地址开始顺序读取多个字节
|
||||
*/
|
||||
int at24c02_read_buf(uint8_t addr, uint8_t *p_buf, uint16_t len)
|
||||
{
|
||||
HAL_StatusTypeDef hal_ret;
|
||||
|
||||
if ((p_buf == NULL) || (len == 0)) {
|
||||
return AT24C02_ERR_PARAM;
|
||||
}
|
||||
if (addr + len > AT24C02_SIZE) {
|
||||
return AT24C02_ERR_PARAM;
|
||||
}
|
||||
|
||||
/* 假写:设定读起始地址 */
|
||||
hal_ret = HAL_I2C_Master_Transmit(&hi2c1, AT24C02_ADDR_WRITE,
|
||||
&addr, 1, AT24C02_I2C_TIMEOUT);
|
||||
if (hal_ret != HAL_OK) {
|
||||
return AT24C02_ERR_I2C;
|
||||
}
|
||||
|
||||
/* 顺序读 */
|
||||
hal_ret = HAL_I2C_Master_Receive(&hi2c1, AT24C02_ADDR_READ,
|
||||
p_buf, len, AT24C02_I2C_TIMEOUT);
|
||||
if (hal_ret != HAL_OK) {
|
||||
return AT24C02_ERR_I2C;
|
||||
}
|
||||
|
||||
return AT24C02_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:检测AT24C02设备是否存在
|
||||
* 入口参数:无
|
||||
* 返回值: 0=检测到设备,-1=未响应
|
||||
* 函数说明:通过I2C发送设备地址,检查是否有ACK应答
|
||||
*/
|
||||
int at24c02_scan(void)
|
||||
{
|
||||
HAL_StatusTypeDef hal_ret;
|
||||
|
||||
hal_ret = HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_ADDR_WRITE,
|
||||
3, AT24C02_I2C_TIMEOUT);
|
||||
if (hal_ret != HAL_OK) {
|
||||
printf("AT24C02: no device found\r\n");
|
||||
return AT24C02_ERR_DEVICE;
|
||||
}
|
||||
|
||||
printf("AT24C02: device detected\r\n");
|
||||
return AT24C02_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:等待内部写周期完成(应答查询)
|
||||
* 入口参数:无
|
||||
* 返回值: 0=完成,-3=超时
|
||||
* 函数说明:发送设备地址(写模式),直到器件应答
|
||||
*/
|
||||
int at24c02_wait_ready(void)
|
||||
{
|
||||
HAL_StatusTypeDef hal_ret;
|
||||
uint16_t trials = 50;
|
||||
|
||||
while (trials--) {
|
||||
hal_ret = HAL_I2C_IsDeviceReady(&hi2c1, AT24C02_ADDR_WRITE,
|
||||
1, 1);
|
||||
if (hal_ret == HAL_OK) {
|
||||
return AT24C02_OK;
|
||||
}
|
||||
HAL_Delay(1);
|
||||
}
|
||||
|
||||
return AT24C02_ERR_TIMEOUT;
|
||||
}
|
||||
102
STM32F103C8T6/Drivers/BSP/AT24C02/at24c02.h
Normal file
102
STM32F103C8T6/Drivers/BSP/AT24C02/at24c02.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 模块名称:AT24C02 EEPROM 驱动
|
||||
* 模块功能:提供AT24C02的读写操作接口,基于STM32 HAL I2C
|
||||
* 适用平台:STM32F103C8T6
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-07-14
|
||||
* 修改记录:
|
||||
* 2026-07-14 王建锋 创建初始版本
|
||||
*/
|
||||
|
||||
#ifndef __AT24C02_H
|
||||
#define __AT24C02_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/* AT24C02 器件参数 */
|
||||
#define AT24C02_ADDR_WRITE 0xA0 /* 写设备地址 (A2=A1=A0=GND) */
|
||||
#define AT24C02_ADDR_READ 0xA1 /* 读设备地址 */
|
||||
#define AT24C02_SIZE 256 /* 总字节数 */
|
||||
#define AT24C02_PAGE_SIZE 8 /* 页大小 */
|
||||
#define AT24C02_PAGE_NUM 32 /* 总页数 */
|
||||
#define AT24C02_I2C_TIMEOUT 100 /* I2C 通讯超时 (ms) */
|
||||
|
||||
/* AT24C02 操作返回值 */
|
||||
#define AT24C02_OK 0 /* 操作成功 */
|
||||
#define AT24C02_ERR_DEVICE -1 /* 设备未响应 */
|
||||
#define AT24C02_ERR_I2C -2 /* I2C通讯错误 */
|
||||
#define AT24C02_ERR_TIMEOUT -3 /* 写周期超时 */
|
||||
#define AT24C02_ERR_PARAM -4 /* 参数错误 */
|
||||
|
||||
/*
|
||||
* 函数功能:检测AT24C02设备是否存在
|
||||
* 入口参数:无
|
||||
* 返回值: 0=检测到设备,-1=未响应
|
||||
* 函数说明:通过I2C发送设备地址,检查是否有ACK应答
|
||||
*/
|
||||
int at24c02_scan(void);
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02字节写入
|
||||
* 入口参数:addr - 目标地址(0~255)
|
||||
* data - 要写入的数据
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:先发送写命令,再等待内部写周期完成
|
||||
*/
|
||||
int at24c02_write_byte(uint8_t addr, uint8_t data);
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02随机读取
|
||||
* 入口参数:addr - 目标地址(0~255)
|
||||
* 返回值:>=0=读取的数据,负值=错误码
|
||||
* 函数说明:假写操作设定地址,再重新发送读命令读取
|
||||
*/
|
||||
int at24c02_read_byte(uint8_t addr);
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02页写入(不超过页边界)
|
||||
* 入口参数:addr - 起始地址(0~255)
|
||||
* p_data - 数据缓冲区指针
|
||||
* len - 写入长度(≤8)
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:页写入,自动等待写周期完成
|
||||
*/
|
||||
int at24c02_write_page(uint8_t addr, const uint8_t *p_data, uint8_t len);
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02连续写入(跨页自动拆分)
|
||||
* 入口参数:addr - 起始地址(0~255)
|
||||
* p_data - 数据缓冲区指针
|
||||
* len - 写入长度
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:自动处理跨页边界,逐页写入
|
||||
*/
|
||||
int at24c02_write_buf(uint8_t addr, const uint8_t *p_data, uint16_t len);
|
||||
|
||||
/*
|
||||
* 函数功能:AT24C02连续读取
|
||||
* 入口参数:addr - 起始地址(0~255)
|
||||
* p_buf - 接收缓冲区指针
|
||||
* len - 读取长度
|
||||
* 返回值: 0=成功,负值=错误码
|
||||
* 函数说明:从指定地址开始顺序读取多个字节
|
||||
*/
|
||||
int at24c02_read_buf(uint8_t addr, uint8_t *p_buf, uint16_t len);
|
||||
|
||||
/*
|
||||
* 函数功能:等待内部写周期完成(应答查询)
|
||||
* 入口参数:无
|
||||
* 返回值: 0=完成,-3=超时
|
||||
* 函数说明:发送设备地址(写模式),直到器件应答
|
||||
*/
|
||||
int at24c02_wait_ready(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __AT24C02_H */
|
||||
Reference in New Issue
Block a user