用I/O口模拟总线时序
在做总线通信过程中,我们很少会用到这样方法,一般在我们选择MCU的时候都会带有你所需要的通信接口。但是,对于一些简单的通信应该用的场合,一般在一些传感器的数据通信过程中,传感器厂商会将通信协议做一些改变,这些通信协议也没有一个标准的协议规定。以至于传感器的兼容性很差,甚至有时候找不到能够与其通信的MCU,这个时候有一种方法就是用I/O口来模拟通信总线(由于I/O速度的限制一般只适用于低速的通信总线)的时序。之前,用I2C通信做一个温湿度测量的工程,本篇文章就以一个例子来看看如何用I/O口对总线时序进行模拟。
我们平时计算机常用的RS232/485工作在异步工作状态时是有严格的数据时钟限制,也就是我们所说的波特率,通信的两个设备有相同的波特率才能正确的通信。对于同步通信一般没有严格的时间限制,总线通过高低电平来分辨数据是“0”还是“1”,有两个关键的时刻:上升沿,下降沿。它是用过上升沿和下降沿的时刻来读写数据的,也就是说这样的话通信频率不是固定的,因为通信的设备“数”的是上升沿和下降沿的数目,然后读写数据线上的数据。笔者做过实验,将I2C通信的频率降到了10Hz左右,这样用示波器能够很好的捕捉到每一个时钟,通信的结果也是正确的。
好了,直接来看案例吧。
通常我们的I2C的通信时序应该如下图所示,在时钟线拉高的情况下,将数据线拉低就会产生一个启动信号。但是传感器SHT的启动信号却是一个数据线拉低后,时钟线产生一个脉冲,而后再将数据线拉高,这样做的好处是在一定程度上确保了总线正确的启动,但是几乎与之匹配的MCU。这个时候就需要通过I/O模拟的方式来与SHT11完成通信。


#define IIC_SCL RC0 //I2C时钟线
#define IIC_SDA RC1 //I2C数据线
#define IIC_SCL_DIR TRISC0 //I2C时钟线传输方向
#define IIC_SDA_DIR TRISC1 //I2C数据线传输方向
#define PORT_INPUT 1
#define PORT_OUTPUT 0 #define IIC_SCL_HIGH() IIC_SCL_DIR = PORT_INPUT //时钟线拉高
#define IIC_SCL_LOW() IIC_SCL_DIR = PORT_OUTPUT;IIC_SCL=0//时钟线拉低
#define IIC_SDA_HIGH() IIC_SDA_DIR = PORT_INPUT //数据线拉高
#define IIC_SDA_LOW() IIC_SDA_DIR = PORT_OUTPUT;IIC_SDA=0//数据线拉低 /***************
*SHT11启动时序
***************/
void SHT_START(void)
{
IIC_SCL_HIGH();
IIC_SDA_HIGH();
delay_us();
IIC_SDA_LOW();
delay_us();
IIC_SCL_LOW();
delay_us();
IIC_SCL_HIGH();
delay_us();
IIC_SDA_HIGH();
delay_us();
IIC_SCL_LOW();
}
/***************
*SHT11发送数据时序
***************/
void SHT_SEND(uchar data)
{uchar i,data1;
for(i=;i<;i++)
{
data1=data<<i;
if(!(data1&0x80))
IIC_SDA_LOW();
if(data1&0x80)
IIC_SDA_HIGH();
IIC_SCL_LOW(); //写完1位数据将时钟线拉低,等待发送
delay_us();
IIC_SCL_HIGH(); //时钟线上升沿,发送1位数据
delay_us(); //等待1位数据发送完成
}
IIC_SCL_LOW();
IIC_SDA_HIGH(); //8位数据发送完成,数据线拉高,等待SLAVE器件响应
delay_us();
IIC_SCL_HIGH(); //时钟线拉高,产生上升沿读取数据线是否SLAVE器件有响应
//while(IIC_SDA==1);
delay_us();
IIC_SCL_LOW();
IIC_SDA_HIGH(); //数据线拉高,时钟线拉低,等待转换完成
}
/***************
*SHT11接收数据时序
***************/
uint SHT_REC(void)
{
uint i;
uint REC1=,REC0=,REC=;
for(i=;i<;i++)
{
IIC_SCL_HIGH(); //转换完成,SLAVE器件将数据线拉低,时钟线产生上升沿读取高8位数据
REC1=(REC1<<)+IIC_SDA;
delay_us();
IIC_SCL_LOW(); //将时钟线拉低,等待下一个上升沿的到来
delay_us();
}
SHT_ASK(); //高8位数据接收完毕,发送应答信号
for(i=;i<;i++)
{
IIC_SCL_HIGH(); //转换完成,SLAVE器件将数据线拉低,时钟线产生上升沿读取低8位数据
REC0=(REC0<<)+IIC_SDA;
delay_us();
IIC_SCL_LOW();
delay_us();
}
SHT_STOP(); //低8位数据接收完毕,结束
REC=(REC1<<)+REC0;
return REC;
}
/***************
*SHT11应答时序
***************/
void SHT_ASK(void)
{
IIC_SCL_LOW();
IIC_SDA_LOW(); //数据线拉低
delay_us();
IIC_SCL_HIGH(); //时钟线拉高才生应答信号
delay_us();
IIC_SDA_HIGH();
IIC_SCL_LOW();
delay_us();
}
/***************
*SHT11停止时序
***************/
void SHT_STOP(void)
{
IIC_SDA_HIGH();
IIC_SCL_LOW();
delay_us();
IIC_SCL_HIGH();
delay_us();
IIC_SDA_HIGH();
IIC_SCL_LOW();
}
用I/O口模拟总线时序的更多相关文章
- 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)
版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 ...
- 用I/O口模拟IIC总线协议遇到的一些问题
最近做的一个项目,是基于IIC总线通信的传感器系统.由于另外一个传感器使用的是类IIC协议,而不是标准IIC,所以MCU不能与其通信,最后没有办法,只有通过I/O口模拟的方式实现IIC的总线通信.具体 ...
- MSP430的IO口模拟I2C总线对AT24C25进行读写程序
功能: 实现MSP430口线模拟I2C总线协议与24C04通信. ** 描述: 主系统工作时钟为12MHz,I2C工 ...
- 51单片机GPIO口模拟串口通信
51单片机GPIO口模拟串口通信 标签: bytetimer终端存储 2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报 本文章已收录于: 分类: 深入C语言(20) 作者同 ...
- stm32 普通IO口模拟串口通信
普通IO口模拟串口通信 串口通信协议 串口传输 默认 波特率9600 1起始位 1停止位 其他0 数据位是8位(注意图上的给错了). 传输时,从起始位开始,从一个数据的低位(LSB)开始发送,如图从左 ...
- 使用软件模拟spi 时序时注意点
软件模拟 spi 时序有以下几个点需要注意: cs 使能后到第一个 sck 边沿需要延时. 最后一个sck 边沿到下一个 cs 需要延时. sck 的高电平和低电平本身需要维持时间. mosi 需要先 ...
- S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动
目录:一. 说明 二. 驱动程序说明及问题 三. 案例一 四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...
- lpc1788IO口模拟IIC
#ifndef __MYIIC_H_ #define __MYIIC_H_ #include "common.h" #include "delay.h" #in ...
- GPIO软件模拟IIC时序
一.MPU6050中的IIC时序 1.1 START和STOP SDA和SCL在高电平时,SDA拉低表示START.SCL拉低,表示可以传输数据. SDA和SCL在低电平时,SDA拉高表示STOP. ...
随机推荐
- sql server迁移数据(文件组之间的互相迁移与 文件组内文件的互相迁移)
转自:https://www.cnblogs.com/lyhabc/p/3504380.html?utm_source=tuicool SQLSERVER将数据移到另一个文件组之后清空文件组并删除文件 ...
- SVN入门-2分钟教你入门
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u010540106/article/details/37317201 学习SVN首先我们应该知道 ...
- node.js---sails项目开发(5)---用户表的建立
1. ctrl+c 暂停sails项目 ,输入如下命令,创建一个user表 sails generate api user 2.在api目录分别建立了两个文件 api/controllers/U ...
- 在pycharm中导入PyMysql出错,解决方法
在写Django项目的时候,需要用到数据库中的数据,我们在pycharm中需导入 import PyMySQL; 如果没有该模块会报错,像我这样: 如果你的错误像我这样,那么你按照我的方法应该能搞好 ...
- C#框架及概念
EF框架
- CNN学习笔记:正则化缓解过拟合
CNN学习笔记:正则化缓解过拟合 过拟合现象 在下图中,虽然绿线完美的匹配训练数据,但太过依赖,并且与黑线相比,对于新的测试数据上会具有更高的错误率.虽然这个模型在训练数据集上的正确率很高,但这个模型 ...
- SQL server 数据库 操作及简单查询
使用SQL Sever语言进行数据库的操作 常用关键字identity 自增长primary key 主键unique 唯一键not null 非空references 外键(引用) 在使用查询操作数 ...
- mysql 系列文章推荐
1. mysql日志详细解析 http://www.cnblogs.com/wangkongming/p/3684950.html 2. mysql 主从同步实验 http://pmg ...
- dogo 官方翻译 Ajax with dojo/request
require(["dojo/request"], function(request){ request("helloworld.txt").then( fun ...
- Web开发相关笔记 #01#
前端学习纲要 ※jQuery 参考 ※ 整理 Chrome 收藏夹的小技巧 ※ 解决 AJAX 跨域获取 cookie ※ 记一次 MyBatis 相关的 debug [1] 前端学习纲要: ♦ 第一 ...