移植iic--24c02和fdc2214

IIC

一、用于连接CPU和外围电路的总线,一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。I2C总线上允许连接多个微处理器以及各种外围设备,为了进行通讯,每个接到I2C总线的设备都有一个唯一的地址。

二、信号。IIC在每次传输完一字节后需要应答信号。

  1. 在进行通信时,主控要告诉外设开始和结束,分别对应开始和结束信号。
  2. IIC在每次传输完一字节后需要应答信号。
  3. 在驱动大部分外设时,传输一个字节数据需要SCL==1。此时SDA上的数据认为是可信的。这也就是说如果对于信号没有特殊的要求,这部分不需要改写。这里直接用的正点原子的,就是初始化和配置端口需要自己改。
    #include "myiic.h"
    #include "delay.h"
    //	 
    //本程序只供学习使用,未经作者许可,不得用于其它任何用途
    //ALIENTEK STM32F407开发板
    //IIC 驱动代码	   
    //正点原子@ALIENTEK
    //技术论坛:www.openedv.com
    //创建日期:2014/5/6
    //版本:V1.0
    //版权所有,盗版必究。
    //Copyright(C) 广州市星翼电子科技有限公司 2014-2024
    //All rights reserved									  
    // 	
    
    //初始化IIC
    void IIC_Init(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_PP;//推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
      GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
    	IIC_SCL=1;
    	IIC_SDA=1;
    }
    //产生IIC起始信号
    void IIC_Start(void)
    {
    	SDA_OUT();     //sda线输出
    	IIC_SDA=1;	  	  
    	IIC_SCL=1;
    	delay_us(4);
     	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
    	delay_us(4);
    	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
    }	  
    //产生IIC停止信号
    void IIC_Stop(void)
    {
    	SDA_OUT();//sda线输出
    	IIC_SCL=0;
    	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
     	delay_us(4);
    	IIC_SCL=1; 
    	IIC_SDA=1;//发送I2C总线结束信号
    	delay_us(4);							   	
    }
    //等待应答信号到来
    //返回值:1,接收应答失败
    //        0,接收应答成功
    u8 IIC_Wait_Ack(void)
    {
    	u8 ucErrTime=0;
    	SDA_IN();      //SDA设置为输入  
    	IIC_SDA=1;delay_us(1);	   
    	IIC_SCL=1;delay_us(1);	 
    	while(READ_SDA)
    	{
    		ucErrTime++;
    		if(ucErrTime>250)
    		{
    			IIC_Stop();
    			return 1;
    		}
    	}
    	IIC_SCL=0;//时钟输出0 	   
    	return 0;  
    } 
    //产生ACK应答
    void IIC_Ack(void)
    {
    	IIC_SCL=0;
    	SDA_OUT();
    	IIC_SDA=0;
    	delay_us(2);
    	IIC_SCL=1;
    	delay_us(2);
    	IIC_SCL=0;
    }
    //不产生ACK应答		    
    void IIC_NAck(void)
    {
    	IIC_SCL=0;
    	SDA_OUT();
    	IIC_SDA=1;
    	delay_us(2);
    	IIC_SCL=1;
    	delay_us(2);
    	IIC_SCL=0;
    }					 				     
    //IIC发送一个字节
    //返回从机有无应答
    //1,有应答
    //0,无应答			  
    void IIC_Send_Byte(u8 txd)
    {                        
        u8 t;   
    	SDA_OUT(); 	    
        IIC_SCL=0;//拉低时钟开始数据传输
        for(t=0;t<8;t++)
        {              
            IIC_SDA=(txd&0x80)>>7;
            txd<<=1; 	  
    		delay_us(2);   //对TEA5767这三个延时都是必须的
    		IIC_SCL=1;
    		delay_us(2); 
    		IIC_SCL=0;	
    		delay_us(2);
        }	 
    } 	    
    //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
    u8 IIC_Read_Byte(unsigned char ack)
    {
    	unsigned char i,receive=0;
    	SDA_IN();//SDA设置为输入
        for(i=0;i<8;i++ )
    	{
            IIC_SCL=0; 
            delay_us(2);
    		IIC_SCL=1;
            receive<<=1;
            if(READ_SDA)receive++;   
    		delay_us(1); 
        }					 
        if (!ack)
            IIC_NAck();//发送nACK
        else
            IIC_Ack(); //发送ACK   
        return receive;
    }

     

三、我们有了驱动的信号,就可以做读或者写数据了。这是我们就要看好数据手册了。主要是他需要的地址信息(每个外设唯一)和信号指令(读或者写)。

  1. 先来看24c02的首地址,A2/1/0都是地址位。                                                                                                                           当24c02的三个A管脚都置零时,如果写数据则首地址位是1010 0000,如果读数据也就是1010 0001。
  2. 在看fdc2214的首地址。他是这么说的“当ADDR pin设置为低时,FDC I2C地址为0x2A;当ADDR pin设置为高时,FDC I2C地址为0x2B”。
  3. 然后我们看他们给我们读取或写入数据的规则。拿24c02读数据来说:                                    他说我们需要先写一个起始条件,然后器件地址接应答,在进入读模式读取8位数据,最后停止。
    //在AT24CXX指定地址读出一个数据
    //ReadAddr:开始读数的地址  
    //返回值  :读到的数据
    u8 AT24CXX_ReadOneByte(u16 ReadAddr)
    {				  
    	u8 temp=0;		  	    																 
        IIC_Start();  
    	if(EE_TYPE>AT24C16)
    	{
    		IIC_Send_Byte(0XA0);	   //发送写命令
    		IIC_Wait_Ack();
    		IIC_Send_Byte(ReadAddr>>8);//发送高地址	    
    	}else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据 	   
    	IIC_Wait_Ack(); 
        IIC_Send_Byte(ReadAddr%256);   //发送低地址
    	IIC_Wait_Ack();	    
    	IIC_Start();  	 	   
    	IIC_Send_Byte(0XA1);           //进入接收模式			   
    	IIC_Wait_Ack();	 
        temp=IIC_Read_Byte(0);		   
        IIC_Stop();//产生一个停止条件	    
    	return temp;
    }

     

  4. 在看fdc2214                                                                         我们需要写入器件地址和寄存器地址,在进行数据读取,最后无应答和停止信号,只不过这个寄存器是16位的。我们需要读两次。其实和上面24c02的代码是很像的。
    u16 FDC_Read(u8 reg)    //核心代码    //不需修改
    {
    	u16 res;
       FDC_IIC_Start(); 
    	FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|0);//发送器件地址+写命令	
    	FDC_IIC_Wait_Ack();		//等待应答 
        FDC_IIC_Send_Byte(reg);	//写寄存器地址
        FDC_IIC_Wait_Ack();		//等待应答
        FDC_IIC_Start();
    	FDC_IIC_Send_Byte((FDC2214_ADDR<<1)|1);//发送器件地址+读命令	
        FDC_IIC_Wait_Ack();		//等待应答 
    	res=FDC_IIC_Read_Byte(1)<<8;//读取数据,发送ACK
    	  
    	res|=FDC_IIC_Read_Byte(0);//读取数据,发送nACK
        FDC_IIC_Stop();			//产生一个停止条件
    	return res;		
    }

    结束了。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值