NUC140之I2C和AT24C32

I2C总线一根数据线,一根时钟线,起始和终止条件如下:

AT24C32是一款4K字节的EEPROM,它的字节写如下图:

具体的文字描述结合我的程序一看就明白了,我的程序注释非常丰富

/*****************************************
*文件名:at24c32.c                       *
*功能:EEPROM读写程序      	             *
******************************************/
#include "at24c32.h"

void at24c32_write (uint8_t device_address, uint8_t data_high_address, uint8_t data_low_address, uint8_t data_);
uint8_t at24c32_read (uint8_t device_address, uint8_t data_high_address, uint8_t data_low_address);

/**************************************************
*函数名:at24c32_initialize 					  *
*功能:	 EEPROM初始化      	                      *
*出口参数:无									  *
*入口参数:无									  *
**************************************************/


void at24c32_initialize (void)
{
	uint8_t temp_data = 0;
	DrvGPIO_InitFunction (E_FUNC_I2C1);    //PA.10,PA.11设置为I2C
	DrvSYS_UnlockProtectedReg ();          //解锁受保护的系统寄存器
	DrvSYS_SetIPClock (E_SYS_I2C1_CLK, 1); //使能I2C端口1的核心时钟    
	DrvSYS_LockProtectedReg ();            //对系统寄存器上锁
	DrvI2C_Open (I2C_PORT1, 100000);       //使能I2C端口1,时钟为100KHz
										   //由于所有I2C端口共用一个时钟分频器,所以每个I2C端口的时钟频率必须设为一致,且不能超过1MHz
	delay (100);                           //延迟使时钟稳定

	temp_data = at24c32_read (DEVICE_ADDRESS, EEPROM_INITIALIZED_HIGH_ADDRESS, EEPROM_INITIALIZED_LOW_ADDRESS);
	if (temp_data != 0xfe)
	{
		at24c32_write(DEVICE_ADDRESS, EEPROM_INITIALIZED_HIGH_ADDRESS, EEPROM_INITIALIZED_LOW_ADDRESS, 0xfe);                 //对最后一个地址写数据表明EEPROM已被初始化
		at24c32_write(DEVICE_ADDRESS, RADIO_MAIN_HIGH_ADDRESS, RADIO_MAIN_LOW_ADDRESS, RADIO_MAIN_DEFAULT);                   
		at24c32_write(DEVICE_ADDRESS, ENABLE_PTT_LIMIT_HIGH_ADDRESS, ENABLE_PTT_LIMIT_LOW_ADDRESS, ENABLE_PTT_LIMIT_DEFAULT); 
		at24c32_write(DEVICE_ADDRESS, PTT_LIMIT_TIME_HIGH_ADDRESS, PTT_LIMIT_TIME_LOW_ADDRESS, PTT_LIMIT_TIME_DEFAULT);     
		at24c32_write(DEVICE_ADDRESS, POWER_VALUE_HIGH_ADDRESS, POWER_VALUE_LOW_ADDRESS, POWER_VALUE_DEFAULT);             
		at24c32_write(DEVICE_ADDRESS, MODULATION_VALUE_HIGH_ADDRESS, MODULATION_VALUE_LOW_ADDRESS, MODULATION_VALUE_DEFAULT);
		at24c32_write(DEVICE_ADDRESS, ENABLE_ERROR_HIGH_ADDRESS, ENABLE_ERROR_LOW_ADDRESS, ENABLE_ERROR_DEFAULT);          
		at24c32_write(DEVICE_ADDRESS, FREQUENCY_HIGH_ADDRESS, FREQUENCY_LOW_ADDRESS, FREQUENCY_DEFAULT);                  
		at24c32_write(DEVICE_ADDRESS, CHANNEL_SPACE_HIGH_ADDRESS, CHANNEL_SPACE_LOW_ADDRESS, CHANNEL_SPACE_DEFAULT);          
	}
}

/**************************************************
*函数名:at24c32_write     					      *
*功能:  EEPROM写程序       	                  *
*出口参数:无									  *
*入口参数:设备8位地址,写数据高8位地址,		  *
*            低8位地址,8位数据	                  *
**************************************************/

void at24c32_write (uint8_t device_address, uint8_t data_high_address, uint8_t data_low_address, uint8_t data_)
{
 	DrvI2C_Ctrl (I2C_PORT1, 1, 0, 0, 0);             //I2C端口1发送一个起始标志(注释若有不明白的,参芯片手册中文版216页起好好看看)
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0)     //查询中断标志位SI,当起始已被发送时,SI为0x08
	{
	}

	DrvI2C_WriteData (I2C_PORT1, device_address);    //将at24c32设备地址(高7位)+写命令(0)存入I2CDAT中
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);		     //清除中断标志位,准备发送地址+写命令(0)
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0)     //查询中断标志位,当从机地址+W已被发送且收到ACK时SI 不为0,为0x18
	{
	}

	DrvI2C_WriteData (I2C_PORT1, data_high_address); //将数据高8位地址(前四位任意)存入I2CDAT中
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);			 //清除中断标志位,准备发送数据高8位地址
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0)	 //查询中断标志位,当高8位地址已被发送且收到ACK时SI 不为0,为0x28
	{
	}

	DrvI2C_WriteData (I2C_PORT1, data_low_address);   //将数据低8位地址存入I2CDAT中
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);			  //清除中断标志位,准备发送数据低8位地址
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0)	  //查询中断标志位,当高8位地址已被发送且收到ACK时SI 不为0,为0x28
	{
	}

	DrvI2C_WriteData (I2C_PORT1, data_);              //将要写的数据存入I2CDAT中
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);			  //清除中断标志位,准备发送要写入的数据
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0)	  //查询中断标志位,当高8位地址已被发送且收到ACK时SI 不为0,为0x28
	{
	}

	DrvI2C_Ctrl (I2C_PORT1, 0, 1, 1, 0);              //I2C端口1发送一个结束标志且清除SI
	delay(MINIMUM_DELAY);							              //at24c32写数据之后要给至少10ms才能再写一个数据,在此给40ms延迟
}

 /**************************************************
 *函数名:	at24c32_read     					  *
 *功能:	EEPROM读程序       	                  *
 *出口参数:读取的8位数据						  *
 *入口参数:读数据高8位地址,低8位地址			  *
 *************************************************/

uint8_t at24c32_read (uint8_t device_address, uint8_t data_high_address, uint8_t data_low_address)
{
	uint8_t data_read;
	DrvI2C_Ctrl (I2C_PORT1, 1, 0, 0, 0);              //I2C端口1发送一个起始标志
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0)	  //查询中断标志位SI,当起始已被发送时,SI为0x08
	{
	}
	DrvI2C_WriteData (I2C_PORT1, device_address);	  //将at24c32设备地址(高7位)+写命令(0)存入I2CDAT中
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);			  //清除中断标志位,准备发送地址+写命令(0)
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0);	  //查询中断标志位,当从机地址+W已被发送且收到ACK时SI 不为0,为0x18
	{
	}

	DrvI2C_WriteData (I2C_PORT1, data_high_address);  //将数据高8位地址(前四位任意)存入I2CDAT中
 	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);			  //清除中断标志位,准备发送数据高8位地址
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0);	  //查询中断标志位,当高8位地址已被发送且收到ACK时SI 不为0,为0x28
	{
	}

	DrvI2C_WriteData (I2C_PORT1, data_low_address);   //将数据低8位地址存入I2CDAT中
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);			  //清除中断标志位,准备发送数据低8位地址
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0);	  //查询中断标志位,当高8位地址已被发送且收到ACK时SI 不为0,为0x28
	{
	}
	
	DrvI2C_Ctrl (I2C_PORT1, 1, 0, 1, 0);              //发送一个再开始标志并清SI
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0);	  //查询中断标志位SI,当再开始起始已被发送时,SI为0x10
	{
	}
	
	DrvI2C_WriteData (I2C_PORT1, device_address+1);   //将at24c32设备地址+读命令(1),+1表示读存入I2CDAT中
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);			  //清除SI准备发送从机地址+读命令
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0);	  //查询中断标志位,当从机地址+读命令已发送且收到ACK时,SI不为0,为0x40
	{
	}
	
	DrvI2C_Ctrl (I2C_PORT1, 0, 0, 1, 0);		       //清除中断标志位,不设置ACK,因为24C32读数据不会回传ACK应答
	while ((DrvI2C_GetIntFlag (I2C_PORT1)) == 0);	   //查询中断标志位,若已收到数据且无ACK时,SI不为0,为0x58
	{
	}

	data_read = DrvI2C_ReadData (I2C_PORT1);           //读取数据
	DrvI2C_Ctrl (I2C_PORT1, 0, 1, 1, 0);			   //清除SI且发生结束标志
	return (data_read); 
}











头文件如下:

#ifndef at24c32_h
#define at24c32_h

#include "stdint.h"
#include "common_variables.h"
#include "DrvGPIO.h"
#include "DrvI2C.h"
#include "DrvSYS.h"
#include "delay.h"
#define MINIMUM_DELAY 150	 //at24c32写数据最低延迟时间10ms,在此给15ms

//定义AT24C32的地址单元
#define DEVICE_ADDRESS 0xa0                     //EEPROM地址,1010 0000,前四位固定,地址为000,最后一位写是0,读是1

#define EEPROM_INITIALIZED_HIGH_ADDRESS 0xff	//判断EEPROM是否以及被初始化的地址单元
#define EEPROM_INITIALIZED_LOW_ADDRESS  0xff

#define RADIO_MAIN_HIGH_ADDRESS         0xf0   
#define RADIO_MAIN_LOW_ADDRESS          0x01
#define	RADIO_MAIN_DEFAULT              0x00	

#define ENABLE_PTT_LIMIT_HIGH_ADDRESS   0xf0   
#define ENABLE_PTT_LIMIT_LOW_ADDRESS    0x02
#define ENABLE_PTT_LIMIT_DEFAULT        0x01    

#define PTT_LIMIT_TIME_HIGH_ADDRESS     0xf0    
#define PTT_LIMIT_TIME_LOW_ADDRESS      0x03   
#define PTT_LIMIT_TIME_DEFAULT          0x01	

#define POWER_VALUE_HIGH_ADDRESS        0xf0	
#define POWER_VALUE_LOW_ADDRESS         0x04
#define POWER_VALUE_DEFAULT             0x32    

#define MODULATION_VALUE_HIGH_ADDRESS   0xf0	
#define MODULATION_VALUE_LOW_ADDRESS    0x05
#define MODULATION_VALUE_DEFAULT        0x5a 

#define ENABLE_ERROR_HIGH_ADDRESS       0xf0   
#define ENABLE_ERROR_LOW_ADDRESS        0x06
#define ENABLE_ERROR_DEFAULT            0x01   

#define FREQUENCY_HIGH_ADDRESS          0xf0  
#define FREQUENCY_LOW_ADDRESS           0x07
#define FREQUENCY_DEFAULT               0x76   

#define CHANNEL_SPACE_HIGH_ADDRESS      0xf0   
#define CHANNEL_SPACE_LOW_ADDRESS       0x08
#define CHANNEL_SPACE_DEFAULT           0x01    

extern void at24c32_initialize (void); //初始化at24c32
extern void at24c32_write (uint8_t device_address,    //EEPROM地址
						   uint8_t data_high_address, //写数据高8为地址,前四位任意 
					       uint8_t data_low_address,  //写数据低8位地址
					       uint8_t data_); 		      //8位数据
extern uint8_t at24c32_read (uint8_t device_address,	 //EEPROM地址
							 uint8_t data_high_address,  //读数据高8位地址
				             uint8_t data_low_address);  //读数据低8为地址
#endif

注意!!!

对AT24C32连续写数据时,每写一个字节要等待10ms,否则会写入失败,这是由芯片特性决定的,

可以参看DATASHEET。

猜你喜欢

转载自blog.csdn.net/pxy198831/article/details/85305160
I2C