STM32CubeMx HAL库使用硬件IIC读写AT24C02

介绍使用硬件IIC接口读写AT24C02,STM32自带硬件IIC,比较好用,没必要千篇一律的使用模拟IIC。作为一个IIC的使用例子,可以适当修改用于其他IIC接口设备通信控制。

一、测试环境

STM32F407+CubeMx(6.1.1)+MDK(5.34)+AT24C02

IIC Pin:PB8 PB9

CubeMx配置如下:

二、I2C驱动代码

CubeMx生成i2c.c i2c.h。读写使用HAL库的IIC操作接口:

/**
  * @brief  Write an amount of data in blocking mode to a specific memory address
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
  *                the configuration information for the specified I2C.
  * @param  DevAddress Target device address: The device 7 bits address value
  *         in datasheet must be shifted to the left before calling the interface
  * @param  MemAddress Internal memory address
  * @param  MemAddSize Size of internal memory address
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be sent
  * @param  Timeout Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);

/**
  * @brief  Read an amount of data in blocking mode from a specific memory address
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
  *                the configuration information for the specified I2C.
  * @param  DevAddress Target device address: The device 7 bits address value
  *         in datasheet must be shifted to the left before calling the interface
  * @param  MemAddress Internal memory address
  * @param  MemAddSize Size of internal memory address
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be sent
  * @param  Timeout Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);

三、AT24C02驱动代码

头文件:at24c02.h

代码里边写了一个测试用例的宏开关,测试阶段打开AT24CXX_TEST_ENABLE,配置需要测试的起始地址AT24CXX_TEST_ADDR和测试读写长度AT24CXX_TEST_SIZE,调用AT24C02_Test()进行测试,返回值表示读写出错的数据个数。

例如:

OS_msgPrintf("AT24C02_Test err = %d\r\n",AT24C02_Test());  

打印:AT24C02_Test err = 0

表示指定测试地址和长度读写成功。

/*
  ******************************************************************************
  * File Name          : at24c02.h
  * Description        : this code is used for at24c02 application
  * Author             : JackWang
  * Date               : 2019-05-07
  ******************************************************************************
*/

#ifndef __AT24C02_H
#define __AT24C02_H

#ifdef __cplusplus
 extern "C" {
#endif

/*! -------------------------------------------------------------------------- */
/*! Include headers */
#include <stdint.h>

#define AT24CXX_TEST_ENABLE     0

/*! -------------------------------------------------------------------------- */
/*! Public functions prototype */
int AT24C02_write(uint8_t addr, uint8_t* dataPtr, uint16_t dataSize);
int AT24C02_read (uint8_t addr, uint8_t* dataPtr, uint16_t dataSize);

#if (1 == AT24CXX_TEST_ENABLE)
/*! -------------------------------------------------------------------------- */
/*! Public test functions prototype */
#define AT24CXX_TEST_ADDR       39
#define AT24CXX_TEST_BUFF_SIZE  255
#define AT24CXX_TEST_SIZE       90

int AT24C02_Test(void);
#endif

#ifdef __cplusplus
}
#endif

#endif
/*! end of the file */

实现文件:at24c02.c

读写采用了扇区Page读写方式,可以给定任意有效地址和有效长度进行操作,方便应用层调用。

移植代码时注意头文件sysdelay.h换成自己的延时函数文件。主要是实现delayms。

/*
  ******************************************************************************
  * File Name          : at24c02.c
  * Description        : this code is used for at24c02 application
  * Author             : JackWang
  * Date               : 2019-05-07
  ******************************************************************************
*/

/*! -------------------------------------------------------------------------- */
/*! Include headers */
#include "at24c02.h"
#include "sysdelay.h"
#include "i2c.h"

/*! -------------------------------------------------------------------------- */
/*! Private macros define */
#define AT24CXX_Write_ADDR 0xA0
#define AT24CXX_Read_ADDR  0xA1
#define AT24CXX_MAX_SIZE   256
#define AT24CXX_PAGE_SIZE  8
#define AT24CXX_PAGE_TOTAL (AT24CXX_MAX_SIZE/AT24CXX_PAGE_SIZE)

/*! -------------------------------------------------------------------------- */
/*! Public functions list */
int AT24C02_write(uint8_t addr, uint8_t* dataPtr, uint16_t dataSize);
int AT24C02_read (uint8_t addr, uint8_t* dataPtr, uint16_t dataSize);

/*! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int 
AT24C02_write(uint8_t addr, uint8_t* dataPtr, uint16_t dataSize)
{
    if (0 == dataSize) { return -1; }
    
    int res = HAL_OK;
    
    int selectPage_idx  = addr % AT24CXX_PAGE_SIZE;
    int selectPage_rest = AT24CXX_PAGE_SIZE - selectPage_idx;
    
    if (dataSize <= selectPage_rest) {
        res = HAL_I2C_Mem_Write(&hi2c1, 
                                 AT24CXX_Write_ADDR, 
                                 addr,
                                 I2C_MEMADD_SIZE_8BIT, 
                                 dataPtr,
                                 dataSize,
                                 0xFF);
        
        if (HAL_OK != res) { return -1; }
        
        sysDelay_ms(10);
        
    } else {
    
        /*! 1 write selectPage rest*/
        res = HAL_I2C_Mem_Write(&hi2c1, 
                                 AT24CXX_Write_ADDR, 
                                 addr,
                                 I2C_MEMADD_SIZE_8BIT, 
                                 dataPtr,
                                 selectPage_rest,
                                 0xFF);
        
        if (HAL_OK != res) { return -1; }
        
        addr     += selectPage_rest;
        dataSize -= selectPage_rest;
        dataPtr  += selectPage_rest;
        
        sysDelay_ms(5);
        
        /*! 2 write nextPage full */
        int fullPage = dataSize/AT24CXX_PAGE_SIZE;
        for (int iPage = 0; iPage < fullPage; ++iPage) {
            res = HAL_I2C_Mem_Write(&hi2c1, 
                                     AT24CXX_Write_ADDR, 
                                     addr,
                                     I2C_MEMADD_SIZE_8BIT, 
                                     dataPtr,
                                     AT24CXX_PAGE_SIZE,
                                     0xFF);
            
            if (HAL_OK != res) { return -1; }
            
            sysDelay_ms(5);
            
            addr     += AT24CXX_PAGE_SIZE;
            dataSize -= AT24CXX_PAGE_SIZE;
            dataPtr  += AT24CXX_PAGE_SIZE;
        }
        
        /*! 3 write rest */
        if (0 != dataSize) {
            res = HAL_I2C_Mem_Write(&hi2c1, 
                                     AT24CXX_Write_ADDR, 
                                     addr,
                                     I2C_MEMADD_SIZE_8BIT, 
                                     dataPtr,
                                     dataSize,
                                     0xFF);
        
            if (HAL_OK != res) { return -1; }
            
            sysDelay_ms(5);
        }
    }
    
    return 0;
}

/*! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int 
AT24C02_read(uint8_t addr, uint8_t* dataPtr, uint16_t dataSize)
{
    int res = HAL_I2C_Mem_Read(&hi2c1,
                                AT24CXX_Read_ADDR,
                                addr,
                                I2C_MEMADD_SIZE_8BIT,
                                dataPtr,
                                dataSize,
                                0xFF);
    
    if (HAL_OK != res) { return -1; }
    
    return 0;
}

#if (1 == AT24CXX_TEST_ENABLE)
/*! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#include <string.h>
static uint8_t AT24CXX_testBuff[AT24CXX_TEST_BUFF_SIZE];

int 
AT24C02_Test(void)
{    
    for (int idx = 0; idx < AT24CXX_TEST_BUFF_SIZE; ++idx) {
        AT24CXX_testBuff[idx] = idx;
    }
    
    AT24C02_write(AT24CXX_TEST_ADDR, AT24CXX_testBuff+AT24CXX_TEST_ADDR, AT24CXX_TEST_SIZE);
    
    memset(AT24CXX_testBuff, 0, AT24CXX_TEST_BUFF_SIZE);
    
    AT24C02_read(AT24CXX_TEST_ADDR, AT24CXX_testBuff, AT24CXX_TEST_SIZE);  
    
    int err = 0;
    
    for (int idx = 0; idx < AT24CXX_TEST_SIZE; ++idx) {
        if ((AT24CXX_TEST_ADDR+idx) != AT24CXX_testBuff[idx]) err++;
    }
    
    return err;
    
}
#endif

总体上代码还算简洁,供大家参考使用。

 

  • 12
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
使用HAL库进行STM32IIC读写AT24C02时,你可以参考以下步骤: 1. 首先,你需要在你的工程中包含AT24CXX.c文件,并在代码中引用该文件。该文件中定义了一些常量和函数,用于初始化AT24CXX芯片、写入数据和读取数据等操作。 2. 在AT24CXX.c文件中,你可以看到定义了一些常量,如AT24C02的地址为255。这些常量可以根据你所使用的芯片型号进行修改。 3. 在AT24CXX.c文件中,还定义了一些函数,如AT24CXX_Init()用于初始化AT24CXX芯片,AT24CXX_Write()用于写入数据,AT24CXX_Read()用于读取数据,AT24CXX_Check()用于检查AT24CXX芯片是否正常工作。你可以根据需要调用这些函数来实现对AT24C02读写操作。 4. 在配置STM32的引脚时,你需要将IIC的引脚与AT24C02芯片的引脚相连接。具体的引脚配置可以参考AT24CXX.c文件中的注释。 5. 在配置串口时,你可以选择使用串口进行数据查看,以便调试和验证读写操作的结果。 6. 最后,根据你的需求选择适当的时钟频率,生成Keil工程代码。 综上所述,你可以使用HAL库的函数和AT24CXX.c文件中定义的函数来实现对AT24C02芯片的读写操作。 #### 引用[.reference_title] - *1* *3* [STM32 (基于HAL库) 硬件IIC读写任意AT24CXX芯片](https://blog.csdn.net/weixin_56565733/article/details/124401443)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32系列(HAL库)——F103C8T6通过IIC/I2C方式读写AT24C02—(EEPROM 存储模块)](https://blog.csdn.net/lwb450921/article/details/124394615)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值