打印

请大师们看看我的AT24C02N程序

[复制链接]
2285|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
EWB5|  楼主 | 2012-2-2 14:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 EWB5 于 2012-2-2 19:12 编辑

已经弄iic一周了,时好时坏,就是这个汇编程序看不出哪儿不行,用的海象nimi开发板(24M)P2接的是74138;程序如下(自己写的),特意放慢速度,在proteus上运行正常0-7显示,但在板子上不显示0-4,理论上应该一直向后显示的 程序如下:
STORE_PLACE  EQU 00H            ;24C02芯片内的缓冲区首址
SEND_DATA    EQU 30H
RECE_DATA  EQU 40H
wr_cmd EQU 0aeH
re_cmd EQU 0afH
NUM1    EQU  8
NUM2    EQU  8      
Sda bit p1.2
Scl bit p1.1
WP bit p1.0
ORG 0000h                                                                                                       
AJMP MAIN   
ORG 0030H
;----------------主函数--------------------------                  
MAIN:     
          MOV 30H,#3fH      
          MOV 31H,#06H
          MOV 32H,#5bH            
              MOV 33H,#4fH;  
          MOV 34H,#66H      
          MOV 35H,#6DH
          MOV 36H,#7DH            
              MOV 37H,#07H;
                  CLR WP             
          LCALL MAIN_WRITE
                  LCALL DELAY_S
          LCALL MAIN_READ
          MOV R0,#RECE_DATA
LOOP:     MOV p2,#0fH
                  MOV p0,@R0
          MOV p2,#02H
                                                                  
                  LCALL DELAY_S  
                  LCALL DELAY_S        
                  INC R0  
                      
              AJMP LOOP       
                  AJMP $               
;*************************页存储num字节的数据***********************  
MAIN_WRITE: MOV R5,#NUM1                
            MOV R0,#SEND_DATA        ;发送缓冲区
            MOV R1,#STORE_PLACE                  ;存储地址设置
L0:   LCALL START          ;启动
L1:   MOV A,#wr_cmd               ;写控制
            LCALL SEND                          
                        LCALL CHECK_ACK
                        JB F0,L1                                  
L2:   MOV A,R1                        ;存储地址设置
            LCALL SEND                             
                        LCALL CHECK_ACK
                        JB F0,L2                                 
L3:   MOV A,@R0                              ;发送数据
            LCALL SEND
                        LCALL CHECK_ACK               
                JB F0,L3   
           LCALL STOP                          
                        LCALL DELAY_10MS
                        LCALL DELAY_10MS
                                         
                INC R0
                        INC R1
            DJNZ R5,L0      ;发送所有字节                                                      
                LCALL DELAY_10MS
                        RET
;*******************Radom读取num字节的数据**************************
MAIN_READ:  MOV R5,#NUM2
            MOV R0,#RECE_DATA
                        MOV R1,#STORE_PLACE                 ;存储缓冲区        
L4:     LCALL START          ;启动
L5:     MOV A,#wr_cmd     ;写控制   
            LCALL SEND
                        LCALL CHECK_ACK   
                        JB F0,L5
L6:     MOV A,R1        ;存储地址设置
            LCALL SEND
                        LCALL CHECK_ACK           
                  JB F0,L6                     
        LCALL START   ; 再次启动
L7:     MOV A,#re_cmd                 ;读控制
            LCALL SEND
                        LCALL CHECK_ACK           
            JB F0,L7                          
L8:     LCALL RECE           ;读取一个字节数据,结束   
                LCALL SEND_NOACK                       
                LCALL STOP
              MOV @R0,A

                    INC R0
            INC R1                         
            DJNZ R5, L4                     
                        LCALL DELAY_10MS;
                RET                
;----------------IIC启动---------------------------------
START:  CLR scl
        LCALL DELAY
        SETB sda
        LCALL DELAY   
        SETB scl
        LCALL DELAY         
        CLR sda
        LCALL DELAY
        CLR scl
                LCALL DELAY
        RET
;---------------IIC停止----------------------------------
STOP:   CLR sda               
        LCALL DELAY
        SETB scl
        LCALL DELAY
        SETB sda
        LCALL DELAY
                CLR scl
                LCALL DELAY
        RET
;-------------SEND_ACK是发送应答位子程序---------
SEND_ACK:    CLR sda                ;拉低sda线
             LCALL DELAY
             SETB scl               ;发出时钟信号
             LCALL DELAY
             CLR scl
                         LCALL DELAY                          
                         SETB sda;
                         LCALL DELAY
             RET
;------------SEND_NOACK是发送应答位子程序---------
SEND_NOACK:  CLR scl
             LCALL DELAY
             SETB sda            ;拉高sda线
                         LCALL DELAY
             SETB scl               ;发出时钟信号
             LCALL DELAY
             CLR scl
             LCALL DELAY

                         CLR sda;                        ;拉低sda线
                         LCALL DELAY
             RET
;------------CHECK_ACK是检查应答信号---------
CHECK_ACK:   CLR  F0
             SETB sda               ;拉高sda为输入方式
                         LCALL DELAY
             SETB scl               ;发出一个时钟
             LCALL DELAY
CHECK_LOOP:  JNB sda,CHECK_ACK_END    ;如果sda为0 则收到应答
                         SETB F0            ;如果sda为1 F0=1;
CHECK_ACK_END:                           
             CLR scl                ;否则sda为0,表示接受到应答位,结束时钟
             LCALL DELAY
                     RET
;----------------SEND是发送一个字节8 bit子程序---------------------------
SEND:        MOV R7,#8H            
WRB0 :            RLC A                                  ;左环移,把A的最高位移入cy  
             JC WRB1         
                         CLR sda
                         LCALL DELAY
                         SETB scl           ;发出一个时钟               
                         LCALL DELAY
                         CLR scl
                         LCALL DELAY
                         DJNZ R7, WRB0
                         RET
WRB1:        SETB sda
             LCALL DELAY
             SETB scl                  ;在scl上产生一个时钟
             LCALL DELAY
                CLR scl
         LCALL DELAY
          CLR sda
             DJNZ R7, WRB0     ;重复8次,发送一个字节                                                                                                   
             RET
;---------------RECE是读取一个字节8 bit的数据-----------------------------
RECE:    MOV R7,#08H                             
             CLR A             
RECE_LOOP:   SETB sda     
                    SETB scl               ;发出一个时钟
             LCALL DELAY
                    MOV C,sda              ;读入sda状态
             RLC A                  ;把该位的状态移入A中
                         CLR scl
             LCALL DELAY                               
             DJNZ R7,RECE_LOOP      ;重复8次,读入一个字节       
                 RET
;------------------延时程序----------------------------------------
DELAY :  nop                       ;延时us子程序
         nop
         nop
         nop
                 nop
                 nop
                 nop
         RET

DELAY_10MS: MOV R2,#24
del4:      MOV R3,#250  
del5:      DJNZ R3,del5
           DJNZ R2,del4
                   RET
DELAY_S: MOV R2,#10         
del1:    MOV R3,#200
del2:    MOV R4,#250  
del3:    DJNZ R4,del3
           DJNZ R3,del2
           DJNZ R2,del1   
           RET

  END


  END

相关帖子

沙发
zjsyjbb| | 2012-2-2 14:13 | 只看该作者
不知道楼主调试过没有??

使用特权

评论回复
板凳
EWB5|  楼主 | 2012-2-2 14:45 | 只看该作者
调了一下的,我开发板配套的C语言程序写四位然后读四位看是否一致是正确的,数码管会显示1234循环,但如果改为读6就显示1288,如果说当页写指针已经回归到0,那后面两位数也不应该是88啊,所以我写了这个汇编程序,但情况更糟,不显示,您看这个程序可能哪儿的问题,会不会硬件?

使用特权

评论回复
地板
EWB5|  楼主 | 2012-2-2 14:45 | 只看该作者
本帖最后由 EWB5 于 2012-2-2 14:50 编辑

还有就是开发板原来的程序,没有检查应答的程序,他是自己直接应答信号的,我就纳闷为什么这样也行。。。

使用特权

评论回复
5
EWB5|  楼主 | 2012-2-2 14:45 | 只看该作者
调了一下的,我开发板配套的C语言程序写四位然后读四位看是否一致是正确的,数码管会显示1234循环,但如果改为读6就显示1288,如果说当页写指针已经回归到0,那后面两位数也不应该是88啊,所以我写了这个汇编程序,但情况更糟,不显示,您看这个程序可能哪儿的问题,会不会硬件?

使用特权

评论回复
6
EWB5|  楼主 | 2012-2-2 14:45 | 只看该作者
调了一下的,我开发板配套的C语言程序写四位然后读四位看是否一致是正确的,数码管会显示1234循环,但如果改为读6就显示1288,如果说当页写指针已经回归到0,那后面两位数也不应该是88啊,所以我写了这个汇编程序,但情况更糟,不显示,您看这个程序可能哪儿的问题,会不会硬件?

使用特权

评论回复
7
bd7qwmcu| | 2012-2-2 18:02 | 只看该作者
看到了熟悉的汇编呀,亲切

使用特权

评论回复
8
fliger| | 2012-2-2 18:35 | 只看该作者
好多年 没看程序了。  估计再过几年 就像看天书了

使用特权

评论回复
9
dengm| | 2012-2-3 00:20 | 只看该作者
;------------CHECK_ACK是检查应答信号---------
CHECK_ACK:  
             CLR  F0
             SETB sda               ;拉高sda为输入方式
         LCALL DELAY
CHECK_LOOP:
             JNB sda,CHECK_ACK_END    ;如果sda为0 则收到应答
            SETB F0            ;如果sda为1 F0=1; ERROR
                  CLR SDA           ; ERROR FOR STOP *******
                  LCALL DELAY
                  SETB scl
                  LCALL DELAY
                  SETB SDA        ; STOP
                  LCALL DELAY
                  RET     

CHECK_ACK_END:                           
             SETB scl
          LCALL DELAY
             CLR SCL
             LCALL DELAY
             RET

使用特权

评论回复
10
outstanding| | 2013-8-16 16:24 | 只看该作者
汇编啊,头大

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:小鸟一个有待提高

0

主题

14

帖子

0

粉丝