登录 免费注册 首页 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

求助关于GPIO的IOPIN问题

作者:fengboy 栏目:MCU技术
求助关于GPIO的IOPIN问题
我想用LPC2114.html">LPC2114来模拟I2C总线(虽然LPC2114.html">LPC2114有自带的接口,不过这种模拟还是有普遍意义).
LPC2114的GPIO在应用中要么是输入,要么是输出,同时既是输入又是输出是不能的.
这就遇到一个问题,I2C中有应答机制,也就是说SDA是双向的,它同时发送信号,又要接收来自器件的应答信号,这怎么模拟?
我的想法是:
   发送数据是设置模拟的SDA端口(比如P0.24)为GPIO,方向为输出;
   在接收数据或判断应答信号时把SDA端口(比如P0.24)的方向设置为输入,读取IOPIN.
   是不是要这样来回切换I/O口的方向.
   还有一个问题就是对IOPIN寄存器的理解.手册中是这么说的,
IOPIN:GPIO引脚寄存器,不管方向和模式如何设定,引脚的当前状态都可以从该寄存器中读数.
    如果果真是这样的话,我引脚设置成输出,外面输入信号,我不用切换状态,直接从IOPIN读端口状态不就可以拉吗?  如果这样的话,端口不是能拉双向的拉吗,同时既是输入又是输出.
  希望大家帮我解惑,谢谢

下面是我模拟I2C的关键程序,运行发现出错.
#define SDA  1<<24             //p0.24  作为输出
#define SDA1 0x00000000             //p0.24   作为输出
#define SCL  1<<25        //p0.25 作为输出

void Delay1(uint16 x)
{
  for(;x>0;x--);  
}

void Start_I2c()
{
  IO0SET=SDA;   /*发送起始条件的数据信号*/    
  IO0SET=SCL;
  Delay1(1000);    /*起始条件建立时间大于4.7us,延时*/    
  IO0CLR=SDA;   /*发送起始信号*/
  Delay1(1000);   /* 起始条件锁定时间大于4μs*/       
  IO0CLR=SCL;   /*钳住I2C总线,准备发送或接收数据 */
  Delay1(1000);  
}

void Stop_I2c()
{
  IO0CLR=SDA;
  IO0CLR=SCL;          /*发送结束条件的数据信号*/
  Delay1(1000);   /*发送结束条件的时钟信号*/
  IO0SET=SCL;         /*结束条件建立时间大于4μs*/
  Delay1(1000);
  IO0SET=SDA;        /*发送I2C总线结束信号*/
  Delay1(1000);
}
/*******************************************************************
                 字节数据传送函数               
函数原型: void  SendByte(uint8 c);
功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
     此状态位进行操作.(不应答或非应答都使ack=0 假)     
     发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void  SendByte(uint8 c)
{
uint8 BitCnt;
uint32 i;
CHAR s[40];
for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
    {
     if((c<<BitCnt)&0x80)IO0SET=SDA;   /*判断发送位*/
       else  IO0CLR=SDA;                
     Delay1(1000);
     IO0SET=SCL;               /*置时钟线为高,通知被控器开始接收数据位*/
     Delay1(1000);               /*保证时钟高电平周期大于4μs*/         
     IO0CLR=SCL;                /*保证时钟低电平周期大于4.7μs*/
     Delay1(1000);
    }
    IO0SET=SDA;               /*8位发送完后释放数据线,准备接收应答位*/
    Delay1(1000);  
    IO0SET=SCL;              //产生第9个时钟
    
    IO0DIR=SDA1|SCL;     //切换SDA方向
    while(IO0PIN&SDA)
    { i++;
      if(i>2000)
       break;
     }
     
    if(i>2000)
       {sprintf(s,"NO ACK!,ERROR!");
        SendPCStr(40,20,s,0x30);ack=0;
      }
      else
      {sprintf(s,"OK!");
        SendPCStr(40,20,s,0x30);ack=1;}
                   /*判断是否接收到应答信号*/
    IO0CLR=SCL;
    IO0DIR=SDA|SCL;
    
    Delay1(1000);
}
uint8 ISendByte(uint8 sla,uint8 c)
{
   Start_I2c();               /*启动总线*/
   SendByte(sla);            /*发送器件地址*/
     if(ack==0)return(0);
   SendByte(c);               /*发送数据*/
     if(ack==0)return(0);
  Stop_I2c();                 /*结束总线*/
  return(1);
}
main函数初始化后运行ISendByte(0xa0,0x55),发现总是显示NO ACK!ERROR!说明程序有问题.fclk=4*11.0592;Delay1(1000)这个延迟肯定是大于4.7us的.不知道什么问题,时序我看拉没问题啊.

* - 本贴最后修改时间:2007-4-29 19:10:15 修改者:fengboy

参与讨论
昵称:
讨论内容:
 
 
相关帖子
外部数据存储器的用法
急寻LCD驱动的超低功耗8位MCU
大家帮忙~用jtag调试外部flash出现错误
913 问题
求助周公
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入


Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号