I2C组件
来源:互联网 发布:淘宝怎么用照片搜同款 编辑:程序博客网 时间:2024/05/22 14:26
I2C.h
#ifndef _I2C_H#define _I2C_H#define I2Cdelay(); { _nop_(); _nop_(); _nop_(); _nop_(); }sbit I2C_SCL = P3^7;sbit I2C_SDA = P3^6;void I2Cstart();void I2Cstop();bit I2Cwrite(uint8_t dat);uint8_t I2CreadNak();uint8_t I2CreadAck();#endif // _I2C_H
I2C.c
/** * 文件名:I2C.c * 描 述:I2C总线驱动模块 * 备 注:基于IO口模拟实现,总线时序延时等皆由软件方式实现 * 时钟信号SCL的产生和延时很重要 */#include <reg52.h>#include <intrins.h>#include "stdint.h"#include "I2C.h"/* 产生总线起始信号 */void I2Cstart() { I2C_SDA = 1; //首先确保sda、scl都是高电平 I2C_SCL = 1; I2Cdelay(); //保持状态一段时间 I2C_SDA = 0; //先拉低sda(在scl为高电平期间,sda出现下降沿) I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl(使得可以往数据线sda上写数据)}/* 产生总线停止信号 */void I2Cstop() { //I2C_SCL = 0; //首先确保sda、scl都是低电平(时钟信号scl之前已经置0了) I2C_SDA = 0; I2Cdelay(); //之前i2c已经工作过,是以时钟信号scl为0结束的,此时需要把该时钟状态保持一段时间 I2C_SCL = 1; //先拉高scl I2Cdelay(); //保持状态一段时间 I2C_SDA = 1; //再拉高sda(在scl为高电平期间,sda出现上升沿) I2Cdelay(); //保持状态一段时间}/* i2c总线写操作,dat-待写入字节,返回值-从机应答位的值 */bit I2Cwrite(uint8_t dat) { bit ack; //用于暂存应答位的值 uint8_t mask; //用于探测字节内某一位值的掩码变量 //从高位到低位依次进行 for (mask = 0x80; mask != 0; mask >>= 1) { if ((mask & dat) == 0) //该位的值输出到sda上(之前已经保证scl为低电平了,此时可以写数据) I2C_SDA = 0; else I2C_SDA = 1; I2Cdelay(); //保持状态一段时间 I2C_SCL = 1; //拉高scl(使得从机可以从sda上读数据) I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl,完成一个位周期,为下一次写数据做好准备 } I2C_SDA = 1; //8位数据发送完后,主机释放sda,以检测从机应答 I2Cdelay(); //保持状态一段时间,此时从机将应答值写到sda上 I2C_SCL = 1; //拉高scl ack = I2C_SDA; //读取此时的sda值,即为从机的应答值 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl完成应答位,并保持住总线,为下一次写数据做好准备 return (~ack); //应答值取反以符合通常的逻辑: //0=不存在或忙或写入失败,1=存在且空闲或写入成功}/* I2C总线读操作,并发送非应答信号,返回值-读到的字节 */uint8_t I2CreadNak() { uint8_t mask, dat; I2C_SDA = 1; //首先确保主机释放sda,之前已确保scl为0 //从高位到低位依次进行 for (mask = 0x80; mask != 0; mask >>= 1) { I2Cdelay(); //延时一段时间,此时从机将数据位写到sda上 I2C_SCL = 1; //拉高scl,主机开始读 if (I2C_SDA == 0) //读取sda的值 dat &= ~mask; //为0时,dat中对应位清零 else dat |= mask; //为1时,dat中对应位置1 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl,以使从机发送出下一位 } I2C_SDA = 1; //8位数据发送完后,主机拉高sda,发送非应答信号 I2Cdelay(); //保持状态一段时间 I2C_SCL = 1; //拉高scl,使得从机可以读这个非应答信号 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl完成非应答位,并保持住总线 return dat;}/* I2C总线读操作,并发送应答信号,返回值-读到的字节 */uint8_t I2CreadAck() { uint8_t mask, dat; I2C_SDA = 1; //首先确保主机释放sda,之前已确保scl为0 //从高位到低位依次进行 for (mask = 0x80; mask != 0; mask >>= 1) { I2Cdelay(); //延时一段时间,此时从机将数据位写到sda上 I2C_SCL = 1; //拉高scl,主机开始读 if (I2C_SDA == 0) //读取sda的值 dat &= ~mask; //为0时,dat中对应位清零 else dat |= mask; //为1时,dat中对应位置1 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl,以使从机发送出下一位 } I2C_SDA = 0; //8位数据发送完后,主机拉低sda,发送应答信号 I2Cdelay(); //保持状态一段时间 I2C_SCL = 1; //拉高scl,使得从机可以读这个应答信号 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl完成应答位,并保持住总线 return dat;}
0 0
- I2C组件
- I2C组件(新)
- I2C
- I2C
- i2c
- I2C
- I2C
- i2c
- i2c
- I2C
- I2C
- I2c
- I2C
- I2C
- I2C
- I2C
- I2C
- i2c
- 关于java中get和set方法的好处
- php之echo print区别
- 矩阵乘方
- java中的多态
- [经典面试题]字符串编辑距离
- I2C组件
- Memcached服务器安装
- Light OJ 1341 Aladdin and the Flying Carpet(唯一分解定理)
- 葫芦娃关于快速幂流程的详细讲解
- 二进制取反
- sdt:bind用法
- vcs和verdi的联合仿真
- 【算法学习笔记】22.算法设计初步 二分查找 上下界判断
- Android SetBackGroundColor not working