• 基于51单片机实现模拟IIC总线时序


      最近用到测量光线的模块BH1750FVI时需要用到IIC总线操作, 于是就又费功夫学习了下, 基本上算是了解了, 所以呢, 就用51的IO口, 模拟出了总线时序, 并能正确操纵需要用IIC总线访问地一系列模块. 本来想写篇文章简单介绍下我对IIC总线的理解的, 但, 发现没工夫, 所以, 放在以后有时候再来弄吧. 今天我还是只给出一个范例程序, 它能在我的51单片机机系统上工作得很好. iic.h 列出了所有IIC总线的操作函数. 下面给出源代码:

    //iic.h - 实现相关的头文件
    //女孩不哭 2013-01-18
    #ifndef __IIC_H__
    #define __IIC_H__
    
    void iic_start(void);
    void iic_stop(void);
    bit iic_get_ack(void);
    void iic_write_byte(uchar dat);
    uchar iic_read_byte(void);
    void iic_send_ack(bit ack);
    
    #endif//!__IIC_H__
    //IIC总线模拟实现文件
    //女孩不哭 22:11 2013-1-18
    #include "common.h"
    #include "iic.h"
    
    sbit SDA = P1^2;
    sbit SCL = P1^0;
    
    //产生START信号
    void iic_start(void)
    {
        SDA = 1;        //需在SCL之前设定
        SCL = 1;        //硬件进入SDA检测状态
        delay_us(5);    //延时至少4.7us
        SDA = 0;        //SDA由1->0,产生开始信号
        delay_us(5);    //延时至少4us
        SCL = 0;        //SCL变为无效
    }
    
    //产生STOP信号
    void iic_stop(void)
    {
        SDA = 0;        //在SCL之前拉低
        SCL = 1;        //硬件进入SDA检测状态
        delay_us(5);    //至少延时4us
        SDA = 1;        //SDA由0->1,产生结束信号
        delay_us(5);    //延时至少4.7us
    }
    
    //写IIC总线写1个字节
    void iic_write_byte(uchar dat)
    {
        uchar loop = 8;     //必须为一个字节
        while(loop--){
            SDA = dat&0x80; //从MSb开始逐位写入
            SCL = 1;
            delay_us(5);    //延时至少4us
            SCL = 0;
            dat <<= 1;      //低位向高位移动
            delay_us(5);
        }
    }
    
    //从IIC总线读取1个字节
    uchar iic_read_byte(void)
    {
        uchar loop = 8;     //必须为一个字节
        uchar ret = 0;
        while(loop--){
            SDA = 1;        //8051内部电阻上拉
            SCL = 1;
            delay_us(5);    //延时至少4us
            ret <<= 1;
            ret |= SDA;     //读取1位
            SCL = 0  ;
            delay_us(5);
        }
        return ret;
    }
    
    //由主向从发送应答码
    //0-ACK,1-NAK
    void iic_send_ack(bit ack)
    {
        SDA = ack;      //产生应答电平
        SCL = 1;        //发送应答信号
        delay_us(5);    //延时至少4us
        SCL = 0;        //整个期间保持应答信号
    }
    
    //取得由从到主的应答码
    bit iic_get_ack(void)
    {
        bit ret;        //用来接收返回值
        SDA = 1;        //电阻上拉,进入读(8051)
        SCL = 1;        //进入应答检测
        delay_us(5);    //至少延时4us
        ret = SDA;      //保存应答信号
        SCL = 0;
        return ret;
    }

      上面的代码给出的是所有的IIC总线的程序.

      common.h中实现的函数及相关定义, 在我的文章中有:http://www.cnblogs.com/nbsofer/archive/2012/11/26/2789239.html

      女孩不哭(QQ:191035066)@2013-01-18 22:18:55 http://www.cnblogs.com/nbsofer

  • 相关阅读:
    Global.asax 事件备忘
    JavaScript异常捕捉
    还记得 virtual 吗?我们来温故知新下吧。
    开发(ASP.NET程序)把写代码写至最有面向对象味道
    MVC中实现 "加载更多..."
    js和C#中的编码和解码(备忘)
    System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
    10种提高WordPress访问速度的方法
    使用Python3实现Telnet功能
    读书计划(不断更新)201904
  • 原文地址:https://www.cnblogs.com/memset/p/2867034.html
Copyright © 2020-2023  润新知