HC32F4驱动AT24Cx系列

#include "HC32_i2c_24cxx.h"

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/
/* Define I2C unit used for the example */
#define I2C_UNIT                        (M4_I2C1)
/* Define E2PROM device address */
#define E2_ADDRESS                      (0x50u)
/* AT24C02 page length */
#define E2_PAGE_LEN                     (8u)
#define E2_MEM_ADR_LEN                  (1u)
/* Define test address for read and write */
#define DATA_TEST_ADDR                  (0x08u)
/* Define port and pin for SDA and SCL */
#define I2C_SCL_PORT                    (PortA)
#define I2C_SCL_PIN                     (Pin09)
#define I2C_SDA_PORT                    (PortA)
#define I2C_SDA_PIN                     (Pin08)
#define I2C_GPIO_SCL_FUNC               (Func_I2c1_Scl)
#define I2C_GPIO_SDA_FUNC               (Func_I2c1_Sda)

#define I2C_FCG_USE                     (PWC_FCG1_PERIPH_I2C1)

#define TIMEOUT                         (0x40000ul)


/**
 ******************************************************************************
 ** \brief  I2C memory write
 **
 ** \param  u8DevAddr             The slave address
 ** \param  u16MemAddr            The memory address
 ** \param  pu8Data               Pointer to the data buffer
 ** \param  u32Size               Data size
 ** \param  u32TimeOut            Time out count
 ** \retval en_result_t           Enumeration value:
 **         - Ok:                 Success
 **         - Error:              Receive NACK
 **         - ErrorTimeout:       Time out
 ******************************************************************************/
static en_result_t I2C_Mem_Write(uint16_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
    en_result_t enRet;
    uint16_t u16MemAddrTemp;
//    u16MemAddrTemp = ((u16MemAddr >> 8) & 0xFFul) + ((u16MemAddr << 8) & 0xFF00ul);
    u16MemAddrTemp = u16MemAddr;
    I2C_Cmd(I2C_UNIT, Enable);

    I2C_SoftwareResetCmd(I2C_UNIT, Enable);
    I2C_SoftwareResetCmd(I2C_UNIT, Disable);
    enRet = I2C_Start(I2C_UNIT,u32TimeOut);
    if(Ok == enRet)
    {
        enRet = I2C_TransAddr(I2C_UNIT, u8DevAddr, I2CDirTrans, u32TimeOut);

        if(Ok == enRet)
        {
            enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddrTemp, E2_MEM_ADR_LEN, u32TimeOut);
            if(Ok == enRet)
            {
                enRet = I2C_TransData(I2C_UNIT, pu8Data, u32Size, u32TimeOut);
            }
        }
    }

    I2C_Stop(I2C_UNIT,u32TimeOut);
    I2C_Cmd(I2C_UNIT, Disable);

    return enRet;
}

/**
 ******************************************************************************
 ** \brief  I2C memory read
 **
 ** \param  u8DevAddr             The slave address
 ** \param  u16MemAddr            The memory address
 ** \param  pu8Data               Pointer to the data buffer
 ** \param  u32Size               Data size
 ** \param  u32TimeOut            Time out count
 ** \retval en_result_t           Enumeration value:
 **         - Ok:                 Success
 **         - ErrorTimeout:       Time out
 ******************************************************************************/
static en_result_t I2C_Mem_Read(uint8_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
    en_result_t enRet;
    uint16_t u16MemAddrTemp;
//    u16MemAddrTemp =  ((u16MemAddr << 8) & 0xFF00ul) + ((u16MemAddr >> 8) & 0xFFul);
    u16MemAddrTemp = u16MemAddr;
    I2C_Cmd(I2C_UNIT, Enable);

    I2C_SoftwareResetCmd(I2C_UNIT, Enable);
    I2C_SoftwareResetCmd(I2C_UNIT, Disable);
    enRet = I2C_Start(I2C_UNIT,u32TimeOut);
    if(Ok == enRet)
    {
        enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirTrans, u32TimeOut);

        if(Ok == enRet)
        {
            enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddrTemp, E2_MEM_ADR_LEN, u32TimeOut);
            if(Ok == enRet)
            {
                enRet = I2C_Restart(I2C_UNIT,u32TimeOut);
                if(Ok == enRet)
                {
                    if(1ul == u32Size)
                    {
                        I2C_AckConfig(I2C_UNIT, I2c_NACK);
                    }

                    enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);
                    if(Ok == enRet)
                    {
                        enRet = I2C_MasterDataReceiveAndStop(I2C_UNIT, pu8Data, u32Size, u32TimeOut);
                    }

                    I2C_AckConfig(I2C_UNIT, I2c_ACK);
                }

            }
        }
    }

    if(Ok != enRet)
    {
        I2C_Stop(I2C_UNIT,u32TimeOut);
    }

    I2C_Cmd(I2C_UNIT, Disable);
    return enRet;
}

/**
 ******************************************************************************
 ** \brief  Initialize the I2C peripheral for e2prom
 ** \param  None
 ** \retval en_result_t           Enumeration value:
 **         - Ok:                 Success
 **         - ErrorTimeout:       Time out
 ******************************************************************************/
static en_result_t E2_Initialize(void)
{
    stc_i2c_init_t stcI2cInit;
    en_result_t enRet;
    float32_t fErr;

    I2C_DeInit(I2C_UNIT);

    MEM_ZERO_STRUCT(stcI2cInit);
    stcI2cInit.u32ClockDiv = I2C_CLK_DIV32;
    stcI2cInit.u32Baudrate = 100000ul;
    stcI2cInit.u32SclTime = 0ul;
    enRet = I2C_Init(I2C_UNIT, &stcI2cInit, &fErr);

    I2C_BusWaitCmd(I2C_UNIT, Enable);

    return enRet;
}

static void HC32_I2C_24CXX_Delay_us(uint8_t us)
{
	uint16_t i = 0;
	//通过示波器测量进行校准
	while(us--)
	{
		for(i=0;i<1200;i++);
	}
}

void HC32_I2C_24Cxx_INT(void)
{
    /* Initialize I2C port*/
    PORT_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_GPIO_SCL_FUNC, Disable);
    PORT_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_GPIO_SDA_FUNC, Disable);

    /* Enable I2C Peripheral*/
    PWC_Fcg1PeriphClockCmd(I2C_FCG_USE, Enable);
    /* Initialize I2C peripheral and enable function*/
    E2_Initialize();
    HC32_I2C_24CXX_Delay_us(200);
    HC32_I2C_24CXX_Delay_us(200);
}
    

   




uint8_t HC32_I2C_24CXX_READ_one_BYTE(uint16_t addr)
{
    uint8_t a[1] = {0};
    I2C_Mem_Read(E2_ADDRESS, addr, a, 1u, TIMEOUT);
    return a[0];
}

/*******************************************************************************
* 函 数 名         : HC32_I2C_24CXX_write_one_page
* 函数功能		   : 在AT24CXX指定页写入一页数据
* 输    入         : addr:写入数据的目的地址 
					 dat:要写入的数据
* 输    出         : 无
*******************************************************************************/
void HC32_I2C_24CXX_write_one_page(uint16_t addr, uint8_t *dat)
{
    I2C_Mem_Write(E2_ADDRESS, addr, dat, E2_PAGE_LEN, TIMEOUT);
	HC32_I2C_24CXX_Delay_us(200);
}
/*******************************************************************************
* 函 数 名         : HC32_I2C_24CXX_read_one_page
* 函数功能		   : 在AT24CXX指定页读一页数据
* 输    入         : addr:读数据的目的地址 
					 dat:要读的数据
* 输    出         : 无
*******************************************************************************/
void HC32_I2C_24CXX_read_one_page(uint16_t addr, uint8_t *dat)
{
    I2C_Mem_Read(E2_ADDRESS, addr, dat, E2_PAGE_LEN, TIMEOUT);
	HC32_I2C_24CXX_Delay_us(200);
}

/*******************************************************************************
* 函 数 名         :HC32_I2C_24CXX_write_bytes
* 函数功能		   : 在AT24CXX指定地址写入一段数据
* 输    入         : addr:写入数据的目的地址  
					 pdat:要写入的数据首地址
					 Len:数据长度
* 输    出         : 无
*******************************************************************************/
uint8_t tem[8] = {0};
void HC32_I2C_24CXX_write_bytes(uint16_t addr, uint8_t* pdat, uint8_t Len)
{
    uint8_t Temp[8];
	uint16_t pdat_id_S = addr % 8;
	uint8_t i, pages;
    if(pdat_id_S)
	{
		for(i = 0; i < pdat_id_S; ++i)
        {
            Temp[i] = HC32_I2C_24CXX_READ_one_BYTE(addr - pdat_id_S + i);
            HC32_I2C_24CXX_Delay_us(100);
        }
			
		for (; i < 8; ++i)
		{
			Temp[i] = *pdat;
			++pdat;
			--Len;
			if(!Len)
			{
				HC32_I2C_24CXX_write_one_page(addr - pdat_id_S, Temp);
                HC32_I2C_24CXX_Delay_us(100);
				return;
			}
		}
		HC32_I2C_24CXX_write_one_page(addr - pdat_id_S, Temp);
		addr = addr + 8 - pdat_id_S;
	}
	pages = Len / 8;
	for (i = 0; i < pages; ++i)
	{
		HC32_I2C_24CXX_write_one_page(addr, pdat);
		addr += 8;
		pdat += 8;
		Len  -= 8;
        HC32_I2C_24CXX_Delay_us(100);
	}
	if(!Len)
		return;
	for (i = 0; i < Len; ++i)
	{
		Temp[i] = *pdat;
		++pdat;
	}
	for(; i < 8; ++i)
	{
//		Temp[i] = HC32_I2C_24CXX_READ_one_BYTE(addr + i);
        Temp[i] = 0;
	}
    HC32_I2C_24CXX_Delay_us(100);
	HC32_I2C_24CXX_write_one_page(addr, Temp);
    HC32_I2C_24CXX_Delay_us(100);
    HC32_I2C_24CXX_read_one_page(addr,tem);
}

/*******************************************************************************
* 函 数 名         : HC32_I2C_24CXX_read_bytes
* 函数功能		   : 在AT24CXX指定地址读出一段数据
* 输    入         : addr:写入数据的目的地址  
					 pbuffer:要写入的缓冲区首地址
					 Len:数据长度
* 输    出         : 无
*******************************************************************************/
void HC32_I2C_24CXX_read_bytes(uint16_t addr, uint8_t *pbuffer, uint8_t Len)
{
	uint16_t pdat_id_S = addr % 8;
	uint8_t i, pages;
	if(pdat_id_S)
	{
		for(i = pdat_id_S; i < 8; ++i)
		{
			*pbuffer++ = HC32_I2C_24CXX_READ_one_BYTE(addr++);
			--Len;
			if(!Len)
				return;
            HC32_I2C_24CXX_Delay_us(100);
		}
	}
	pages = Len / 8;
	for (i = 0; i < pages; ++i)
	{
		HC32_I2C_24CXX_read_one_page(addr, pbuffer);
		addr += 8;
		pbuffer += 8;
		Len  -= 8;
        HC32_I2C_24CXX_Delay_us(100);
	}
	if(!Len)
		return;
    I2C_Mem_Read(E2_ADDRESS, addr, pbuffer,Len, TIMEOUT);
    HC32_I2C_24CXX_Delay_us(100);
//	i2c_mem_read(ADDR_24C02, addr, pbuffer, Len);
	pbuffer += Len;
	*pbuffer = '\0';
}


//测试用
uint8_t u8RxBuf[E2_PAGE_LEN];
void test_write_and_read(void)
{
    uint8_t u8TxBuf[E2_PAGE_LEN];
    
    uint32_t i;
    for(i=0ul; i<E2_PAGE_LEN; i++)
    {
        u8TxBuf[i] = (uint8_t)i+1u;
    }
    memset(u8RxBuf, 0x00, E2_PAGE_LEN);
    /* E2prom byte write*/
    I2C_Mem_Write(E2_ADDRESS, DATA_TEST_ADDR, u8TxBuf, 5u, TIMEOUT);

    /* 5mS delay for e2prom*/
    HC32_I2C_24CXX_Delay_us(20ul);

    /* E2prom ramdom read*/
    I2C_Mem_Read(E2_ADDRESS, DATA_TEST_ADDR, u8RxBuf, 5u, TIMEOUT);
}

#ifndef  _HC32_i2c_24cxx_H
#define  _HC32_i2c_24cxx_H

#include "main.h"
#include "hc32_ddl.h"
#include "uart_config.h"

void HC32_I2C_24Cxx_INT(void);
void test_write_and_read(void);

void HC32_I2C_24CXX_read_bytes(uint16_t addr, uint8_t* pbuffer, uint8_t Len);
void HC32_I2C_24CXX_write_bytes(uint16_t addr, uint8_t* pdat, uint8_t Len);
#endif


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值