打印

51单片机GPIO模拟IIC功能

[复制链接]
2441|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rousedeshui|  楼主 | 2011-10-11 15:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA=P3^4;
sbit SCL=P3^3;
uchar ack;



void start()
{
    SDA=1;
    SCL=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SDA=0;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SCL=0;   
}
void stop()
{
    SDA=0;
    SCL=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SDA=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}
void sendByte(uchar byte)
{
    uchar i;

    for(i=0;i<8;i++)
    {   
        if(byte&0x80)
            SDA=1;
        else
            SDA=0;
        byte=byte<<1;
        _nop_();
        SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
        _nop_();
        _nop_();              /*保证时钟高电平周期大于4μs*/
        _nop_();
        _nop_();
        _nop_();         
        SCL=0;
    }
    _nop_();
    _nop_();
    SDA=1;               /*8位发送完后释放数据线,准备接收应答位*/
    _nop_();
    _nop_();   
    SCL=1;
    _nop_();
    _nop_();
    _nop_();
    if(SDA==1)ack=0;     
       else ack=1;        /*判断是否接收到应答信号*/
    SCL=0;
    _nop_();
    _nop_();
}
uchar receiveByte()
{
    uchar i,byte=0;
    SCL=0;
    SDA=1;
    for(i=0;i<8;i++)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        SCL=1;
        byte=byte<<1;   
        if(SDA==1)
            byte=byte+1;
        SCL=0;
    }
    return byte;
}
void ackIIC(bit a)
{
    SDA=a;
    SCL=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SCL=0;
}
void main()
{
    start();
    sendByte(0xa0);
    sendByte(0x60);
    sendByte(0x55);
    stop();

    start();
    sendByte(0xa0);
    sendByte(0x60);
    start();
    sendByte(0xa1);
    P0=receiveByte();
}
我用51单片机的IO口模拟IIC功能,写得这个程序在倒数第二个语句“sendByte(0xa1)”这就写不成功了,前面的语句都写成功了呀,请教大牛这事嘛回事?

相关帖子

沙发
ayb_ice| | 2011-10-11 15:34 | 只看该作者
程序需要对应答位进行相应的处理
具体情况应该是在写进程中,这个需要时间,一般是5~10MS
试试

stop();
delay(15MS); // 加入延时
start();

使用特权

评论回复
板凳
ericyang001| | 2011-10-12 08:39 | 只看该作者
需要5-10个ms?不是吧。。。

使用特权

评论回复
地板
_编程浪子| | 2011-10-13 09:46 | 只看该作者
本帖最后由 _编程浪子 于 2011-10-13 09:58 编辑

Nop加的少了。
用你的晶振频率算算时间。我的24C02的开始、结束传输数据时,SDA保持时间不能小于4.7ms。

使用特权

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

本版积分规则

0

主题

6

帖子

1

粉丝