📄 iic.c
字号:
#include <string.h>
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\iic.h"
#include "includes.h"
#define WRDATA (1)
#define POLLACK (2)
#define RDDATA (3)
#define SETRDADDR (4)
#define IICBUFSIZE 0x20
U8 _iicData[IICBUFSIZE];
volatile int _iicDataCount;
volatile int _iicStatus;
volatile int _iicMode;
int _iicPt;
******************************************************************************/
//以下为I2C操作时所需要的变量
INT8U I2C_sla; //I2C器件从地址,
INT8U I2C_suba; //I2C器件内部寄存器地址
INT8U I2C_suba_num; //I2C子地址字节数
INT8U *I2C_buf; //数据缓冲区指针(读操作时会被更改)
INT8U I2C_num; //操作数据个数(会被更改)
INT8U I2C_end; //操作结束标志,为1时表示操作结束,为0xFF时表示操作失败
INT8U I2C_suba_en; //子地址使能控制。
//0--子地址已经处理或者不需要子地址
//1--读取操作
//2--写操作
INT8U data_buf[2] = {0}; //接收I2C数据缓冲区
INT8U glm75_finish = FALSE;
INT32U glm75_count = 0;
INT32U gloop_1 = 0;
/******************************************************************************/
//定义与温度有关的变量
INT8U temp_s = 0x00; //temp_s = temperature sign
INT8U temperature = 0x00;
/******************************************************************************/
void __irq IicInt(void);
void Test_Iic(void)
{
unsigned int i,j;
static U8 data[256];
pISR_IIC=(unsigned)IicInt;
rINTMSK=~(BIT_GLOBAL|BIT_IIC);
rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xf); //Enable interrupt, IICCLK=MCLK/16, Enable ACK
//66Mhz/16/(15+1) = 257Khz
rIICADD=0x10; // S3C44B0X slave address
rIICSTAT=0x10;
Uart_Printf("Read test data from LM75\n");
for(i=0;i<256;i++)
void Query_LM75(void);
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
Uart_Printf("%2x ",data_buf[i*16+j]);
Uart_Printf("\n");
}
}
/*******************************************************************************
函数名称 :I2C_ReadNByte()
函数功能 :从有子地址器件任意地址开始读取N字节数据
入口参数 : sla 器件从地址
suba 器件子地址
s 数据接收缓冲区指针
num 读取的个数
出口参数 : TRUE 操作成功
FALSE 操作失败
说明 :使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
*******************************************************************************/
INT8U I2C_ReadNByte(INT8U sla, INT8U suba, INT8U *s, INT8U num)
{
if (num == 0)
{
return (FALSE);
}
if (glm75_finish == FALSE)
{
I2C_sla = sla + 1; //读操作的器件地址
I2C_suba = suba; //器件子地址
I2C_buf = s; //数据接收缓冲区指针
I2C_num = num; //要读取的个数
I2C_suba_en = 1; //有子地址读
I2C_end = 0;
I2C0CONCLR = 0x2C; //清除STA,SI,AA标志位
I2C0CONSET = 0x60; //置位STA,启动I2C总线
glm75_finish = TRUE;
glm75_count = 0;
}
if (I2C_end == 0)
{
glm75_finish = FALSE;
glm75_count = 0;
return TRUE;
}
else
{
glm75_count++;
if (glm75_count > 1000)
{
glm75_finish = FALSE;
glm75_count = 0;
}
return FALSE;
}
}
/******************************************************************************
函数名称 :void Query_LM75(void)
函数功能 :查询LM75温度传感器的状态
入口参数 :无
出口参数 :无
*******************************************************************************/
void Query_LM75(void)
{
INT8U Temp_H = 0, Temp_L = 0;
gloop_1++;
if (gloop_1 > 20000)
{
if (I2C_ReadNByte(LM75Addr, 0, data_buf, 2) == TRUE) //读LM75当前的温度
{
Temp_H = data_buf[0];
Temp_L = data_buf[1];
temp_s = Temp_H & 0x80;
Temp_H = Temp_H << 1;
Temp_L = Temp_L >> 7;
temperature = Temp_H | Temp_L;
if (temp_s == ZERO_ABOVE)
{
if (temperature > 0x0e)
{
temperature = ((Temp_H | Temp_L) - 0x0e); //温度补偿
}
else
{
temperature = Temp_H | Temp_L;
}
}
}
gloop_1 = 0;
}
}
void __irq IicInt(void)
{
U32 iicSt,i;
rI_ISPC=BIT_IIC;
iicSt=rIICSTAT;
if(iicSt&0x8){} // when bus arbitration is failed.
if(iicSt&0x4){} // when a slave address is matched with IICADD
if(iicSt&0x2){} // when a slave address is 0000000b
if(iicSt&0x1){} // when ACK isn't received
switch(_iicMode)
{
case POLLACK:
_iicStatus=iicSt;
break;
case WRDATA:
if((_iicDataCount--)==0)
{
rIICSTAT=0xd0; //stop MasTx condition
rIICCON=0xaf; //resumes IIC operation.
Delay(1); //wait until stop condtion is in effect.
//The pending bit will not be set after issuing stop condition.
break;
}
rIICDS=_iicData[_iicPt++]; //_iicData[0] has dummy.
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
rIICCON=0xaf; //resumes IIC operation.
break;
case RDDATA:
if((_iicDataCount--)==0)
{
_iicData[_iicPt++]=rIICDS;
rIICSTAT=0x90; //stop MasRx condition
rIICCON=0xaf; //resumes IIC operation.
Delay(1); //wait until stop condtion is in effect.
//too long time...
//The pending bit will not be set after issuing stop condition.
break;
}
_iicData[_iicPt++]=rIICDS;
//The last data has to be read with no ack.
if((_iicDataCount)==0)
rIICCON=0x2f; //resumes IIC operation with NO ACK.
else
rIICCON=0xaf; //resumes IIC operation with ACK
break;
case SETRDADDR:
//Uart_Printf("[S%d]",_iicDataCount);
if((_iicDataCount--)==0)
{
break; //IIC operation is stopped because of IICCON[4]
}
rIICDS=_iicData[_iicPt++];
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
rIICCON=0xaf; //resumes IIC operation.
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -