zoukankan      html  css  js  c++  java
  • IIC驱动源码程序---STC89C52实时用PCF8591采集温度LCD显示

    一、创建头文件i2c.h代码如下:

    #ifndef __I2C_H_
    #define __I2C_H_
    
    #include <reg52.h>
    
    sbit SCL=P2^1;
    sbit SDA=P2^0;
    
    void I2cStart(); //    I2c启动
    void I2cStop(); //    I2c停止
    unsigned char I2cSendByte(unsigned char dat);  // I2c发送字节
    unsigned char I2cReadByte(); //    I2c读取字节
    void I2cAck(unsigned char ackbit); // I2c响应
    bit I2cWaitAck(void); // I2c等待响应
    void At24c02Write(unsigned char addr,unsigned char dat);
    unsigned char At24c02Read(unsigned char addr);
    
    #endif

    二、创建编译文件i2c.c代码如下:

    #include"i2c.h"
    
    /*******************************************************************************
    * 函数名         : Delay10us()
    * 函数功能           : 延时10us
    * 输入           : 无
    * 输出              : 无
    *******************************************************************************/
    
    void Delay10us()
    {
        unsigned char a,b;
        for(b=1;b>0;b--)
            for(a=2;a>0;a--);
    
    }
    /*******************************************************************************
    * 函数名         : I2cStart()
    * 函数功能         : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿
    * 输入           : 无
    * 输出              : 无
    * 备注           : 起始之后SDA和SCL都为0
    *******************************************************************************/
    
    void I2cStart()
    {
        SDA=1;
        Delay10us();
        SCL=1;
        Delay10us();//建立时间是SDA保持时间>4.7us
        SDA=0;
        Delay10us();//保持时间是>4us
        SCL=0;            
        Delay10us();        
    }
    /*******************************************************************************
    * 函数名         : I2cStop()
    * 函数功能         : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿
    * 输入           : 无
    * 输出              : 无
    * 备注           : 结束之后保持SDA和SCL都为1;表示总线空闲
    *******************************************************************************/
    
    void I2cStop()
    {
        SDA=0;
        Delay10us();
        SCL=1;
        Delay10us();//建立时间大于4.7us
        SDA=1;
        Delay10us();        
    }
    /*******************************************************************************
    * 函数名         : I2cSendByte(unsigned char dat)
    * 函数功能         : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定
    * 输入           : num
    * 输出              : 0或1。发送成功返回1,发送失败返回0
    * 备注           : 发送完一个字节SCL=0,SDA=1
    *******************************************************************************/
    
    void I2cAck(unsigned char ackbit) //当ackbit为1时,表示单片机对从设备发送来数据的应答
    
    { //当ackbit为0时,表示主机接收了最后一个字节,因此不再应答,结束通信
        if(ackbit)
        {
        SDA = 0;
        }
        else
        {
        SDA = 1;
        }
        Delay10us();
        SCL = 1;
        Delay10us();
        SCL = 0;
        SDA = 1;
        Delay10us();
    }
    
    void delay()        //短暂5us延时
    {
        ;;
    }
    
    void ack()
    {
        unsigned char i = 0;
        SCL = 1;
        delay();
        while(SDA == 1 && i < 250)i++;
        SCL = 0;            //SCL=0,SDA可以改变
        delay();
    }
        
    bit I2cWaitAck(void)
        {
        SDA = 1;
        Delay10us();
        SCL = 1;
        Delay10us();
        if(SDA) //在SCL为高电平期间,因为接收设备未将SDA拉低,所以默认未接收到应答,结束IIC通信
        {
        SCL = 0;
        I2cStop();
        return 0;
        }
        else //接收到应答,返回1,继续下一个数据字节的传输
        {
        SCL = 0;
        return 1;
        }
    
    }
    
    unsigned char I2cSendByte(unsigned char dat)
    {
        unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。        
        for(a=0;a<8;a++)//要发送8位,从最高位开始
        {
            SDA=dat>>7;     //起始信号之后SCL=0,所以可以直接改变SDA信号
            dat=dat<<1;
            Delay10us();
            SCL=1;
            Delay10us();//建立时间>4.7us
            SCL=0;
            Delay10us();//时间大于4us        
        }
        SDA=1;
        Delay10us();
        SCL=1;
        while(SDA)//等待应答,也就是等待从设备把SDA拉低
        {
            b++;
            if(b>200)     //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
            {
                SCL=0;
                Delay10us();
                return 0;
            }
        }
        SCL=0;
        Delay10us();
         return 1;        
    }
    /*******************************************************************************
    * 函数名         : I2cReadByte()
    * 函数功能           : 使用I2c读取一个字节
    * 输入           : 无
    * 输出              : dat
    * 备注           : 接收完一个字节SCL=0,SDA=1.
    *******************************************************************************/
    
    unsigned char I2cReadByte()
    {
        unsigned char a=0,dat=0;
        SDA=1;            //起始和发送一个字节之后SCL都是0
        Delay10us();
        for(a=0;a<8;a++)//接收8个字节
        {
            SCL=1;
            Delay10us();
            dat<<=1;
            dat|=SDA;
            Delay10us();
            SCL=0;
            Delay10us();
        }
        return dat;        
    }
    
    
    /*******************************************************************************
    * 函数名         : void At24c02Write(unsigned char addr,unsigned char dat)
    * 函数功能           : 往24c02的一个地址写入一个数据
    * 输入           : 无
    * 输出              : 无
    *******************************************************************************/
    
    void At24c02Write(unsigned char addr,unsigned char dat)
    {
        I2cStart();
        I2cSendByte(0xa0);//发送写器件地址
        I2cSendByte(addr);//发送要写入内存地址
        I2cSendByte(dat);    //发送数据
        I2cStop();
    }
    /*******************************************************************************
    * 函数名         : unsigned char At24c02Read(unsigned char addr)
    * 函数功能           : 读取24c02的一个地址的一个数据
    * 输入           : 无
    * 输出              : 无
    *******************************************************************************/
    
    unsigned char At24c02Read(unsigned char addr)
    {
        unsigned char dat;
        I2cStart();
        I2cSendByte(0xa0); //发送写器件地址
        I2cSendByte(addr); //发送要读取的地址
        I2cStart();
        I2cSendByte(0xa1); //发送读器件地址
        dat=I2cReadByte(); //读取数据
        I2cStop();
        return dat;    
    }

    三、主程序见:https://www.cnblogs.com/wlei5206/p/13023977.html

  • 相关阅读:
    【iOS】找工作的面试题集锦
    APP项目优化--启动速度优化篇
    【Swift】Timer定时器到底准不准确?
    leetcode刷题 495~
    leetcode刷题 464~
    leetcode刷题 441~
    leetcode刷题 420~
    leetcode刷题 396~
    leetcode刷题 373~
    leetcode刷题 307~
  • 原文地址:https://www.cnblogs.com/wlei5206/p/13024116.html
Copyright © 2011-2022 走看看