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

📄 iic.c

📁 这是一个IIC程序,已通过测试,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 + -