LPC2148 GPIO模拟I2C(源码)
#include <LPC214X.H>#include "delay.h"
#define USE_FAST_IO
#define GPIO0M 0x00000001
#define GPIO1M 0x00000002
#define SetPortBit(port,bit) port=port|(1<<bit)
#define ClrPortBit(port,bit) port=port&(~(1<<bit))
#define GetPortBit(port,bit) port&(1<<bit)
#define NACK 0
#define SACK1
#define IO_GND (unsigned int)(1<<19)//0x00080000
#define IO_SDA (unsigned int)(1<<21)//0x00200000
#define IO_SCL (unsigned int)(1<<23)//0x00800000
unsigned char f_I2C_Error=0;
//unsigned char GetBit(unsigned char DDRport,unsigned char bit)
#define LSB(a) ((unsigned char)a)
#define MSB(a) ((unsigned char)(a>>8))
//============================================================
void IicBusDelay( void )
{
//delay_us(5);
}
void ClrSCL(void)
{
//P1.19P1.21 P1.23
#ifdef USE_FAST_IO
FIO1DIR=FIO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
FIO1MASK = ~(IO_SCL);
FIO1PIN = 0x00000000;
#else
IO1DIR=IO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
IO1CLR = IO_SCL;
#endif
IicBusDelay();
}
void ClrSDA(void)
{
//P1.19P1.21 P1.23
#ifdef USE_FAST_IO
FIO1DIR=FIO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
FIO1MASK = ~(IO_SDA);
FIO1PIN = 0x00000000;
#else
IO1DIR=IO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
IO1CLR = IO_SDA;
#endif
IicBusDelay();
}
unsigned char GetSDA(void)
{
unsigned int val;
//P1.19P1.21 P1.23
#ifdef USE_FAST_IO
FIO1DIR=FIO1DIR&(~(IO_SDA));
FIO1DIR=FIO1DIR|(IO_SCL)|(IO_GND);
FIO1MASK = ~(IO_SDA);
delay_us(1);
val=FIO1PIN;
#else
IO1DIR=IO1DIR&(~(IO_SDA));
IO1DIR=IO1DIR|(IO_SCL)|(IO_GND);
delay_us(1);
val=IO1PIN;
#endif
val=val & IO_SDA;
if(val)
return 1;
else
return 0;
}
unsigned char GetSCL(void)
{
unsigned int val;
//P1.19P1.21 P1.23
#ifdef USE_FAST_IO
FIO1DIR=FIO1DIR&(~(IO_SCL));
FIO1DIR=FIO1DIR|(IO_SDA)|(IO_GND);
FIO1MASK = ~(IO_SCL);
delay_us(1);
val=FIO1PIN;
#else
IO1DIR=IO1DIR&(~(IO_SCL));
IO1DIR=IO1DIR|(IO_SDA)|(IO_GND);
delay_us(1);
val=IO1PIN;
#endif
val=val & IO_SCL;
if(val)
return 1;
else
return 0;
}
void SetSCL(void)
{
unsigned char chr1;
#ifdef USE_FAST_IO
FIO1DIR=FIO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
FIO1MASK = ~(IO_SCL);
FIO1PIN = IO_SCL;
#else
IO1DIR=IO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
IO1SET = IO_SCL;
#endif
if( GetSCL() == 1 ) return ;
for(chr1=0; chr1<255; chr1++) // 为避免数据传送时受IIC总线上大电容(100-1000P)的影响,以及适应某些反应速度慢的IC在做出反应前拉低SCL的做法
if( GetSCL() == 1 ) break ;
}
void SetSDA(void)
{
unsigned char chr1;
#ifdef USE_FAST_IO
FIO1DIR=FIO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
FIO1MASK = ~(IO_SDA);
FIO1PIN = IO_SDA;
#else
IO1DIR=IO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
IO1SET = IO_SDA;
#endif
if( GetSDA() == 1 ) return ;
for(chr1=0; chr1<255; chr1++) // 为避免数据传送时受IIC总线上大电容(100-1000P)的影响,以及适应某些反应速度慢的IC在做出反应前拉低SCL的做法
if( GetSDA() == 1 ) break ;
}
void ACK(unsigned char ack)
{
if(!ack)//非应答
SetSDA();
else //应答
ClrSDA();
IicBusDelay();
SetSCL();
IicBusDelay();
ClrSCL();
IicBusDelay();
}
void I2CInit(void)
{
f_I2C_Error=0;
PINSEL2=PINSEL2&0xfffffff7;//P1.25 -16 用作GPIO 管脚
PINSEL2=PINSEL2|0x00000004;//P1.31 - 26 用作一个调试端口
//P1.19P1.21 P1.23
#ifdef USE_FAST_IO
SCS |= GPIO1M; /* set GPIOx to use Fast I/O */
FIO1DIR=FIO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
FIO1MASK = ~(IO_GND);
FIO1PIN = 0x00000000;
#else
IO1DIR=IO1DIR|(IO_SCL)|(IO_SDA)|(IO_GND);
IO1CLR = IO_GND;
#endif
}
void IicStart(void)
{
f_I2C_Error=0;
IicBusDelay();
SetSDA();
IicBusDelay();
SetSCL();
IicBusDelay();
if( GetSDA()==0)
{
f_I2C_Error = 1 ;
return ;
}
if( GetSCL()==0 )
{
f_I2C_Error = 1 ;
return ;
}
ClrSDA();
IicBusDelay();
ClrSCL();
IicBusDelay();
}
void IicStop( void )
{
IicBusDelay();
ClrSDA();
IicBusDelay();
SetSCL();
IicBusDelay();
SetSDA();
IicBusDelay();
}
void IicSendByte(unsigned char chr)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(chr&0x80)
SetSDA();
else
ClrSDA();
SetSCL();
IicBusDelay();
ClrSCL();
chr<<=1;
IicBusDelay();
}
IicBusDelay();
SetSDA();
IicBusDelay();
SetSCL();
IicBusDelay();
if(GetSDA())
f_I2C_Error=1; //失败
else
f_I2C_Error=0;
ClrSCL();
IicBusDelay();
}
unsigned char IicReceiveByte(unsigned char ack)
{
unsigned char i,rval;
rval=0;
SetSDA();
for(i=0;i<8;i++)
{
IicBusDelay();
ClrSCL();
IicBusDelay();
SetSCL();
IicBusDelay();
rval<<=1;
if(GetSDA())
rval++;
}
ClrSCL();
IicBusDelay();
ACK(ack);
return(rval);
} * *备注:所有函数在12m频率以上都比较准确,注意头文件里Fclk的设置
****************************************************************/
#include "delay.h"
/**********************************************************************
**函数名称:delay_s()
**函数功能:秒级延时,注意设置delay.h中的Fclk
**函数入口:t
**函数出口:无
***********************************************************************/
void delay_s(unsigned long int t)
{
unsigned long int i;
unsigned long int j;
j=Fclk*t;
for(i = 0; i < j; i++);
}
/**********************************************************************
**函数名称:delay_ms()
**函数功能:毫秒级延时,注意设置delay.h中的Fclk
**函数入口:t
**函数出口:无
***********************************************************************/
void delay_ms(unsigned long int t)
{
unsigned long int i;
unsigned long int j;
j=Fclk/1000*t;
for(i = 0; i < j; i++);
}
/**********************************************************************
**函数名称:delay_us()
**函数功能:微秒级延时,注意设置delay.h中的Fclk
**函数入口:t
**函数出口:无
***********************************************************************/
void delay_us(unsigned long int t)
{
unsigned long int i;
unsigned long int j;
j=Fclk/1000000*t;
for(i = 0; i < j; i++);
} #ifndef __delay_H
#define __delay_H
#defineFclk 60000000
//**********************函数声明***************************
void delay_s (unsigned long int t);
void delay_ms(unsigned long int t);
void delay_us(unsigned long int t);
//*********************************************************
#endif 好用的就顶一下 我认为函数的返回不应该放到全局变量中。以启动条件为例:
void IicStart(void)
{
f_I2C_Error=0;
IicBusDelay();
SetSDA();
IicBusDelay();
SetSCL();
IicBusDelay();
if( GetSDA()==0)
{
f_I2C_Error = 1 ;
return ;
}
if( GetSCL()==0 )
{
f_I2C_Error = 1 ;
return ;
}
ClrSDA();
IicBusDelay();
ClrSCL();
IicBusDelay();
}
可改为:
unsigned char IicStart(void)
{
IicBusDelay();
SetSDA();
IicBusDelay();
SetSCL();
IicBusDelay();
if( GetSDA()==0)
{
return 1;
}
if( GetSCL()==0 )
{
return 1;
}
ClrSDA();
IicBusDelay();
ClrSCL();
IicBusDelay();
return 0;
} mark mark 开发工具用的是什么? 不错,学习一下!!!!!!!!!!!!! mark
页:
[1]