⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic.c

📁 基于STM32F的模拟IIC时序。从STM32F的官方范例"IOToggle_key"改写而来
💻 C
字号:

#include <IIC.h>

//#include<sensor.h>

/*******************************************************************************
* Function Name  : _delay_ms
* Description    : 延时
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
GPIO_InitTypeDef QGPIO_InitStructure;

void delay_1ms(void)
{
  u32 i,j;
  for (i=0; i<8000; i++)
  {
      j ++;
  }
}
//---------------------------------
void Delay (u32 j)
{
  u32 i;
  for (i=0; i<j; i++)
  {
      delay_1ms();
  }
}
//---------------------------------
void TWait(void)
{
  Delay(5);
}
//------------------------------------------
void PIN_SDA_FLOAT(void)
            {QGPIO_InitStructure.GPIO_Pin = PIN_SDA;
             QGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
             GPIO_Init(GPIOB, &QGPIO_InitStructure);
            } 
void PIN_SDA_OUTPUT(void)
       {
         QGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         QGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
         QGPIO_InitStructure.GPIO_Pin =  PIN_SDA;
         GPIO_Init(GPIOB, &QGPIO_InitStructure);
       }
/********************************************/

void IICStart(void)
{ TSDA_H;
	TSCL_H;
	TWait();
	TSDA_L;
	TSCL_L;
	TWait();
}
/********************************************/
void IICStop(void)
{	
	TSCL_L;
	TSDA_L;
	  
    TSCL_H; TWait();
    TSDA_H;
    TSCL_L; TWait();
}
/********************************************/
void IICSendTAck(uchar ack)           //确认接收
{ 
	
	if (ack)
	     TSDA_H;
	else 
             TSDA_L;
        TSCL_H;
 	TWait();
	TSCL_L;
	TWait();
}
uchar IICTestTAck(uchar tep)           
{uchar ack=0;uchar flag;
  PIN_SDA_FLOAT();  
  flag=tep;
  TSCL_H;
	TWait();
	if (GPIO_ReadInputDataBit(GPIOB, PIN_SDA))
	//if(TSDA)
		ack=1;
	TSCL_L;
        if (flag==0)  //若flag为0,则意味接下来继续处于发送状态,所以还原端口为输出状态
	PIN_SDA_OUTPUT();
	return ack;
}
void IICSentByte(unsigned char bytedata)          //传送一个字节数据
{    unsigned char i=8;
	do{
		//TSDA=bytedata&0x80;
		if (bytedata&0x80)
			 TSDA_H;
			 else 
			 	TSDA_L;
		TSCL_H;
		TWait();
		bytedata<<=1;
		TSCL_L;
                if (i>1) //判断是否传递最后一位数据,若是最后一位则TSCL拉低后不用等待
		TWait();
    	}while(--i);
}
unsigned char IICReceiveByte(void)             				//接收一个字节数据
{	unsigned char x=0,i=8;
	
  PIN_SDA_FLOAT();
	do
	{	TSCL_H;
		TWait();
		x<<=1;
		if(GPIO_ReadInputDataBit(GPIOB, PIN_SDA))
			x++;
		TSCL_L;
                if (i>1) //判断是否传递最后一位数据,若是最后一位则TSCL拉低后不用等待
		TWait();
	 }while(--i);
	 
	PIN_SDA_OUTPUT();
	return(x);
}



unsigned char EEPROMBYTE_Write(unsigned int addr,unsigned char regdata)
{unsigned char sign,TEP;
       Delay(4);
		sign=0;
		
		TEP=addr>>8;
		TEP &=0X06;   //针对24LC08
		TEP |=0XA0;   //CONTROL BYTE:1010 A2 * * W =10100000 ; 其中A2=0
		
		IICStart();
		IICSentByte(TEP);     //CONTROL BYTE:1010 A2 A1 A0 W =10100000
		if(IICTestTAck(0))
			sign+=0x01;
		//TEP=addr>>8;
		//IICSentByte(TEP);
		//if(IICTestTAck(0))
		//sign+=0x02;
		
		TEP=addr; 
		//Delay(20);
		IICSentByte(TEP);
                
		if(IICTestTAck(0))
            { sign+=0x04;}
        
		IICSentByte(regdata);
             //   PIN_SDA_FLOAT();
                
 		if(IICTestTAck(0))
           {//TWait();TWait();TWait();Delay(20);
              sign+=0x08; 
              while(1);   //判断数据是否正确写入,测试用
           }	
		
		IICStop();
    return sign;
}
unsigned char EEPROMBYTE_Read(unsigned int addr)
{
	unsigned char sign=0,TEP;
	
	TEP=addr>>8;
		TEP &=0X06;   //针对24LC08
		TEP |=0XA0;   //CONTROL BYTE:1010 A2 * * W =10100000 ; 其中A2=0
		
	IICStart();
	IICSentByte(TEP);      ////CONTROL BYTE:1010 A2 A1 A0 W =10100000
	if(IICTestTAck(0))
	      sign+=0x01;
	
	//TEP=addr>>8;
	//IICSentByte(TEP);
	//if(IICTestTAck(0))
	//sign+=0x02;
	TEP=addr; 	
	IICSentByte(TEP);
	if(IICTestTAck(0))
	         sign+=0x04;
	
	IICStart();
	IICSentByte(0xA1);      ////CONTROL BYTE:1010 A2 A1 A0 R =10100001  不知此处是否需要修改,资料没有明确说明
	if(IICTestTAck(1))
	           sign+=0x08;
	
	sign=IICReceiveByte();
	//PIN_SDA_OUTPUT();
	IICSendTAck(1);
	IICStop();
    return(sign);
}
unsigned char EEPROMfloat_Write(unsigned int addr,float gdata)
{unsigned char sign=0,TEP;
    //------------------------
   uchar i,*px;
   uchar x[4]; //定义字符数组,准备存储浮点数的四个字节
   void *pf;  //void 型指针
    px=x;    /*px指针指向数组x*/
    pf=&gdata;  //void 型指针指向浮点数首地址
    for(i=0;i<4;i++)
    { 
	    *(px+i)=*((char *)pf+i); /*强制void 型指针转成char型,因为*/
    }                          /*void型指针不能运算*/
    //--------------------------- 
   Delay(2);
   
                TEP=addr>>8;
		TEP &=0X06;   //针对24LC08
		TEP |=0XA0;   //CONTROL BYTE:1010 A2 * * W =10100000 ; 其中A2=0
   
		IICStart();
		IICSentByte(TEP);     //CONTROL BYTE:1010 A2 A1 A0 W =10100000
		if(IICTestTAck(0))
			sign+=0x01;
		
		//TEP=addr>>8;
		//IICSentByte(TEP);
		//if(IICTestTAck(0))
		//sign+=0x02;
		
		TEP=addr; 
		//Delay(20);
		IICSentByte(TEP);
		if(IICTestTAck(0))
                      { sign+=0x04;}
        
		IICSentByte(*px); px++;
 		if(IICTestTAck(0))
                        sign=255; 
                IICSentByte(*px);  px++;
 		if(IICTestTAck(0))
                           sign=255; 
      
                IICSentByte(*px);  px++;
 		if(IICTestTAck(0))
                        sign=255;
            
                IICSentByte(*px);
 		if(IICTestTAck(0))
                      { //TWait();TWait();TWait();Delay(20);
                        sign=255; 
                        while(1);   //判断数据是否正确写入。
                      }	            	
        
		IICStop();
		return sign;
		
}
float EEPROMfloat_Read(unsigned int addr)
{
	//unsigned char sign=0,TEP;
        uint addr2;
	//---------------------------
   float a;
   uchar i,*px;
   uchar x[4];
   void *pf;
   px=x;  //px指向数组 "x"
	//-----------------------
	/*
        TEP=addr>>8;
		TEP &=0X06;   //针对24LC08
		TEP |=0XA0;   //CONTROL BYTE:1010 A2 * * W =10100000 ; 其中A2=0
		
	IICStart();
	IICSentByte(TEP);      ////CONTROL BYTE:1010 A2 A1 A0 W =10100000
	if(IICTestTAck(0))
	       sign+=0x01;
	//TEP=addr>>8;
	//IICSentByte(TEP);
	//if(IICTestTAck(0))
	//sign+=0x02;
	TEP=addr; 	
	IICSentByte(TEP);
	if(IICTestTAck(0))
	       sign+=0x04;
	
	IICStart();
	IICSentByte(0xA1);      ////CONTROL BYTE:1010 A2 A1 A0 R =10100001
	if(IICTestTAck(1))
	       sign+=0x08;
	
	*px=IICReceiveByte();    //对数组x赋值
	IICSendTAck(0);           px++;
	*px=IICReceiveByte();  
	IICSendTAck(0);           px++;   
	*px=IICReceiveByte();  
	IICSendTAck(0);           px++; 
	*px=IICReceiveByte();
        IICSendTAck(1);
        IICStop();
        */   
        //24c08仿佛不支持连续读,下面改为选择读。
         addr2=addr;
         *px=EEPROMBYTE_Read(addr2); addr2++;px++;  //对数组x赋值
         *px=EEPROMBYTE_Read(addr2); addr2++;px++;
         *px=EEPROMBYTE_Read(addr2); addr2++;px++;
         *px=EEPROMBYTE_Read(addr2); addr2++;px++;
    
	//------------------
	  px=x;  //把px重新指向数组x首地址
	  pf=&a;
  for(i=0;i<4;i++)
  { *((char *)pf+i)=*(px+i);  }
	//-------------------------------
    return(a);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -