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