mini2440之IIC通信协议

IIC的源文件 iic.c
/***********************************************
  Copyright (C),2016-2020,xmetc  Tech. Co., Ltd.  
  FileName: lcd.c  
  Author:lifangguo 
  Version:1.0 
  Date::2016-08-22 
  Description:iic驱动. 
  History     :   	  
	1  Date	        2016-8-22 
	   Author       li
	   Modification   Init vision 
 ***********************************************/

#include "2440addr.h"
#include "iic.h"
#include "uart.h"





/***********************************************
Function  name  :   iic_init
Description     :   IIC gpio init
Input parameter :   none
Return          :   none	 	
Others		    :                     	                    
*************************************************/

void iic_init(void)
{
	volatile unsigned int regval;
	
	regval = rGPECON&~((unsigned int)0xf<<28); 
	rGPECON = regval|((unsigned int)0xa<<28);

	//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/1
    rIICCON  = rIICCON&((~0xf)<<4)|(1<<7) | (1<<6) | (1<<5) | (0x0);
}




/***********************************************
Function  name  :   iic_write
Description     :   iic 指定地址写
Input parameter :   devaddr--设备地址
                    wordaddr--内存地址
                    data--要写的数据
Return          :   none	 	
Others		    :                     	                    
*************************************************/
void iic_write(unsigned char devaddr, unsigned char wordaddr, unsigned char data)
{  

	unsigned int i;
	
	// Tx dev addr
	rIICSTAT = 0xF0;            // (1)  与(2)调换会丢失第一个数据
	rIICDS = devaddr;           // (2)
	
	while(rIICSTAT&0x1);
	while(!(rIICCON & 0x10));   //可以ack 和 pending 一起判断,也可以只判断pending,但如果只判断ack会丢失第一个数据
	

	// Tx word addr
	rIICDS = wordaddr;
	for(i=0;i<100;i++);            //for setup time until rising edge of IICSCL
	rIICCON = rIICCON&~(1<<4);    //resumes IIC operation.
	while(rIICSTAT&0x1);
	while(!(rIICCON & 0x10));   //
	


	rIICDS = data;
	for(i=0;i<100;i++);           //for setup time until rising edge of IICSCL
	rIICCON = rIICCON&~(1<<4);    //resumes IIC operation.
	while(rIICSTAT&0x1);
	while(!(rIICCON & 0x10));     //可以ack 和 pending 一起判断,也可以只判断pending,但如果只判断ack会丢失第一个数据
	


	rIICSTAT = 0xd0;                //stop MasTx condition 
	rIICCON = rIICCON&~(1<<4);    //resumes IIC operation.
	for(i=0;i<10000;i++);          //for stop condition takes effect.



	// waiting ACK  确保刚才的数据已经写完。 如果没有这步,会丢失数据
   	while(1)
	{   
	 
		rIICSTAT = 0xF0;
		rIICDS =devaddr;
		
		rIICCON = rIICCON&~(1<<4);   //resumes IIC operation. (need)
		while(!(rIICCON & 0x10));    //   (need)
		

		if(	!(rIICSTAT & 0x01))      // rIICSTAT[0] = 0,ACK receive
		{
			break;
		}
	}

	rIICSTAT = 0xd0;                //stop MasTx condition    释放总线
	rIICCON = rIICCON&~(1<<4);      //resumes IIC operation.
	for(i=0;i<10000;i++);           //for stop condition takes effect.



}







/***********************************************
Function  name  :   iic_read
Description     :   iic 指定地址读
Input parameter :   devaddr--设备地址
                    wordaddr--内存地址
                    pdata--读数据存放的缓冲
                    size--读的字节数
Return          :   none	 	
Others		    :                     	                    
*************************************************/
void iic_read(unsigned char devaddr, unsigned char wordaddr, unsigned char *pdata, unsigned int size)
{

	unsigned int i;

	// set read address
	rIICSTAT = 0xF0; 
	
	rIICDS = devaddr;  

	while(!(rIICCON & 0x10));

	rIICDS = wordaddr;
	for(i=0;i<100;i++);           //for setup time until rising edge of IICSCL
	rIICCON = rIICCON&~(1<<4);    //resumes IIC operation.
	while(!(rIICCON & 0x10));

	// start read 
	rIICSTAT = 0xb0;
	rIICDS = devaddr|1;             // 不或上1也OK
	for(i=0;i<100;i++);   
	rIICCON = rIICCON&~(1<<4);    //resumes IIC operation.
	while(!(rIICCON & 0x10));

/***********************su 先判断有值过来再读 读N个24c08连续*****************

	while(1)  //10  9 ack  1noack
	{
		--size;
		if((size)==0)
		{
			rIICCON = rIICCON&~((1<<7)|(1<<4));  //Resumes IIC operation with 
		
			// NOACK.(need)
		}
		else
		{
			rIICCON = rIICCON&~(1<<4);    //resumes IIC operation.
		}
	    while(!(rIICCON & 0x10));
		*pdata = rIICDS;

		pdata++ ;
		if((size)==0)
		{
			break;
		}
	}

/*************************************************/


//****************su 先判断有值过来再读 读1个

    rIICCON = rIICCON&~((1<<7)|(1<<4));   //Resumes IIC operation with   noack
	while(!(rIICCON & 0x10));
	*pdata = rIICDS;

//****************/

	rIICSTAT = 0x90;              //Stop MasRx condition 
	rIICCON = rIICCON&~(1<<4);    //resumes IIC operation.
	for(i=0;i<10000;i++);          //for stop condition takes effect.
 
}





void iic_write_int(U8 devaddr,U8 wordaddr,int data)
{
	U8 i;
	U8 *p;
	p = (U8*)&data;
	for(i=0 ; i<4 ; i++)
	{
		iic_write(devaddr , wordaddr+i , p[i]);
		//uart_printf("write %d\n",p[i]);
	}
}

void iic_read_int(U8 devaddr,U8 wordaddr,int *data)
{
	U8 i;
	U8 *p;
	p = (U8*)data;
	for(i=0 ; i<4 ; i++)
	{
		iic_read(devaddr , wordaddr+i , &p[i],1);
		//uart_printf("read %d\n",p[i]);
	}
}


void iic_write_float(U8 devaddr,U8 wordaddr,float data)
{
	U8 i;
	U8 *p;
	p = (U8*)&data;
	for(i=0 ; i<4 ; i++)
	{
		iic_write(devaddr , wordaddr+i , p[i]);
		//uart_printf("write %d\n",p[i]);
	}
}

void iic_read_float(U8 devaddr,U8 wordaddr,float *data)
{
	U8 i;
	U8 *p;
	p = (U8*)data;
	for(i=0 ; i<4 ; i++)
	{
		iic_read(devaddr , wordaddr+i , &p[i],1);
		//uart_printf("read %d\n",p[i]);
	}
}



/***********************************************
Function  name  :   test_iic
Description     :   iic 读写测试函数
Input parameter :   none 
Return          :   none	 	
Others		    :                     	                    
*************************************************/

void iic_test(void)
{  
	U32 i,j;
    U8 data[256*4];  
	U8 data2[256*4];

	float temp;
	
 //iic_write(0xa0,9,3);
 //iic_read(0xa0,9,&data[0],1); 
 
#if 1
	//int k=0;
	for(i=0;i<1024;i++)
	   data[i]=i%256;

	uart_printf("write ...\n");
	/*
	for(j=0;j<4;j++)
		for(i=0;i<256;i++)
		{ 
		        iic_write(0xa0|(j<<1),i,data[j*256+i]);
		}
       */
      	for(i=0;i<256;i++)
		{ 
		  iic_write(0xa0,9,3);
		}
		for(i=0;i<256;i++)
		{ 
		  iic_write(0xa2,8,4);
		}
		for(i=0;i<256;i++)
		{ 
		  iic_write(0xa4,7,5);
		}
		for(i=0;i<256;i++)
		{ 
		  iic_write(0xa6,6,6);
		}

	  uart_printf("\n\n");
	 
	  uart_printf("read ...\n");

	// iic_read(0xa0,0,data2,1024);   //连续读
	//*      逐页逐个读
	  for(i=0;i<256;i++)
	  {
	  	iic_read(0xa0,i,&(data2[i]),1); 
	  }
	
	  for(i=0;i<256;i++)
	  {
	    iic_read(0xa2,i,&(data2[i+256]),1); 
	  }
	  for(i=0;i<256;i++)
	  {
	    iic_read(0xa4,i,&(data2[i+256*2]),1); 
	  }
	  for(i=0;i<256;i++)
	  {
	    iic_read(0xa6,i,&(data2[i+256*3]),1); 
	  }//*/


 					   
    for(i=0;i<16*4;i++)
    {
        for(j=0;j<16;j++)
           
            uart_printf("%4x",data2[i*16+j]);
        uart_printf("\n");
    }
    //*/
 
 #endif
 
 #if 0
    iic_write_float(0xa0,0,2.5);
    iic_read_float(0xa0,0,&temp);
    uart_printf("1--temp=%d",(int)(temp*5));
    
 #endif
  
}

头文件  iic.h
<pre name="code" class="cpp">/***********************************************
  Copyright (C),2016-2020,xmetc  Tech. Co., Ltd.  
  FileName: lcd.c  
  Author:lifangguo 
  Version:1.0 
  Date::2016-08-22 
  Description:iic module function  declare  
  History     :   	  
	1  Date	        2016-8-22 
	   Author       li
	   Modification   Init vision 
 ***********************************************/


#ifndef IIC_H
#define IIC_H

#define EEPROMADDR   0xa0

#define WRDATA      (1)
#define POLLACK     (2)
#define RDDATA      (3)
#define SETRDADDR   (4)

void __irq IicInt(void);
extern void iic_init(void);
extern void iic_write(unsigned char devaddr, unsigned char wordaddr, unsigned char data);
extern void iic_read(unsigned char devaddr, unsigned char wordaddr, unsigned char *pdata, unsigned int size);
extern void iic_test(void);

void iic_write_float(U8 devaddr,U8 wordaddr,float data);
void iic_read_float(U8 devaddr,U8 wordaddr,float *data);

#endif


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值