搜索
bottom↓
回复: 9

LPC2148 GPIO模拟I2C(源码)

[复制链接]

出0入0汤圆

发表于 2008-7-29 11:00:42 | 显示全部楼层 |阅读模式
#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 SACK  1

#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.19  P1.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.19  P1.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.19  P1.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.19  P1.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.19  P1.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);  
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2008-7-29 11:02:32 | 显示全部楼层
* *备  注:所有函数在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++);
    }

出0入0汤圆

 楼主| 发表于 2008-7-29 11:04:29 | 显示全部楼层
#ifndef __delay_H
#define __delay_H
#define  Fclk    60000000
//**********************函数声明***************************
void delay_s (unsigned long int t);
void delay_ms(unsigned long int t);
void delay_us(unsigned long int t);
//*********************************************************
#endif

出0入0汤圆

 楼主| 发表于 2008-7-29 11:06:12 | 显示全部楼层
好用的就顶一下

出0入0汤圆

发表于 2008-8-22 12:26:42 | 显示全部楼层
我认为函数的返回不应该放到全局变量中。以启动条件为例:
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;
}

出0入0汤圆

发表于 2009-10-8 12:36:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-25 01:27:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-25 11:07:26 | 显示全部楼层
开发工具用的是什么?

出0入0汤圆

发表于 2010-6-28 10:23:10 | 显示全部楼层
不错,学习一下!!!!!!!!!!!!!

出0入0汤圆

发表于 2010-7-29 08:58:35 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-28 03:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表