?? i2cio.c
字號:
/* File: I2CIO.C */
/****************************************************************************
*
* STK16X.I2CIO
* ============
*
* Low level routines for I2C bus control
*
* TQ-Systems GmbH
* ---------------
* Customer: TQ-Components
* Project : STK16XSW
* Tools : uVision 2.05
*
*
* Rev: Date: Name: Modification:
* ----+---------+----------------+------------------------------------------
* 100 16.01.01 A. Lichte taken over from STK16X.506
*****************************************************************************/
/****************************************************************************
*
* availability summary
*
* available for Starterkit: STK16X
* conformed for Starterkit: STK16X
* available for Modul : TQM164 TQM165 TQM165U TQM166 TQM167
* TQM167LC TQM167U TQM167UL
* conformed for Modul : TQM164 TQM165 TQM165U TQM166 TQM167
* TQM167LC TQM167U TQM167UL
*****************************************************************************/
/*==========================================================================*
* pragmas:
*===========================================================================*/
/*=========================================================================*
* include files (#INCLUDE):
*==========================================================================*/
/*-------------------------------------------------------------------------*
* standard include files:
*--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <ctype.h> /* typecast functions */
#include <string.h> /* string functions */
#include <setjmp.h> /* global jump functions */
#include <stdio.h> /* standard I/O functions */
#include <absacc.h> /* absolute accesss */
#include <intrins.h> /* Intrinsic functions */
#include <stdarg.h>
#include <reg167.h> /* special function register */
/*-------------------------------------------------------------------------*
* project specific include files:
*--------------------------------------------------------------------------*/
#include "timer.h"
#include "i2cio.h"
/*==========================================================================*
* module internal definitions (#DEFINE):
*===========================================================================*/
sbit I2C_SCL = P3^0;
sbit I2C_SCL_DIR = DP3^0;
sbit I2C_SDA = P3^1;
sbit I2C_SDA_DIR = DP3^1;
sbit I2C_SCL_164 = P8^0;
sbit I2C_SCL_DIR_164 = DP8^0;
sbit I2C_SDA_164 = P8^1;
sbit I2C_SDA_DIR_164 = DP8^1;
/*==========================================================================*
* module internal type declarations (TYPEDEF):
*===========================================================================*/
/*==========================================================================*
* module internal constants (CONST):
*===========================================================================*/
#define TSU_STA 5 // minimum required setup time for start condition in us
#define THD_STA 5 // minimum required hold time for start condition in us
#define TSU_STO 5 // minimum required setup time for stop condition in us
#define TCL_LOW 5 // minimum required time for SCL HIGH in us
#define TCL_HIGH 5 // minimum required time for SCL LOW in us
/*==========================================================================*
* extern available constants (CONST):
*===========================================================================*/
/*==========================================================================*
* modul internal variables:
*===========================================================================*/
/*==========================================================================*
* globale external available variables (EXTERN):
*===========================================================================*/
/*==========================================================================*
* modul internal functions:
*===========================================================================*/
/*--------------------------------------------------------------------------*
* void loop_delay_us(USHORT len)
*---------------------------------------------------------------------------*
* FT: generate delay for "len" us (no precise timer, for developing only!)
* EP: -
* RW: -
* GP: -
*---------------------------------------------------------------------------*/
void loop_delay_us(USHORT len)
{
while(len--);
}
/*--------------------------------------------------------------------------*
* void i2c_start(void)
*---------------------------------------------------------------------------*
* FT: start new I2C bus cycle
* EP: -
* RW: -
* GP: -
*---------------------------------------------------------------------------*/
void i2c_start(void)
{
if (TQMMOD == TQM164)
{
I2C_SCL_164 = 0;
I2C_SCL_DIR_164 = 1;
I2C_SDA_164 = 1; // start condition for I2C:
I2C_SDA_DIR_164 = 1;
I2C_SCL_164 = 1; // (HIGH to LOW transition of SDA while SCL is HIGH)
loop_delay_us(TSU_STA);
I2C_SDA_164 = 0;
loop_delay_us(THD_STA);
I2C_SCL_164 = 0;
I2C_SDA_DIR_164 = 0; // set I2C data line as input
I2C_SDA_164 = 1;
}
else
{
I2C_SCL = 0;
I2C_SCL_DIR = 1;
I2C_SDA = 1; // start condition for I2C:
I2C_SDA_DIR = 1;
I2C_SCL = 1; // (HIGH to LOW transition of SDA while SCL is HIGH)
loop_delay_us(TSU_STA);
I2C_SDA = 0;
loop_delay_us(THD_STA);
I2C_SCL = 0;
I2C_SDA_DIR = 0; // set I2C data line as input
I2C_SDA = 1;
}
}
/*--------------------------------------------------------------------------*
* void i2c_stop(void)
*---------------------------------------------------------------------------*
* FT: stop I2C bus cycle
* EP: -
* RW: -
* GP: -
*---------------------------------------------------------------------------*/
void i2c_stop(void)
{
if (TQMMOD == TQM164)
{
I2C_SCL_164 = 0;
I2C_SCL_DIR_164 = 1; // set I2C clock line as output
I2C_SDA_164 = 0; // stop condition for I2C:
I2C_SDA_DIR_164 = 1; // set I2C data line as output
I2C_SCL_164 = 1; // (LOW to HIGH transition of SDA while SCL is HIGH)
loop_delay_us(TSU_STA);
I2C_SDA_164 = 1;
loop_delay_us(THD_STA);
I2C_SCL_164 = 0;
I2C_SDA_164 = 1;
I2C_SDA_DIR_164 = 0; // set I2C data line as input
I2C_SCL_DIR_164 = 0; // set I2C clock line as input
}
else
{
I2C_SCL = 0;
I2C_SCL_DIR = 1; // set I2C clock line as output
I2C_SDA = 0; // stop condition for I2C:
I2C_SDA_DIR = 1; // konfiguriere I2C-Datenleitung als Ausgang
I2C_SCL = 1; // (LOW-to-HIGH transition of SDA while SCL is HIGH)
loop_delay_us(TSU_STA);
I2C_SDA = 1;
loop_delay_us(THD_STA);
I2C_SCL = 0;
I2C_SDA = 1;
I2C_SDA_DIR = 0; // set I2C data line as input
I2C_SCL_DIR = 0; // set I2C clock line as input
}
}
/*--------------------------------------------------------------------------*
* BYTE i2c_receive_frame(void)
*---------------------------------------------------------------------------*
* FT: read 8 bit frame from I2C-Bus and send acknowledge
* EP: -
* RW: -
* GP: -
*---------------------------------------------------------------------------*/
BYTE i2c_receive_frame(void)
{ BYTE i;
BYTE frame; /* data frame to be read from I2C bus */
if(TQMMOD == TQM164)
{
I2C_SDA_DIR_164 = 0; // set I2C data line as input
for(i=0; i<8; i++) // 8 bit read accces as I2C bus master
{
I2C_SCL_164 =0;
loop_delay_us(TCL_LOW);
frame = frame << 1;
frame |=(I2C_SDA_164&0x01);
I2C_SCL_164 = 1;
loop_delay_us(TCL_HIGH);
}
I2C_SCL_164 = 0;
loop_delay_us(TCL_LOW);
i = I2C_SDA_164; // send acknowledge to I2C bus slave
I2C_SCL_164 = 1;
loop_delay_us(TCL_LOW);
I2C_SCL_164 = 0;
return (frame);
}
else
{
I2C_SDA_DIR = 0; // set I2C data line as output
for(i=0; i<8; i++) // 8 bit read accces as I2C bus master
{
I2C_SCL = 0;
loop_delay_us(TCL_LOW);
frame = frame << 1;
frame |= (I2C_SDA&0x01);
I2C_SCL = 1;
loop_delay_us(TCL_HIGH);
}
I2C_SCL = 0;
loop_delay_us(TCL_LOW);
i = I2C_SDA; // send acknowledge to I2C bus slave
I2C_SCL = 1;
loop_delay_us(TCL_LOW);
I2C_SCL = 0;
return (frame);
}
}
/*--------------------------------------------------------------------------*
* BOOL i2c_send_frame(BYTE frame)
*---------------------------------------------------------------------------*
* FT: send 8 bit data to I2C bus and check acknowledge
* EP: frame = data to be sent to I2C bus
* RW: TRUE = function successfully; FALSE = function failed (no acknowledge)
* GP: -
*---------------------------------------------------------------------------*/
BOOL i2c_send_frame(BYTE frame)
{ BYTE i;
if (TQMMOD == TQM164)
{
I2C_SDA_DIR_164 = 1; // set I2C data line as output
for(i=(1<<7); i>0; i=(i>>1)) // 8 bit write acccess as I2C bus master
{
I2C_SDA_164 = ((frame & i) != 0);
loop_delay_us(TCL_LOW);
I2C_SCL_164 = 1;
loop_delay_us(TCL_HIGH);
I2C_SCL_164 = 0;
}
I2C_SDA_DIR_164 = 0; // set I2C data line as input
loop_delay_us(TCL_LOW);
I2C_SCL_164 = 1;
i = !I2C_SDA_164; // read acknowledge from I2C slave
I2C_SCL_164 = 0;
return (i);
}
else
{
I2C_SDA_DIR = 1; // set I2C data line as output
for(i=(1<<7); i>0; i=(i>>1)) // 8 bit write acccess as I2C bus master
{
I2C_SDA = ((frame & i) != 0);
loop_delay_us(TCL_LOW);
I2C_SCL = 1;
loop_delay_us(TCL_HIGH);
I2C_SCL = 0;
}
I2C_SDA_DIR = 0; // set I2C data line as input
loop_delay_us(TCL_LOW);
I2C_SCL = 1;
i = !I2C_SDA; // read acknowledge from I2C slave
I2C_SCL = 0;
return (i);
}
}
/*==========================================================================*
* extern available functions:
*===========================================================================*/
/*--------------------------------------------------------------------------*
* BOOL i2c_write(BYTE adr, USHORT data, ...)
*---------------------------------------------------------------------------*
* FT: write data to I2C bus
* EP: adr = I2C bus address of receiver
* data = 1st argument: number of n bytes to be written (n)
2nd..(n+1)nd argument: data bytes to be written
* RV: TRUE = function succesfully; FALSE = function failed
* GP: -
*---------------------------------------------------------------------------*/
BOOL i2c_write(BYTE adr, USHORT data, ...)
{ USHORT *pdata = &data+1;
USHORT count = data;
i2c_start();
/* send I2C bus address and prepare write access: */
if (!i2c_send_frame((adr << 1)) & 0xFE)
{
i2c_stop();
return (FALSE);
}
while (count--)
{
if (!i2c_send_frame((BYTE)*pdata++)) // write data to I2C bus
{
i2c_stop();
return FALSE;
}
}
i2c_stop();
return (TRUE);
}
/*--------------------------------------------------------------------------*
* BOOL i2c_read(BYTE adr, USHORT count, USHORT *pdata, ...)
*---------------------------------------------------------------------------*
* FT: read data from I2C bus
* EP: adr = I2C bus address of slave to read from
* count = number of bytes to be read
* pdata = pointer to data to be read
* RV: TRUE = function succesfully; FALSE = function failed
* GP:
*---------------------------------------------------------------------------*/
BOOL i2c_read(BYTE adr, USHORT count, USHORT *pdata, ...)
{
i2c_start();
/* send I2C bus address and prepare read access: */
if (!i2c_send_frame((adr << 1) | 0x01))
{
i2c_stop();
return (FALSE);
}
while(count--)
{
*(pdata++) = (USHORT) i2c_receive_frame(); // read data from I2C bus
}
i2c_stop();
return (TRUE);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -