EMC单片机学习三

来源:互联网 发布:鼠标软件安装 编辑:程序博客网 时间:2024/05/18 12:01

模拟I2C---从机


  硬件平台:em78p153
       一般IO模拟有2种方法:中断或查询。这里用的是查询的方式。查询IO口状态变化,主机SCK速率不能超过100Khz。

     I2C协议中最重要的一点是I2C地址。这个地址有7位和10位两种形式。7位能够表示127个地址,而在实际使用中基本上不会挂载如此多的设置,所以很多设备的地址都采用7位,所以本文接下来的说明都是基于此。I2C还有一个很重要的概念,就是“主—从”。对于从设备来说,它是啥都不干的,更不会自动发送数据;而主设备,则是起到控制作用,一切都是从它开始。


*********

观看时序图总结几点:

1. 时序图都是共用一个时钟信号,注意时钟信号在上下图中的对应。

2. 时序图中有叉或者上升下降的如果是数据线的话表示数据有变化。菱形封闭的一段表示有效数据。

3. 数据需要一段时间稳定,一般在数据变化后,时钟的上升沿或者下降沿读入数据或者写入数据。

**********

由于这里是做从机,所以用主机读写从机来反推时序,可以去查看AT24C02的时序 

做从机时,就要反过来根据时序逆推:采用方式IO口查询模式
作为从机要判断的事件有。


检测start->地址是否匹配->主机是要写,还是要读


  写的情况下:发送ACK -->接收数据-->数据接收完毕发送nack或者等待主机停止-->主机stop


  读的情况下:发送ACK-->发送数据-->等待主机ACK-->主机ACK后继续发送,主机NACK 停止发送,等待STOP-->主机STOP

MCU:8Mhz  内部IRC

程序代码

---代码经过测试,但这种容易阻塞读写不是很高效。这个只提供参考。

Date_0000:                     ;接受开始信号-------------------   
      MOV   A,@0X03       ;0.25us  1个指令周期
      IOW   PORT5            ;sda输入模式       
Date_0001:
      ;--------------------------------------------
      JBS       PORT5,SCL  ;判断scl==1?              2个指令周期
      JMP     Date_0001   ;否,重新判断开始信号  1us 2个指令周期
      JBS      PORT5,SDA  ;判断sda==1            1us
      JMP     Date_0001   ;
Date_0002:
      JBC       PORT5,SDA  ;是,等待sda等于0      1us
      JMP      $-1        ;
      JBS       PORT5,SCL  ;判断scl等于1吗
      JMP     Date_0000   ;否,重新判断开始信号  1us        
地址:
Date_1000:
       CLR        REG0
       MOV     A,@8
       MOV     REG1,A           ;赋值给yr1   1us
       BC         R3,0               ;清c进位标志位
Date_1100:                         ;接受指令---------------------------           
      JBC     PORT5,SCL        ;等待scl变0       1us
      JMP     $-1
      ;============================================        
      JBS     PORT5,SCL         ;等待scl变1
      JMP     $-1                   ;在scl上升沿把sda作为数据输入  1us
      ;============================================      
      RLC     REG0                 ;左移一位把高位移出
      JBC     PORT5,SDA       ;判断sda等于0        1us
      BS     REG0,0                ;等于1置位1
      DJZ     REG1                 ;sda为0,判断yr1减1是否为0
      JMP     SID_1100          ;yr1不为0,接受下一位  1us
      MOV     A,REG0         
      XOR     A,@0Xa0          ;判断数据是否为0xA0  3us
      JBS     R3,2
      JMP     Date_0000        ;不是重新接受开始信号
应答:
Date_1200:                    
      MOV     A,@0X01
      ;IOW    PORT5             ;sda输出模式       
      JBC     PORT5,SCL         ;等到scl变0
      JMP     $-1            
      IOW     PORT5 
      BC      PORT5,SDA         ;输出0 
      JBS     PORT5,SCL         ;等待scl变1
      JMP     $-1
      JBC     PORT5,SCL         ;等待scl变0
      JMP     $-1
非应答:
Date_6500:                     ;非应答----从机  sda = 1
      MOV     A,@0X01
      JBC     PORT5,SCL       ;等到scl变0
      JMP     $-1             ;
      IOW     PORT5           ;sda输出模式
      BS      PORT5,SDA       
      JBS     PORT5,SCL       ;等待scl变1
      JMP     $-1
      JBC     PORT5,SCL       ;等待scl变0
      JMP     $-1        

停止:
Date_7000:                     ;停止信号-------------
      MOV    A,@0X03         
      IOW    PORT5
      JBS    PORT5,SCL        ;判断scl是否为1
      JMP    Date_7000
      JBC    PORT5,SDA         ;判断sda是否为0
      JMP    Date_7000
      JBS    PORT5,SDA         ;等待sda变为1
      JMP    $-1 
      JBS    PORT5,SCL        ;SDA=1,判断scl是否为1
      JMP    Date_7000 


0 0
原创粉丝点击