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

📄 i2cint.c

📁 ARM I2C 通讯软件(中断方式),通过此程序
💻 C
字号:
/****************************************Copyright (c)**************************************************
** File:i2cint
** Created By: zhangacai
** Created date: 2008-05-28 
** Version: v1.0
** Descriptions: i2c function
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "hw_i2c.h"
#include "gpio.h"
#include "sysctl.h"
#include "i2c.h"
#include "interrupt.h"
#include "define.c"

/******************************************************************************************
**     Delays (dly) 
**	   About 1 seconds while dly==35
******************************************************************************************/
void Delays (ulong dly)
{
	int i,j;
	for (; dly>0; dly--)
	{
		for (i=0; i<150; i++)
		     for (j=0; j<255; j++)HWREG(WATCHDOG_BASE + WDT_O_ICR) = WDT_INT_TIMEOUT; 
	}
}

/***********************************************************************************************
**     I2CInit()
**     I2C port initialize
**     spd	speed (100000 or 400000)
**     pri		INT priority (0~7)
**	   Return ture or false
*************************************************************************************************/
int I2CInit(ulong spd, uchar pri)
{	 
	if ((spd == 400000) || (spd == 100000))
	{
    	
       
		//SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
		
    	// Set port pin
    	GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);

    	// Initialize master
    	if(spd == 400000)
    		I2CMasterInit(I2C_MASTER_BASE, true);
		else
			I2CMasterInit(I2C_MASTER_BASE, false);
		
    	// Enable master
    	IntMasterEnable();
    	
    	// Enable I2C INT
    	IntEnable(INT_I2C);

    	// Enable I2C master INT
    	I2CMasterIntEnable(I2C_MASTER_BASE);
    	
    	// Set INT priority
    	IntPrioritySet(INT_I2C, (pri << 5));
    
    	return(true);
    }
    else
    	return(false);
}

/*******************************************************************************************
**    I2C_ISR()
**    I2C INT process 
*******************************************************************************************/
void I2C_ISR (void)
{	
   I2CMasterIntClear(I2C_MASTER_BASE);		// Clear I2C INT flag
    switch(I2C_state)
    {
        // Free state
        case STATE_IDLE:
        {
            break;
        }
        // After sent one byte
        case STATE_WRITE_ONE:
        {
        	I2C_state = STATE_IDLE;
        	break;
        }
		// Send next data
        case STATE_WRITE_NEXT:
        {
        	// Send next data to register
            if(I2C_suba_num != 0)
            {
            	I2C_suba_num--;
            	I2CMasterDataPut(I2C_MASTER_BASE, 
            					(I2C_suba >> (8 * I2C_suba_num)));
            	if((I2C_suba_num == 0) && I2C_opt == 1)
            	{
            		if(I2C_num == 1)
            			I2C_state = STATE_READ_ONE;	
            		else
            			I2C_state = STATE_READ_FIRST;	
            	}
            	
            }            
			else
            {
             	I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf++);
            	I2C_num--;             
            	if(I2C_num == 1)
            	{
                	I2C_state = STATE_WRITE_FINAL;
            	}          
            }
            // Countinuing block send
            I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
            break;
        }
        // Send last data
        case STATE_WRITE_FINAL:
        {
            I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf);
            I2C_num--;
            // Stop send
            I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
			// Will complete next block send
            I2C_state= STATE_IDLE;
            break;
        }
 
 		// Read one byte
        case STATE_READ_ONE:
        {

            I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true);

            I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

            I2C_state= STATE_READ_WAIT;

            break;
        }
		// Start read muti bytes
        case STATE_READ_FIRST:
        {

            I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true);

            I2CMasterControl(I2C_MASTER_BASE,
                             I2C_MASTER_CMD_BURST_RECEIVE_START);

            if(I2C_num == 2)
                I2C_state = STATE_READ_FINAL;
            else
            	I2C_state = STATE_READ_NEXT;

            break;
        }
		// Read next byte
        case STATE_READ_NEXT:
        {

            *I2C_buf++ = I2CMasterDataGet(I2C_MASTER_BASE);
            I2C_num--;

            I2CMasterControl(I2C_MASTER_BASE,
                             I2C_MASTER_CMD_BURST_RECEIVE_CONT);

            if(I2C_num == 2)
                I2C_state = STATE_READ_FINAL;

            break;
        }
		// Read the last byte
        case STATE_READ_FINAL:
        {

            *I2C_buf++ = I2CMasterDataGet(I2C_MASTER_BASE);
            I2C_num--;

            I2CMasterControl(I2C_MASTER_BASE,
                             I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

            I2C_state= STATE_READ_WAIT;
            break;
        }
		// Wait for read a byte
        case STATE_READ_WAIT:
        {
 
            *I2C_buf++  = I2CMasterDataGet(I2C_MASTER_BASE); 
            I2C_num--;

            I2C_state= STATE_IDLE;
            break;
        }
    }
}

/*
*********************************************************************************************************
**    ISendByte()
**    Send one Byte to device with no subaddress
**    sla:device slave address
**    c:The data will be sent
**    Return ture or false	
*********************************************************************************************************
*/ 
int ISendByte(uchar sla, uchar c)
{	
	I2C_sla = sla >> 1;
	I2C_buf = &c;
	I2C_state = STATE_WRITE_ONE;
	
	I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);			
	I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf);				
    I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
	   Delays(1);
	while(I2C_state != STATE_IDLE);
	 
	if(true == I2CMasterBusy(I2C_MASTER_BASE))
		return (false);
	else
		return (true);
}

/**********************************************************************************************
**    ISendStr()** 
**    sla;Device slave address		
**    suba:Subaddress
**    suba_type:Subaddress type, 8+X,one byte,two byte,three byte	 			
**	  s;Pointer		
**	  no:Data number			
**    Return ture or false
************************************************************************************************/ 
int ISendStr(uchar sla, ulong suba, uchar sub_type, uchar *s, ulong no)
{		
	I2C_sla = sla >> 1;
	I2C_buf = s;
	I2C_num = no;
	I2C_suba = suba;
	
	switch(sub_type)
	{
		// “8+x”
		case 0:
			I2C_sla = I2C_sla | ((suba >> 8) & 0x07);
			I2C_suba_num = 1;
			break;	
		// one byte 	
		case 1:
			I2C_suba_num = 1;	
			break;
		// two byte
		case 2:
			I2C_suba_num = 2;	
			break;
		// three byte
		case 3:
			I2C_suba_num = 3;	
			break;
		default: break;
	}
	
	if((no == 1) && (I2C_suba_num == 1))
		I2C_state = STATE_WRITE_FINAL;	// one byte or 8+X subaddress send one byte data
	else
		I2C_state = STATE_WRITE_NEXT;	// Muti byte subaddress send multi byte data	
						
	I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);											
    I2C_suba_num--;
    I2CMasterDataPut(I2C_MASTER_BASE, 
    				(I2C_suba >> (8 * I2C_suba_num)));			// send subaddress HI byte
    I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
     	Delays(1);
	while(I2C_state != STATE_IDLE);
	  
	if(true == I2CMasterBusy(I2C_MASTER_BASE))	
		
		return (true);
	else
		return (true);
		 
}

/*
*********************************************************************************************************
**    ISendStrExt()
**    send muti data to device with no subaddress 
**    sla:Device slave address
**    s:pointer
**    no: Byte number will be sent
**    Return ture or false
*********************************************************************************************************
*/ 
int ISendStrExt(uchar sla, uchar *s, uchar no)
{
	I2C_sla = sla >> 1;
	I2C_buf = s;
	I2C_num = no;
	if (no > 1)							
	{
		if(no == 2)
			I2C_state = STATE_WRITE_FINAL;
		else
			I2C_state = STATE_WRITE_NEXT;
	
		I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);
    	I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf++);
    	I2C_num--;
    	I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
          Delays(1);
		while(I2C_state != STATE_IDLE);
		  
		if(true == I2CMasterBusy(I2C_MASTER_BASE))
			return (false);
		else
			return (true);
	}
	else 
		return(false);
}

/*
*********************************************************************************************************
**    IRcvByte()
**    Read one byte from device with no subaddress 
**    sla:Device slave address
**    c:pointer
**    Return ture or false
*********************************************************************************************************
*/
int IRcvByte(uchar sla, uchar *c)
{	
	I2C_sla = sla >> 1;
	I2C_buf = c;
	I2C_state = STATE_READ_WAIT;
	
	I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true);	// 主机读操作
	I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);// 启动单次读取
	    Delays(1);
	while(I2C_state != STATE_IDLE);
	  
	if(true == I2CMasterBusy(I2C_MASTER_BASE))
		return (false);
	else
		return (true);
}

/**********************************************************************************************
**    IRcvStr()
**    Read N byte data from device with subaddress
**    sla:Device slave address
**	  suba_type:8+X,one byte, two bytes, three bytes 
**	  suba:Subaddress
**	  s:pointer
**	  no;Data number
**    Return ture or false
***********************************************************************************************/
int IRcvStr(uchar sla, ulong suba, uchar sub_type, uchar *s, uchar no)
{	
	I2C_sla = sla >> 1;
	I2C_buf = s;
	I2C_num = no;
	I2C_suba = suba;
	I2C_opt = 1;
	
	switch(sub_type)
	{
		// 8+X
		case 0:
			I2C_sla = I2C_sla | ((suba >> 8) & 0x07);
			I2C_suba_num = 1;
			break;	
		// 1 byte 	
		case 1:
			I2C_suba_num = 1;	
			break;
		//2 bytes
		case 2:
			I2C_suba_num = 2;	
			break;
		// 3 bytes
		case 3:
			I2C_suba_num = 3;	
			break;
		default: break;
	}
	
	if(I2C_suba_num == 1)
	{
		if(I2C_num == 1)
			I2C_state = STATE_READ_ONE;
		else 
		 	I2C_state = STATE_READ_FIRST;
	}
	else
		I2C_state = STATE_WRITE_NEXT;
						
	I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);									
    I2C_suba_num--;
    I2CMasterDataPut(I2C_MASTER_BASE, 
    				(I2C_suba >> (8 * I2C_suba_num)));			// Send Hi byte of subaddress
    I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
       Delays(1);
	while(I2C_state != STATE_IDLE);
	  
	if(true == I2CMasterBusy(I2C_MASTER_BASE))
		return (false);
	else
		return (true);	 
} 

/***********************************************************************************************
**    IRvcStrExt()
**    Read N bytes data from devices with no subaddress 
**    sla: Device slave address
**    s: Pointer
**	  no: Data number
**    Return true or false
************************************************************************************************/
int IRvcStrExt(uchar sla, uchar *s, uchar no)
{
	I2C_sla = sla >> 1;
	I2C_buf = s;
	I2C_num = no;
	
	if(I2C_num > 1)
	{
		if(I2C_num == 2)
			I2C_state = STATE_READ_FINAL;
		else
			I2C_state = STATE_READ_NEXT;
			
		I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true);
    	I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
		   Delays(1);
		while(I2C_state != STATE_IDLE);
		
		if(true == I2CMasterBusy(I2C_MASTER_BASE))
			return (false);
		else
			return (true);
	}
	else
		return (false);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -