首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

89c51 IIC模拟串行通信有关问题

2012-03-13 
89c51 IIC模拟串行通信问题各位用过89c51IIC模拟通信的朋友,以下的程序为写串行E2PROM子程序,但是仿真时第

89c51 IIC模拟串行通信问题
各位用过89c51   IIC模拟通信的朋友,以下的程序为写串行E2PROM子程序,但是仿真时第10、11行程序
  ACALL   SENDBYTE ;出错
  DJNZ  R7,AGAIN;出错
请问大家应该怎样解决此问题,比如在IIC模拟协议方面,整个程序还有其它错误吗?我看了一些程序,
他们用NOP进行延时,这样以延时子程序有何差别


;写串行E2PROM子程序EEPW
;   A0H=10100000(命令1010+器件3位地址+读/写。   器件地址一个芯片,是000)
;   (R4)=片内字节地址
;   (R1)=欲写数据存放地址指针
;   (R7)=连续写字节数n
SCL   BIT   P3.4                                             ;定义24C02的串行时钟线  
SDA   BIT   P3.5                                             ;定义24C02的串行数据线
EEPW:   MOV P1,#0FFH

     ACALL     START  ;发开始信号
     MOV  A,#0A0H  ;送器件地址
     ACALL    SENDBYTE
     MOV  A,R4  ;送片内字节地址
     ACALL SUBS
AGAIN:   MOV A,@R1
     ACALL   SENDBYTE ;调发送单字节子程序INC     R1
     DJNZ  R7,AGAIN;连续写n个字节
;产生I2C总线数据传输停止信号
STOP:             SETB         SCL                        
                      CLR           SDA
                      ACALL       SOMENOP
                      SETB         SDA
                      ACALL       SOMENOP
     RET
;产生I2C总线数据传输起始信号
START:           SETB         SDA                         ;置SDA为高电平状态
                      SETB         SCL                         ;置SCL为高电平状态
                      ACALL       SOMENOP                 ;模拟SCL高电平状态计数
                      CLR           SDA                         ;使SDA产生一个由高到低的跳变
                      ACALL       SOMENOP                 ;延时,模拟SDA低电平状态计数
                      CLR           SCL                         ;将SCL置为低电平状态
                      RET  

;SENDBYTE     向I2C总线发送一个字节        
;ACC待发送的数据字节存放在ACC中
SENDBYTE:     MOV           COUNTER,#08H       ;一个字节共送出8位数据
SENDBYTE1:   CLR           SCL                         ;置SCL为低电平状态
                      RLC           A                             ;带进位循环左移,将最高位移至C


                      MOV           SDA,C                     ;将当前数据位送到数据线SDA
                      ACALL       SOMENOP                 ;计数SCL低电平状态周期数
                      SETB         SCL                         ;置SCL为高电平状态
                      ACALL       SOMENOP                 ;计数SCL高电平状态周期数
                      DJNZ         COUNTER,SENDBYTE1     ;判断8个数据是否发送完成
                      CLR           SCL                           ;字节发送完成,置SCL为低电平状态
                      ;RET
;等待从机(或接收器)返回一个响应信号ACK(或新的开始数据传输信号)
WAITACK:       CLR           SCL                         ;置SCL为低电平
                      SETB         SDA                         ;释放SDA信号线
                      ACALL       SOMENOP                 ;延时,从机或接收器的响应信号\应该在这段延时期间出现
                      SETB         SCL                         ;置SCL为高电平,准备判断SDA
                      ACALL       SOMENOP     ;延时
WAITACK1:     MOV           C,SDA                    
                      JC             WAITACK                 ;SDA为低电平,返回了响应信号\否则等待新的开始数据传输信号
                      CLR           SDA                         ;响应信号ACK或新的开始数据传输\信号出现,将SDA置为低电平状态
                      CLR           SCL                         ;将SCL置为低电平状态
                      ;RET
;向I2C总线发出一个响应信号ACK
ACK:               CLR           SDA                         ;在SCL为低电平期间改变SDA状态
                      ACALL       SOMENOP                 ;置SDA为低电平
                      SETB         SCL                         ;释放SCL信号线


                      ACALL       SOMENOP                 ;延时
                      CLR           SCL                         ;完成高电平状态计时,使SCL重新进入低电平状态
                      RET
;延时子程序
SOMENOP:       MOV           COUNTER1,#00H     ;延时用计数器清零
SOMNOP1:                              
                      DJNZ         COUNTER1,SOMNOP1     ;判断延时计数器是否结束
                      RET
                      END
    



[解决办法]
我有调试成功的IIC模拟程序,email:tl_mail@126.com

热点排行