IIC驱动源码程序---STC89C52实时用PCF8591采集温度LCD显示
Posted wlei5206
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于IIC驱动源码程序---STC89C52实时用PCF8591采集温度LCD显示的主要内容,如果未能解决你的问题,请参考以下文章
STC89C52RC+ LCD1602转IIC接口屏幕驱动显示
STC89C52RC+ LCD1602+PCF8574转IIC接口屏幕驱动显示+Proteus仿真
PCF8591采集温度源码程序---STC89C52实时用PCF8591采集温度LCD显示
PCF8591采集温度源码程序---STC89C52实时用PCF8591采集温度LCD显示