zoukankan      html  css  js  c++  java
  • 用I/O口模拟总线时序

    在做总线通信过程中,我们很少会用到这样方法,一般在我们选择MCU的时候都会带有你所需要的通信接口。但是,对于一些简单的通信应该用的场合,一般在一些传感器的数据通信过程中,传感器厂商会将通信协议做一些改变,这些通信协议也没有一个标准的协议规定。以至于传感器的兼容性很差,甚至有时候找不到能够与其通信的MCU,这个时候有一种方法就是用I/O口来模拟通信总线(由于I/O速度的限制一般只适用于低速的通信总线)的时序。之前,用I2C通信做一个温湿度测量的工程,本篇文章就以一个例子来看看如何用I/O口对总线时序进行模拟。

    我们平时计算机常用的RS232/485工作在异步工作状态时是有严格的数据时钟限制,也就是我们所说的波特率,通信的两个设备有相同的波特率才能正确的通信。对于同步通信一般没有严格的时间限制,总线通过高低电平来分辨数据是“0”还是“1”,有两个关键的时刻:上升沿,下降沿。它是用过上升沿和下降沿的时刻来读写数据的,也就是说这样的话通信频率不是固定的,因为通信的设备“数”的是上升沿和下降沿的数目,然后读写数据线上的数据。笔者做过实验,将I2C通信的频率降到了10Hz左右,这样用示波器能够很好的捕捉到每一个时钟,通信的结果也是正确的。

    好了,直接来看案例吧。

    通常我们的I2C的通信时序应该如下图所示,在时钟线拉高的情况下,将数据线拉低就会产生一个启动信号。但是传感器SHT的启动信号却是一个数据线拉低后,时钟线产生一个脉冲,而后再将数据线拉高,这样做的好处是在一定程度上确保了总线正确的启动,但是几乎与之匹配的MCU。这个时候就需要通过I/O模拟的方式来与SHT11完成通信。

      1 #define IIC_SCL RC0     //I2C时钟线
      2 #define IIC_SDA RC1     //I2C数据线
      3 #define IIC_SCL_DIR TRISC0   //I2C时钟线传输方向
      4 #define IIC_SDA_DIR TRISC1   //I2C数据线传输方向
      5 #define PORT_INPUT 1
      6 #define PORT_OUTPUT 0
      7 
      8 #define IIC_SCL_HIGH() IIC_SCL_DIR = PORT_INPUT           //时钟线拉高
      9 #define IIC_SCL_LOW()  IIC_SCL_DIR = PORT_OUTPUT;IIC_SCL=0//时钟线拉低
     10 #define IIC_SDA_HIGH() IIC_SDA_DIR = PORT_INPUT           //数据线拉高
     11 #define IIC_SDA_LOW()  IIC_SDA_DIR = PORT_OUTPUT;IIC_SDA=0//数据线拉低
     12 
     13 
     14 /***************
     15 *SHT11启动时序
     16 ***************/
     17 void SHT_START(void)
     18 {
     19 IIC_SCL_HIGH();
     20 IIC_SDA_HIGH();
     21 delay_us(5);
     22 IIC_SDA_LOW();
     23 delay_us(5);
     24 IIC_SCL_LOW();
     25 delay_us(5);
     26 IIC_SCL_HIGH();
     27 delay_us(5);
     28 IIC_SDA_HIGH();
     29 delay_us(5);
     30 IIC_SCL_LOW();
     31 }
     32 /***************
     33 *SHT11发送数据时序
     34 ***************/
     35 void SHT_SEND(uchar data)
     36 {uchar i,data1;
     37 for(i=0;i<8;i++)
     38 {
     39 data1=data<<i;
     40 if(!(data1&0x80))
     41 IIC_SDA_LOW();
     42 if(data1&0x80)
     43 IIC_SDA_HIGH();
     44 IIC_SCL_LOW();        //写完1位数据将时钟线拉低,等待发送
     45 delay_us(5);
     46 IIC_SCL_HIGH();        //时钟线上升沿,发送1位数据
     47 delay_us(5);           //等待1位数据发送完成
     48 }
     49 IIC_SCL_LOW();
     50 IIC_SDA_HIGH();        //8位数据发送完成,数据线拉高,等待SLAVE器件响应
     51 delay_us(5);
     52 IIC_SCL_HIGH();        //时钟线拉高,产生上升沿读取数据线是否SLAVE器件有响应
     53 //while(IIC_SDA==1);
     54 delay_us(5);
     55 IIC_SCL_LOW();
     56 IIC_SDA_HIGH();        //数据线拉高,时钟线拉低,等待转换完成
     57 }
     58 /***************
     59 *SHT11接收数据时序
     60 ***************/
     61 uint SHT_REC(void)
     62 {
     63 uint i;
     64 uint REC1=0,REC0=0,REC=0;
     65 for(i=0;i<8;i++)
     66 {
     67 IIC_SCL_HIGH();        //转换完成,SLAVE器件将数据线拉低,时钟线产生上升沿读取高8位数据
     68 REC1=(REC1<<1)+IIC_SDA;
     69 delay_us(5);
     70 IIC_SCL_LOW();                //将时钟线拉低,等待下一个上升沿的到来
     71 delay_us(5);
     72 }
     73 SHT_ASK();                 //高8位数据接收完毕,发送应答信号
     74 for(i=0;i<8;i++)
     75 {
     76 IIC_SCL_HIGH();        //转换完成,SLAVE器件将数据线拉低,时钟线产生上升沿读取低8位数据
     77 REC0=(REC0<<1)+IIC_SDA;
     78 delay_us(5);
     79 IIC_SCL_LOW();
     80 delay_us(5);
     81 }
     82 SHT_STOP();        //低8位数据接收完毕,结束        
     83 REC=(REC1<<8)+REC0;
     84 return REC;
     85 }
     86 /***************
     87 *SHT11应答时序
     88 ***************/
     89 void SHT_ASK(void)
     90 {
     91 IIC_SCL_LOW();
     92 IIC_SDA_LOW();        //数据线拉低
     93 delay_us(5);
     94 IIC_SCL_HIGH();        //时钟线拉高才生应答信号
     95 delay_us(5);
     96 IIC_SDA_HIGH();
     97 IIC_SCL_LOW();
     98 delay_us(5);
     99 }
    100 /***************
    101 *SHT11停止时序
    102 ***************/
    103 void SHT_STOP(void)
    104 {
    105 IIC_SDA_HIGH();
    106 IIC_SCL_LOW();
    107 delay_us(5);
    108 IIC_SCL_HIGH();
    109 delay_us(5);
    110 IIC_SDA_HIGH();
    111 IIC_SCL_LOW();
    112 }
    原谅我这一生不羁放纵爱自由,也怕有天我会跌倒!
  • 相关阅读:
    How to: Implement a View Item 如何:实现视图项
    How to:Create a New Object using the Navigation Control 如何:使用导航控件创建新对象
    How to:Access the Transition Manager 如何:访问过渡管理器
    How to: Implement Custom Context Navigation 如何:实现自定义上下文导航
    How to: Access Master Detail View and Nested List View Environment 如何:访问主详细信息视图和嵌套列表视图环境
    How to: Display a Detail View Directly in Edit Mode in ASP.NET Applications 如何:在ASP.NET应用程序中直接在编辑模式下显示详细信息视图
    How to: Detect a Lookup List View in Code 如何:在代码中检测查找列表视图
    How to: Create and Show a Detail View of the Selected Object in a Popup Window 如何:在弹出窗口中创建和显示选定对象的详细信息视图
    How to: Access Objects Selected in the Current View 如何:访问在当前视图中选择的对象
    How to: Display a List View as a Pivot Grid Table and Chart如何:将列表视图显示为数据透视网格表和图表
  • 原文地址:https://www.cnblogs.com/zhaoming510/p/3935248.html
Copyright © 2011-2022 走看看