构建驱动模块2--STM32模拟IIC访问 (AT24C02)EEPROM 操作

 

          构建驱动模块2-- STM32模拟IIC访问 (AT24C02)EEPROM 操作

        模拟IIC接口可以使用任意两个IO口实现,不受芯片引脚限制,而且硬件IIC在通信出错后,无法自行恢复,模拟IIC则可以迅速恢复;通过调整延时参数,可以调节访问速度。本程序把模拟II2C封装成一个模块,AT24C02只需要调用该模块即可。

1、初始化EEPROM设备。调用 EEPRomhardwareInit("24c02",0);接口即可。在设备管理层生成一个EEPROM节点。

/**********************************************************************************************************
 *
 *  函数名:EEPRomhardwareInit
 *  功 能:
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
void EEPRomhardwareInit(ht_int8_t *name,ht_int16_t devno)//初始化EEPROM设备 其中devno是挂载端口,devno=0 表示挂载到0硬件接口。
{
 char str[64];
	EEPRom_dev =(ht_device_t) cmMalloc(sizeof(struct ht_device) );
	 if(EEPRom_dev==NULL)
	{
		cmFault(SYS_ERROR_MEMMALLOC_ABNORMAL,RECORD_FLAG);
	}
	cmMemset(EEPRom_dev,0,sizeof(struct ht_device));
	EEPRom_dev -> open = bspEEPROMOpen;
	EEPRom_dev -> close = bspEEPROMClose;
	EEPRom_dev -> read = bspEEPROMRead;
	EEPRom_dev->control = NULL;
	EEPRom_dev->del=bspEEPROMdel;
	EEPRom_dev->help=bspEEPROMhelp;
	EEPRom_dev->write = bspEEPROMWrite;
	EEPRom_dev->user_privatedata = NULL;
	sprintf(str,"%s-%d",name,devno);
	if( gI2chardwareInit("Gi2c",devno)>0)
	{
  htDevFsRegister( EEPRom_dev,str);
	htDevFsAssociated(EEPRom_dev,"Gi2c",devno);
   
	}
	else
	{
		cmFree(EEPRom_dev);
	}
 
}

 2、实现open、Close、write、read、del等接口。

/**********************************************************************************************************
 *
 *  函数名:bspEEPROMWrite
 *  功 能:
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
ht_inline ht_int32_t bspEEPROMWrite  (ht_device_t dev, ht_uint32_t WriteAddr, const void *buffer, ht_int32_t NumByteToWrite)
{
	ht_int32_t iResult = NumByteToWrite;
	ht_uint8_t *Dat = (ht_uint8_t *)( buffer),i;
	ht_uint8_t buf[2];
	i2c_msg_t msg;
	htDevFsHandle i2cfd=NULL;
  if(dev->isChildFlag)//是否存在硬件操作接口
  i2cfd=htDevFsOpen(dev->childname,0);//接口名称固定为"Gi2c"
	if(i2cfd==NULL)
	{
		return -1 ;
	}
	for(i=0;i<NumByteToWrite;i++)//写数据到EEPROM
	{
	buf[0]=(ht_uint8_t)WriteAddr++;//设定地址
	buf[1]=Dat[i];//设定数据
	msg.pMsg=&buf[0];
	msg.Len=2;//传输长度
	msg.Stop=1;	//完成本次传输是否停止
	htDevFsControl(i2cfd,CMD_I2C_WRITE,(void*)&msg);//读取操作命令
		OSTimeDlyHMSM(0,0,0,8);
	}
	htDevFsClose(i2cfd);
	return iResult;
} 
/**********************************************************************************************************
 *
 *  函数名:bspEEPROMRead
 *  功 能:
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
ht_inline ht_int32_t bspEEPROMRead  (ht_device_t dev, ht_uint32_t pos, void *buffer, ht_int32_t size)
{
	ht_int32_t iResult = size;
	ht_uint8_t *Dat = (ht_uint8_t *)( buffer),i;
	ht_uint8_t buf[2];
	i2c_msg_t msg;
	htDevFsHandle i2cfd=NULL;
  if(dev->isChildFlag)
  i2cfd=htDevFsOpen(dev->childname,0);
	if(i2cfd==NULL)
	{
		return -1 ;
	}
	for(i=0;i<size;i++)
	{
	buf[0]=(ht_uint8_t)pos++;//设置读取地址
	msg.pMsg=&buf[0];//读取字节
	msg.Len=1;
	msg.Total=2;	
	htDevFsControl(i2cfd,CMD_I2C_WRITEREAD,(void*)&msg);//读取操作命令
	Dat[i]=buf[1];
	
	}
	htDevFsClose(i2cfd);
	return iResult;
}
/**********************************************************************************************************
 *
 *  函数名:bspEEPROMOpen
 *  功 能:
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
ht_inline ht_int32_t bspEEPROMOpen (ht_device_t dev, ht_uint32_t oflag)
{

	i2c_cfg_t i2c_cfg;
	i2c_msg_t msg;
	htDevFsHandle i2cfd=NULL;
  if(dev->isChildFlag)
	{
  i2cfd=htDevFsOpen(dev->childname,0);
	if(i2cfd==NULL)
	{ 
		return -1;
	}
  }
	 //*设置IIC访问速度和设备器件地址参数*//
	 i2c_cfg.hcfI2cDelayTime=16;
	 i2c_cfg.hcfSlaveAddress=0xa0;
	if(htDevFsControl(i2cfd,CMD_I2C_CFG,(void*)&i2c_cfg)<0)
	{
		 
		return -1;
	}
	htDevFsClose(i2cfd);
    return HT_EOK;
}
/**********************************************************************************************************
 *
 *  函数名:bspEEPROMClose
 *  功 能:
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
ht_inline ht_int32_t bspEEPROMClose (ht_device_t dev)
{
	return HT_EOK;
}
/**********************************************************************************************************
 *
 *  函数名:bspEEPROMdel
 *  功 能:
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
 ht_inline ht_int32_t   bspEEPROMdel(ht_device_t dev)
 {

	   ht_int8_t str[32];
	   htDevFsUnregister(dev);//卸载驱动
	   cmFree(dev);//释放Device
	 return 1;
 }
 
 /**********************************************************************************************************
 *
 *  函数名:bspEEPROMhelp
 *  功 能:
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0     
 * EEPROM测试操作
 **********************************************************************************************************/
 	ht_inline ht_int32_t  bspEEPROMhelp   (ht_device_t dev, ht_int8_t argc, ht_int8_t * argv[])
{
	int arg=0,i,j;
	htDevFsHandle fd;
	ht_uint8_t Rbuffer[10];
	ht_uint8_t Tbuffer[10];
	ht_uint16_t temp;
	static ht_uint8_t cnt=0;
	if(arg<=argc)
	{
		if (strcmp((char const *) argv[2], "test")==0)
		{
		ht_printk("devname %s\r\n",argv[1]);
		fd=htDevFsOpen( argv[1],0);
		if(fd!=NULL)
		{
			
			for(j=0;j<5;j++)
			{
				cnt++;
			ht_printk("Write:");
				for(i=0;i<10;i++)
			{
		  Tbuffer[i]=i+cnt;
				 	ht_printk("%02x ",Tbuffer[i]);
			}
			ht_printk("\r\n");
			if( htDevFsWrite(fd,0,Tbuffer,10)==10)
			{
				ht_printk("bspEEPROMWrite is Ok \r\n");
			}
			OSTimeDlyHMSM(0,0,0,300);
				if( htDevFsRead(fd,0,Rbuffer,10)==10)
			{
				ht_printk("bspEEPROMRead is Ok \r\n");
			}
			 	ht_printk("Read:");
			for(i=0;i<10;i++)
			{
		   	ht_printk("%02x ",Rbuffer[i]);
		 
			}
			ht_printk("\r\n");
		}
	}
      htDevFsClose(fd);	
      	
		}
		else
		{
			ht_printk("can not find dev\r\n");
		}
	}
}

3、实际操作II2C端口

	//EEPROM读操作
for(i=0;i<size;i++)
	{
	buf[0]=(ht_uint8_t)pos++;
	msg.pMsg=&buf[0];
	msg.Len=1;
	msg.Total=2;	
	htDevFsControl(i2cfd,CMD_I2C_WRITEREAD,(void*)&msg);
	Dat[i]=buf[1];
	
	}
//EEPROM写操作
	for(i=0;i<NumByteToWrite;i++)
	{
	buf[0]=(ht_uint8_t)WriteAddr++;
	buf[1]=Dat[i];
	msg.pMsg=&buf[0];
	msg.Len=2;
	msg.Stop=1;	
	htDevFsControl(i2cfd,CMD_I2C_WRITE,(void*)&msg);
		OSTimeDlyHMSM(0,0,0,8);
	}

4、配置GI2C 硬件接口

 /**********************************************************************************************************
 *
 *  函数名:GI2C1_GPIO_Config_bf
 *  功 能: 
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
 ht_inline void GI2C1_GPIO_Config_bf(void)
 {
	GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  //使能GPIOB时钟
  //GPIOB8,B9初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;          //普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;         //开漏输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;     //100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;           //上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);                 //初始化IO
	 //ht_printk(" GI2C1_GPIO_Config_bf OK\r\n");
	 GPIO_WriteBit(GPIOB,GPIO_Pin_8,1);
	 GPIO_WriteBit(GPIOB,GPIO_Pin_9,1);
 }
  /**********************************************************************************************************
 *
 *  函数名:GI2C1_SDA_Set
 *  功 能: 
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
ht_inline void GI2C1_SDA_Set(ht_uint8_t Data) 
 {
	 GPIO_WriteBit(GPIOB,GPIO_Pin_9,Data);
 
 }
  /**********************************************************************************************************
 *
 *  函数名:GI2C1_SCL_Set
 *  功 能: 
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
ht_inline void GI2C1_SCL_Set (ht_uint8_t Data) 
 { 
	 GPIO_WriteBit(GPIOB,GPIO_Pin_8,Data);
 }
  /**********************************************************************************************************
 *
 *  函数名:GI2C1_ReadBit
 *  功 能: 
 *  参  数:
 *  返回值:
 *  版 本:REV1.0.0          2016/04/27    Create
 *
 **********************************************************************************************************/
ht_inline ht_uint8_t GI2C1_ReadBit (void) 
{ 
	return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9);
}	

  
//配置GI2C1
const struct hcfResource gI2C1DrvResources[] ={ 
    { "I2C_Init", HT_RES_ADDR, { (void **)&GI2C1_GPIO_Config_bf } }, 
		{	"I2C_SDA_SET", HT_RES_ADDR, { (void **)&GI2C1_SDA_Set } }, 
		{	"I2C_SCL_SET", HT_RES_ADDR, { (void **)&GI2C1_SCL_Set } }, 
		{	"I2C_BIT_READ", HT_RES_ADDR, { (void **)&GI2C1_ReadBit } }, 
		{	"I2C_SPEED", HT_RES_INT,   (void **)16 }, 
  

   };

5、测试结果

EPPROM读取结果:

猜你喜欢

转载自blog.csdn.net/u011996698/article/details/83544283