加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 单片机学习

连接多个相同地址I2C设备的C51程序

时间:2013-09-03  来源:123485.com  作者:9stone

本人初学C,曾为这个问题大伤脑筋^_^,就是一个单片机系统有两个以上的相同地址的I2C设备,无法用两个同一对SDA/SCL引脚,

#include "stc89c51.h"
#include "iic.h"

sbit scl0=P3^5;
sbit sda0 = P3^4;
sbit scl1= P3^3;
sbit sda1 = P3^2;
//这里只写了两个I2C设备,如果需要可以再加上 sbit scl2=xx; sbit sda2=xx; 实际上多个设备的scl脚可以共用

unsigned char iic_delay_time = 8;

void scl(device,value);
void sda(device,value);
bit sdasense(char device);

// delay
void iic_delay(unsigned char m)
{
    unsigned char n;
    for(n=0;n<m;n++);
}

//
void scl(device,value)
{
    if (device==0)        //设备1
        scl1=value;
    if (device==1)        //设备2
        scl2=value;
}
void sda(device,value)
{
    if (device==0)        //设备1
        sda1=value;
    if (device==1)        //设备2
        sda2=value;
}

bit sdasense(char device)
{
switch(device)
    {
        case 1: return sda1;
            break;
        case 2: return sda2;
            break;
    }
}

//启动I2C总线的函数,当scl为高电平时使sda产生一个负跳变
void iic_start(device)
{
    sda(device,1);
    scl(device,1);
    iic_delay(iic_delay_time);
    sda(device,0);
    iic_delay(iic_delay_time);
    scl(device,0);
    iic_delay(iic_delay_time/2);
}

//终止I2C总线,当scl为高电平时使sda产生一个正跳变
void iic_stop(device)
{
    scl(device,0);
    sda(device,0);
    scl(device,1);
    iic_delay(iic_delay_time);
    sda(device,1);
    iic_delay(iic_delay_time);
}

//发送应答信号
void iic_ack(device) {
    sda(device,0);
    scl(device,1);
    scl(device,0);
    sda(device,1);
}

//发送无应答信号
void iic_noack(device)
{
    sda(device,1);
    scl(device,1);
    scl(device,0);
}

//检测应答信号
bit iic_testack(device)
{
    bit errorbit;      //真确应答,返回0
    sda(device,1);
    iic_delay(iic_delay_time);
    scl(device,1);
    iic_delay(iic_delay_time);
    errorbit=sdasense(device);
    scl(device,0);
    iic_delay(iic_delay_time);
    return(errorbit);
}

//发送一个字节
void iic_write8bit(device,unsigned char input)
{
    unsigned char temp;
    for(temp=0;temp<8;temp++)
    {
        if((input<<temp)&0x80)
            sda(device,1);
        else
            sda(device,0);
        scl(device,1);

        iic_delay(iic_delay_time);
        scl(device,0);
    }
}

//读一个字节
unsigned char iic_read8bit(device)
{
    unsigned char temp,rbyte=0;
    for(temp=0;temp<8;temp++)
    {
        scl(device,1);
        iic_delay(iic_delay_time);
        if(sdasense(device))
            rbyte=(rbyte<<1)+1;
        else
            rbyte=rbyte<<1;
        scl(device,0);
    }
    return(rbyte);
}


分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->单片机学习
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门