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

📄 i2c.c

📁 老外写得最新arm 库很多值得学习的基于mcu得c函数写法
💻 C
字号:
/*! \file i2c.c \brief I2C interface using Philips LPC internal I2C hardware. */
//*****************************************************************************
//
// File Name	: 'i2c.c'
// Title		: I2C interface using Philips LPC internal I2C hardware
// Author		: Pascal Stang - Copyright (C) 2004
// Created		: 2004.05.05
// Revised		: 2004.07.12
// Version		: 0.9
// Target MCU	: ARM, Philips LPC2100-series
// Editor Tabs	: 4
//
// Description : I2C (pronounced "eye-squared-see") is a two-wire bidirectional
//		network designed for easy transfer of information between a wide variety
//		of intelligent devices.  Many of the Atmel AVR series processors have
//		hardware support for transmitting and receiving using an I2C-type bus.
//		In addition to the AVRs, there are thousands of other parts made by
//		manufacturers like Philips, Maxim, National, TI, etc that use I2C as
//		their primary means of communication and control.  Common device types
//		are A/D & D/A converters, temp sensors, intelligent battery monitors,
//		MP3 decoder chips, EEPROM chips, multiplexing switches, etc.
//
//		I2C uses only two wires (SDA and SCL) to communicate bidirectionally
//		between devices.  I2C is a multidrop network, meaning that you can have
//		several devices on a single bus.  Because I2C uses a 7-bit number to
//		identify which device it wants to talk to, you cannot have more than
//		127 devices on a single bus.
//
//		I2C ordinarily requires two 4.7K pull-up resistors to power (one each on
//		SDA and SCL), but for small numbers of devices (maybe 1-4), it is enough
//		to activate the internal pull-up resistors in the AVR processor.  To do
//		this, set the port pins, which correspond to the I2C pins SDA/SCL, high.
//		For example, on the mega163, sbi(PORTC, 0); sbi(PORTC, 1);.
//
//		For complete information about I2C, see the Philips Semiconductor
//		website.  They created I2C and have the largest family of devices that
//		work with I2C.
//
// Note: Many manufacturers market I2C bus devices under a different or generic
//		bus name like "Two-Wire Interface".  This is because Philips still holds
//		"I2C" as a trademark.  For example, SMBus and SMBus devices are hardware
//		compatible and closely related to I2C.  They can be directly connected
//		to an I2C bus along with other I2C devices are are generally accessed in
//		the same way as I2C devices.  SMBus is often found on modern motherboards
//		for temp sensing and other low-level control tasks.
//
// This code is distributed under the GNU Public License
//		which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************

#include "lpc2000.h"
#include "global.h"
#include "timer.h"
#include "i2c.h"

void i2cInit(void)
{
	// setup SCL pin P02
	PINSEL0 &= ~(3<<4);
	PINSEL0 |=   1<<4;
	// setup SDA pin P03
	PINSEL0 &= ~(3<<6);
	PINSEL0 |=   1<<6;

	// set default bitrate of 100KHz
	i2cSetBitrate(400);

	// disable and reset interface
	I2CONCLR = 0xFF;
	delay(10);

	// enable interface
	I2CONSET = BIT(I2CON_I2EN);
}
/*
void InitialiseI2C(void)
{

REG(I2C_I2SCLL) = 0x18;

REG(I2C_I2SCLH) = 0x18;

REG(I2C_I2CONCLR) = 0xFF;

// Set pinouts as scl and sda
REG(PCB_PINSEL0) = 0x50;

REG(I2C_I2CONSET) = 0x40;
delay(10);
REG(I2C_I2CONSET) = 0x64;

REG(I2C_I2DAT) = 0x42;

REG(I2C_I2CONCLR) = 0x08;

REG(I2C_I2CONCLR) = 0x20;

}
*/

void i2cSetBitrate(u16 bitrateDiv)
{
	// @60MHz and VPB=2, set to 75 for 400KHz
	// @60MHz and VPB=2, set to 400 for 75KHz
	// set equal high and low periods
	I2SCLL = bitrateDiv;
	I2SCLH = bitrateDiv;
}

void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
{
	// set local device address (used in slave mode only)
	I2ADR = ((deviceAddr&0xFE) | (genCallEn?1:0));
}

void i2cSendStart(void)
{
	I2CONSET = BIT(I2CON_STA);
	I2CONCLR = BIT(I2CON_SI);
}

void i2cSendStop(void)
{
	I2CONSET = BIT(I2CON_STO);
	I2CONCLR = BIT(I2CON_SI);
}

void i2cWaitForComplete(void)
{
	// wait for a valid status code
	while(I2STAT == TW_NO_INFO);
}

void i2cSendByte(u08 data)
{
	// save data into data register
	I2DAT = data;
	// clear SI bit to begin transfer
	I2CONCLR = BIT(I2CON_SI);
}

void i2cReceiveByte(u08 ackFlag)
{
	// begin receive over i2c
	if( ackFlag )
	{
		// ackFlag = TRUE: ACK the recevied data
		I2CONSET = BIT(I2CON_AA);
		//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
	}
	else
	{
		// ackFlag = FALSE: NACK the recevied data
		I2CONCLR = BIT(I2CON_AA);
		//outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
	}
	// clear SI bit to begin transfer
	I2CONCLR = BIT(I2CON_SI);
}

u08 i2cGetReceivedByte(void)
{
	return I2DAT;
}

u08 i2cGetStatus(void)
{
	return I2STAT;
}


u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
{
	u08 retval = I2C_OK;

	// disable TWI interrupt
	//cbi(TWCR, TWIE);

	// send start condition
	i2cSendStart();
	i2cWaitForComplete();
	I2CONCLR = BIT(I2CON_STA);

	// send device address with write
	i2cSendByte( deviceAddr & 0xFE );
	i2cWaitForComplete();

	// check if device is present and live
	if( I2STAT == TW_MT_SLA_ACK)
	{
		// send data
		while(length)
		{
			i2cSendByte( *data++ );
			i2cWaitForComplete();
			length--;
		}
	}
	else
	{
		// device did not ACK it's address,
		// data will not be transferred
		// return error
		retval = I2C_ERROR_NODEV;
	}

	// transmit stop condition
	// leave with TWEA on for slave receiving
//	I2CONSET = BIT(I2CON_STA);
//	delay(10);
//	I2CONCLR = BIT(I2CON_STO);
	i2cSendStop();
	//while( !(inb(TWCR) & BV(TWSTO)) );

	// enable TWI interrupt
	//sbi(TWCR, TWIE);

	return retval;
}

u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data)
{
	u08 retval = I2C_OK;

	// disable TWI interrupt
	///cbi(TWCR, TWIE);

	// send start condition
	i2cSendStart();
	i2cWaitForComplete();
	I2CONCLR = BIT(I2CON_STA);

	// send device address with read
	i2cSendByte( deviceAddr | 0x01 );
	i2cWaitForComplete();

	// check if device is present and live
	if( I2STAT == TW_MR_SLA_ACK)
	{
		// accept receive data and ack it
		while(length > 1)
		{
			i2cReceiveByte(TRUE);
			i2cWaitForComplete();
			*data++ = i2cGetReceivedByte();
			// decrement length
			length--;
		}

		// accept receive data and nack it (last-byte signal)
		i2cReceiveByte(FALSE);
		i2cWaitForComplete();
		*data++ = i2cGetReceivedByte();
	}
	else
	{
		// device did not ACK it's address,
		// data will not be transferred
		// return error
		retval = I2C_ERROR_NODEV;
	}

	// transmit stop condition
	// leave with TWEA on for slave receiving
	i2cSendStop();

	// enable TWI interrupt
	//sbi(TWCR, TWIE);

	return retval;
}

⌨️ 快捷键说明

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