打印

菜鸟求教关于I2C的电路问题

[复制链接]
1559|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhutong1016|  楼主 | 2010-8-30 20:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>
#include<intrins.h>
sbit P2_0 = 0xA0;      //此管脚控制第1位显示
sbit P2_1 = 0xA1;      //此管脚控制第2位显示
sbit P2_2 = 0xA2;      //此管脚控制第3位显示
sbit P2_3 = 0xA3;
sbit     P2_7=0xA7;
sbit     P3_6=0xB6;
#define uchar  unsigned char
#define uint   unsigned int
#define _nop()  _nop_()
#define LED_OFF   10
#define SDA  P2_7  
#define SCL  P3_6     
bit ack;
uchar SZ;
uchar fuse;
uchar adder;
uchar adder1;
uchar date;
unsigned char LED_Tab[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xff};
void Delay10ms(const unsigned char n) //函数调用需要2个指令周期
{
unsigned char i;
unsigned int j;

//for语句需要8个指令周期,(本开发板使用11.0592M晶振,每个指令周期1.0851微秒)
for (i = 0; i < n; i++)  
{
  j = 1305;    //赋值语句需要2个指令周期
  while (j--);   //while语句7个指令周期
}
}
void  STAR(void)
{
SCL = 0;
SCL = 1;
SDA = 1;
_nop_();
_nop_();
SDA = 0;
_nop_();
_nop_();
SCL = 0;
SDA = 1;
}
void STOP(void)
{
  SCL = 0;
SDA = 0;
SCL = 1;
_nop_();
_nop_();
SDA = 1;
_nop_();
_nop_();
SCL = 0;
}
bit WDT(uchar c)
{
int i = 8;
do
{
  SCL = 0;
  if(c&0x80==0x80)  SDA=1;
        else
        SDA=0;
     c <<= 1;
  SCL = 1;
}while(--i);
SCL = 0;
// 等待应答
SDA = 1;                    // For input direct
SCL = 1;
for ( i=5; i>0; i--)
{
  if (SDA == 0)
  {
   SCL = 0;
      return(0x01);
  }
   if(SDA==1)
     {
   SCL = 0;
      return(0x00);
     }
}
}  

  
uchar RDT()
{
  uchar i;  
  uchar retc;
  retc=0;
  SDA=1;
  for(i=0;i<8;i++)
  {
   _nop_();
   SCL=0;
   _nop_();  
   _nop_();
   _nop_();
   _nop_();
   _nop_();
    SCL=1;
   _nop_();  
   _nop_();
   retc=retc<<1;
   if(SDA==1)
   retc=retc+1;
   _nop_();
   _nop_();
  }
  SCL=0;
  _nop_();   
  _nop_();
  return (retc);
}
void ACKS(bit a)
{
if(a==0)
SDA=0;
else
  SDA=1;
_nop_();
  _nop_();
SCL=1;
_nop_();
  _nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}



bit send (uchar sla,uchar suba,  uchar s)
{  uchar  wit;
   STAR();
   wit=WDT(sla);
   return(wit);
   
   
  WDT(suba);
   WDT(s);
  if(ack==1)
      {STOP();
       return(0x01);
       }
     
}
     
   
   
   

  
uchar receive(uint sla ,uint suba)
   
{
   uchar  c;
   STAR();
   WDT(sla);
  
   if(ack==0)
   return(0x01);
   else
   {
   WDT(suba);
  
   if(ack==0)
   return(0x00);
else
   { STAR();
     WDT(sla+1);
      c=RDT();
      SCL=0;
   ACKS(1);
      STOP();
      return(c);
}
   }
}  
   
      
     

void LED_DisplayF(unsigned int num)
{
bit nonzero_before;     //高位0标志,如果高位全为0不显示
unsigned char temp;
static unsigned char digit;   //当前需要扫描显示的位
num = num%10000;     //抛弃4位以上的高数位
  
if (digit == 0)
{
  temp = num/1000;    //得到千位数
  P2_3 = 1;      //关掉上个位

  if (temp)
  {
   P0 = LED_Tab[temp];   //把千位数送上数据输出口
   nonzero_before = 1;   //设置标志位
  }
  else
  {
   P0 = LED_Tab[LED_OFF];  //千位为0不显示
  }
  P2_0 = 0;      //选通千位数码管
  digit++;
}
else if (digit == 1)
{  
  temp = (num%1000)/100;   //得到百位数

  P2_0 = 1;
  if (temp)
  {
   P0 = LED_Tab[temp];   //把百位数送上数据输出口
   nonzero_before = 1;
  }
  else if (nonzero_before)  //千位不为0时,百位为0要显示
  {
   P0 = LED_Tab[temp];
  }
  else       //千位为0
  {
   P0 = LED_Tab[LED_OFF];
  }
  P2_1 = 0;
  digit++;
}
else if (digit == 2)
{
  temp = ((num%1000)%100)/10;  //得到十位数

  P2_1 = 1;
  if (temp)
  {
   P0 = LED_Tab[temp];   //把十位数送上数据输出口
   nonzero_before = 1;
  }
  else if (nonzero_before)  //千或百位或十位不为0时,十位为0要显示
  {
   P0 = LED_Tab[temp];
  }
  else       //十位为0
  {
   P0 = LED_Tab[LED_OFF];
  }
  P2_2 = 0;
  digit++;
}
else if (digit == 3)
{
  temp = ((num%1000)%100)%10;

  P2_2 = 1;
  P0 = LED_Tab[temp];   //把个位数送上数据输出口,0要显示
  P2_3 = 0;
  digit = 0;
  nonzero_before = 0;
}
}  
main(void)
{ uchar anx;
   adder= 0xa0;
   adder1= 0x007f;
   date=0x06;
   anx=send (adder,adder1,date);
   Delay10ms(1);
   fuse=receive(adder,adder1);
    while(1)
{
    LED_DisplayF(anx);
     }  
}
  
还在调试中,只是每次写数据到I2C,SDAu=1没写进去一直没找到原因,求指点啊

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

5

帖子

1

粉丝