纬图虚拟仪器论坛

 找回密码
 立即注册
搜索
查看: 5164|回复: 2

51单片机模拟IIC出问题

[复制链接]
发表于 2012-12-10 21:57:32 | 显示全部楼层 |阅读模式
#include "reg52.h"
#include "intrins.h"
#define WriteDeviceAddress 0xa0   //定义器件在 IIC 总线中的地址
#define ReadDviceAddress 0xa1
#define uchar unsigned char
#define uint unsigned int

sbit SDA=P3^1;
sbit SCL=P3^0;
uchar  code table[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00}; //共阴极数码管
uchar write,sec,min;         

uint tcnt,mtcnt;

void flash()
   { ; ; }

void Delay(unsigned int tc)  
{
while( tc != 0 )
{unsigned int i;
for(i=0; i<100; i++);tc--;}
}
  void LED()     
{   
     P0= ~table[sec%10];  
     Delay(5);
P1=~table[sec/10];
      
}
void AT24c02_init()//At24c02初始化  
     {  
      SDA=1;                    
         
    flash();
  
        SCL=1;   
       flash();
     }
//开始总线
void Start()  
{     
      SDA=1;
      SCL=1;
   flash(); flash();
      SDA=0;
      SCL=0;
}
//结束总线
void Stop()  
{     
       SCL=0;
       SDA=0;
       SCL=1;
        flash(); flash();
       SDA=1;
    SCL=0;
}

//发 ACK0
void NoAck()  
{   
       SDA=1;
       flash();
     flash();
       SCL=1;
      flash();
    flash();
       SCL=0;
}

//检测AT24C02发的响应
void  ACK()
{
      SDA=1;  
     SCL=1;
    flash();
      while(  SDA==1  );   //没有应答时一直检测,检测到在执行下面
   flash();
     SCL=0;
}
   
//写入 8 个 bit 到 24c02
Write8Bit(uchar input)  
{     
     uchar temp;
  SCL=0; flash();
  for(temp=8;temp!=0;temp--)  
{
  if(input&0x80)
     SDA=1;
else
     SDA=1;
     SCL=1;  
   flash();
     flash();
      SCL=0;
    input=input<<1;
}

}
//制定地址写入数据
void Write24c02(uchar ch,uchar address)  
{
Start();
Write8Bit(WriteDeviceAddress);
ACK();
Write8Bit(address);
ACK();
Write8Bit(ch);
ACK();
Stop();
Delay(10);
}
//读数据
uchar Read8Bit()  
{
      uchar temp,rbyte=0;
   SCL=0; flash();SDA=1;
for(temp=8;temp!=0;temp--)  
{
   SCL=1;
   rbyte=rbyte<<1;
   rbyte=rbyte|((uchar)( SDA));
    Delay(5);
   SCL=0;
}
return(rbyte);
}
//在制定地址从24c02中读出 1 个字节
uchar Read24c02(uchar address)  
{
uchar ch;
Start();
Write8Bit(WriteDeviceAddress);
ACK();
Write8Bit(address);
ACK();
Start();
Write8Bit(ReadDviceAddress);
ACK();
ch=Read8Bit();
//NoACK();
Stop();
return(ch);
}
void main(void)
{
TMOD=0x01; //定时器工作在方式1
ET0=1; EA=1;
AT24c02_init(); //初始化24C08
sec=Read24c02(2);//读出保存的数据赋于sec

TH0=(65536-50000)/256;                     //对TH0 TL0 赋值
TL0=(65536-50000)%256; //使定时器0.05 秒中断一次
TR0=1; //开始计时
while(1)
{
LED();
if(write==1) //判断计时器是否计时一秒
{
  write=0; //清零
Write24c02(2,sec); //在24c08 的地址2 中写入数据sec
  Delay(5);
}
}
}
void t0(void) interrupt 1  //定时中断服务函数
{
TH0=(65536-50000)/256; //对TH0 TL0 赋值
TL0=(65536-50000)%256; //重装计数初值
tcnt++; //每过250us tcnt 加一
mtcnt++;
if(mtcnt==120)
{
mtcnt=0;
min++;
if(min==10)
min=0;
}
if(tcnt==20) //计满20次(1 秒)时
{
tcnt=0; //重新再计
sec++;
write=1; //1 秒写一次24C08
if(sec==60) //定时100 秒,在从零开始计时
{sec=0;}
}
}
我用proteus仿真发现数码管根本不亮,悲催啊,求指点!
回复

使用道具 举报

发表于 2012-12-11 09:31:22 | 显示全部楼层
模拟I2C的问题一般时序的问题 你好好看一下I2C的时序
回复 支持 反对

使用道具 举报

发表于 2012-12-11 09:49:05 | 显示全部楼层
楼主最好还是分开调试程序,首先把I2C调通,然后把数码管调通,最后再整合调试,这样容易发现问题
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|纬图虚拟仪器

GMT+8, 2024-12-22 12:20 , Processed in 0.124297 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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