找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2514|回复: 7
收起左侧

PIC16F873A单片机eeprom 24C02-24C64数据抄写程序求助

[复制链接]
ID:655665 发表于 2021-9-6 21:05 | 显示全部楼层 |阅读模式
   网上找的,PIC16F873A单片机eeprom 24C02-24C64数据抄写程序,用MPLAB IDE编译,报告一大堆错误,求助大虾帮忙看看这个汇编程序到底错在哪里?程序如下:
  1. ;****************I2C总线EPROM数据抄写程序*******************
  2. TRISB       EQU          86H              ;
  3. PORTB       EQU          06H              ;
  4.         #DEFINE     SDA1      PORTB,2     ;
  5.         #DEFINE     SDA2      PORTB,3     ;
  6.         #DEFINE     SCL      PORTB,1     ;
  7.         #DEFINE     SDAIO1    TRISB,2     ;
  8.         #DEFINE     SDAIO2    TRISB,3     ;
  9.         #DEFINE     SCLIO    TRISB,1     ;  
  10. TXBUF       EQU         20H              ;
  11. RXBUF       EQU         21H              ;
  12. BCOUNT      EQU         22H              ;
  13. LDZJCQ      EQU         23H              ;
  14. HGZJCQ      EQU         24H              ;
  15. TRISD       EQU         88H              ;
  16. PORTD       EQU         08H              ;
  17. TRISE       EQU         89H              ;
  18. PORTE       EQU         09H              ;
  19. ADCON1      EQU         9FH              ;
  20. STATUS      EQU         03H              ;
  21. Z           EQU          2               ;
  22. RP0         EQU          5               ;
  23. RP1         EQU          6               ;
  24. W           EQU          0               ;
  25. F           EQU          1               ;
  26. C           EQU          0               ;
  27. ;*******************************************
  28.                     BCF      STATUS,RP1  ;
  29.                     BSF      STATUS,RP0  ;
  30.                     MOVLW    0x3F        ;
  31.                     MOVWF    TRISD       ;
  32.                     MOVLW    0x06    ;
  33.                     MOVWF    ADCON1      ;
  34.                     CLRF     TRISE       ;
  35.                     BCF      STATUS,RP0  ;
  36.                     MOVLW    0x00        ;
  37.                     MOVWF    PORTD       ;
  38.                     MOVLW    0x00        ;
  39.                     MOVWF    PORTE       ;
  40.                     MOVLW    0x00        ;
  41.                     MOVWF    PORTB       ;
  42.                     CLRF     LDZJCQ      ;
  43.                     CLRF     HGZJCQ      ;                  
  44. ROMSJ               CLRF     RXBUF       ;
  45.                     CLRF     TXBUF       ;
  46.                     CALL     DCZZCX      ;
  47.                     CALL     XCZZCX      ;
  48.                     BSF      PORTE,0     ;
  49. JCEEP2ROM           BTFSC    PORTD,0     ;
  50.                     GOTO     C02JCOK     ;
  51.                     BTFSC    PORTD,1     ;
  52.                     GOTO     C04JCOK     ;
  53.                     BTFSC    PORTD,2     ;
  54.                     GOTO     C08JCOK     ;
  55.                     BTFSC    PORTD,3     ;
  56.                     GOTO     C16JCOK     ;
  57.                     BTFSC    PORTD,4     ;
  58.                     GOTO     C32JCOK     ;
  59.                     BTFSC    PORTD,5     ;
  60.                     GOTO     C64JCOK     ;
  61.                     BSF      PORTE,2     ;
  62.                     GOTO     JCEEP2ROM    ;
  63. C02JCOK             BCF      PORTE,2      ;
  64.                     MOVLW    11111111B    ;
  65.                     XORWF    LDZJCQ,0     ;
  66.                     BTFSC    STATUS,Z     ;
  67.                     GOTO     CXEEP2ROMOK  ;
  68.                     INCF     LDZJCQ,1     ;
  69.                     GOTO     ROMSJ        ;
  70. C04JCOK             BCF      PORTE,2      ;
  71.                     XORWF    HGZJCQ,0     ;
  72.                     BTFSC    STATUS,Z     ;
  73.                     GOTO     CXEEP2ROMOK  ;
  74.                     INCF     HGZJCQ,10000000B ;
  75.                     INCF     LDZJCQ,1     ;
  76.                     GOTO     ROMSJ        ;
  77. C08JCOK             BCF      PORTE,2      ;
  78.                     MOVLW    11111111B    ;
  79.                     XORWF    LDZJCQ,0     ;
  80.                     BTFSC    STATUS,Z     ;
  81.                     GOTO     C08HJCOK     ;
  82.                     INCF     LDZJCQ,1     ;
  83.                     GOTO     ROMSJ        ;
  84. C08HJCOK            MOVLW    11000000B    ;
  85.                     XORWF    HGZJCQ,0     ;
  86.                     BTFSC    STATUS,Z     ;
  87.                     GOTO     CXEEP2ROMOK  ;
  88.                     INCF     HGZJCQ,1000000B ;
  89.                     INCF     LDZJCQ,1     ;
  90.                     GOTO     ROMSJ        ;
  91. C16JCOK             BCF      PORTE,2      ;
  92.                     MOVLW    11111111B    ;
  93.                     XORWF    LDZJCQ,0     ;
  94.                     BTFSC    STATUS,Z     ;
  95.                     GOTO     C16HJCOK     ;
  96.                     INCF     LDZJCQ,1     ;
  97.                     GOTO     ROMSJ        ;
  98. C16HJCOK            MOVLW    11100000B    ;
  99.                     XORWF    HGZJCQ,0     ;
  100.                     BTFSC    STATUS,Z     ;
  101.                     GOTO     CXEEP2ROMOK  ;
  102.                     INCF     HGZJCQ,100000B ;
  103.                     INCF     LDZJCQ,1     ;
  104.                     GOTO     ROMSJ        ;
  105. C32JCOK             BCF      PORTE,2      ;
  106.                     MOVLW    11111111B    ;
  107.                     XORWF    LDZJCQ,0     ;
  108.                     BTFSC    STATUS,Z     ;
  109.                     GOTO     C32HJCOK     ;
  110.                     INCF     LDZJCQ,1     ;
  111.                     GOTO     ROMSJ        ;
  112. C32HJCOK            MOVLW    11110000B    ;
  113.                     XORWF    HGZJCQ,0     ;
  114.                     BTFSC    STATUS,Z     ;
  115.                     GOTO     CXEEP2ROMOK  ;
  116.                     INCF     HGZJCQ,10000B ;
  117.                     INCF     LDZJCQ,1     ;
  118.                     GOTO     ROMSJ        ;
  119. C64JCOK             BCF      PORTE,2      ;
  120.                     MOVLW    11111111B    ;
  121.                     XORWF    LDZJCQ,0     ;
  122.                     BTFSC    STATUS,Z     ;
  123.                     GOTO     C64HJCOK     ;
  124.                     INCF     LDZJCQ,1     ;
  125.                     GOTO     ROMSJ        ;
  126. C64HJCOK            MOVLW    11111000B    ;
  127.                     XORWF    HGZJCQ,0     ;
  128.                     BTFSC    STATUS,Z     ;
  129.                     GOTO     CXEEP2ROMOK  ;
  130.                     INCF     HGZJCQ,1000B ;
  131.                     INCF     LDZJCQ,1     ;
  132.                     GOTO     ROMSJ        ;
  133. ;*******************************************************
  134. CXEEP2ROMOK         BCF      PORTE,0      ;
  135.                     BSF      PORTE,1      ;
  136.                     GOTO     CXEEP2ROMOK  ;
  137. ;*************************************
  138. DCZZCX              CALL     DI2CSTAR     ;
  139. DXFQD               MOVLW    0xA0          ;
  140.                     MOVWF    TXBUF        ;
  141.                     CALL     DCZFSQJDZ    ;
  142.                     CALL     DMPYDJC      ;
  143.                     BTFSS    STATUS,C     ;
  144.                     GOTO     MPYYD        ;
  145.                     BSF      PORTD,6      ;
  146.                     GOTO     DXFQD        ;
  147. MPYYD               BCF      PORTD,6      ;
  148. MPYYD2              BCF      PORTD,6      ;      
  149. MPYYD3              BCF      PORTD,6      ;
  150. DMP1ZJ              CALL     DRDBYT       ;
  151.                     CALL     DMNACK       ;
  152. DMPJS               CALL     DI2CSTOP     ;
  153.                     RETURN                   ;
  154. ;***********************************
  155. DI2CSTAR     BSF         STATUS,RP0
  156.             BCF         SDAIO1
  157.             BCF         SCLIO
  158.             BCF         STATUS,RP0
  159.             BSF         SDA1
  160.             BSF         SCL                  
  161.             BCF         SDA1         ;
  162.             BCF         SCL
  163.             RETURN                   ;               
  164. ;*******************************************
  165. DCZFSQJDZ   MOVLW       8
  166.             MOVWF       BCOUNT
  167.             BSF         STATUS,RP0
  168.             BCF         SDAIO1
  169.             BCF         STATUS,RP0
  170. DFQDWLP     RLF         TXBUF,F
  171.             BTFSC       STATUS,C
  172.             GOTO        DFQDWR1
  173.             BCF         SDA1         ;
  174.             BCF         TXBUF,0
  175.             BSF         SCL
  176.             BCF         SCL
  177.             GOTO        DFQDDONE32
  178. DFQDWR1     BSF         SDA1        ;
  179.             BSF         TXBUF,0
  180.             BSF         SCL
  181.             BCF         SCL
  182.             BCF         SDA1
  183. DFQDDONE32  DECFSZ      BCOUNT,F    ;
  184.             GOTO        DFQDWLP
  185.             RETURN                   ;
  186. ;******************************************************
  187. DMNACK      BSF         SDA1
  188.             BSF         STATUS,RP0
  189.             BCF         SDAIO1
  190.             BCF         STATUS,RP0
  191.             BSF         SCL
  192.             NOP
  193.             NOP
  194.             BCF         SCL
  195.             BCF         SDA1
  196.             RETURN                   ;
  197. ;*******************************************
  198. DI2CSTOP    BCF         SDA1
  199.             BSF         STATUS,RP0
  200.             BCF         SDAIO1
  201.             BCF         STATUS,RP0
  202.             BSF         SCL
  203.             NOP
  204.             NOP                     
  205.             BSF         SDA1         ;
  206.             NOP
  207.             NOP
  208.             RETURN                   ;
  209. ;***********************************************************
  210. XCZZCX              CALL     XI2CSTAR     ;
  211. XXFQD               MOVLW    0xA0         ;
  212.                     MOVWF    TXBUF        ;
  213.                     CALL     XCZFSQJDZ    ;
  214.                     CALL     XMPYDJC      ;
  215.                     BTFSS    STATUS,C     ;
  216.                     GOTO     XMPYYD       ;
  217.                     BSF      PORTD,7      ;
  218.                     GOTO     XXFQD        ;
  219. XMPYYD              BCF      PORTD,7      ;
  220. XFEEPOROMDYDZ       CALL     XEEP2ROMDZJC ;
  221.                     MOVLW    LDZJCQ       ;
  222.                     MOVWF    TXBUF        ;
  223.                     CALL     XCZFSQJDZ    ;
  224.                     CALL     XMPYDJC      ;
  225.                     BTFSS    STATUS,C     ;
  226.                     GOTO     XMPYYD2      ;
  227.                     BSF      PORTD,7      ;
  228.                     GOTO     XFEEPOROMDYDZ ;
  229. XMPYYD2             BCF      PORTD,7      ;
  230. CXSJFS              MOVWF    RXBUF        ;
  231.                     MOVWF    TXBUF        ;
  232.                     CALL     XCZFSQJDZ    ;
  233.                     CALL     XMPYDJC      ;
  234.                     BTFSS    STATUS,C     ;
  235.                     GOTO     XMPYYD3      ;
  236.                     BSF      PORTD,7      ;
  237.                     GOTO     CXSJFS       ;
  238. XMPYYD3             BCF      PORTD,7      ;
  239.                     CALL     XI2CSTOP     ;
  240.                     RETURN                   ;
  241. ;*************************************************
  242. XI2CSTAR    BSF         STATUS,RP0
  243.             BCF         SDAIO2
  244.             BCF         SCLIO
  245.             BCF         STATUS,RP0
  246.             BSF         SDA2
  247.             BSF         SCL
  248.             NOP
  249.             NOP                     
  250.             BCF         SDA2         ;
  251.             NOP
  252.             NOP
  253.             BCF         SCL
  254.             RETURN                   ;
  255. ;*******************************************
  256. XCZFSQJDZ   MOVLW       8
  257.             MOVWF       BCOUNT
  258.             BSF         STATUS,RP0
  259.             BCF         SDAIO2
  260.             BCF         STATUS,RP0
  261. XFQDWLP     RLF         TXBUF,F
  262.             BTFSC       STATUS,C
  263.             GOTO        XFQDWR1
  264.             BCF         SDA2         ;
  265.             BCF         TXBUF,0
  266.             BSF         SCL
  267.             NOP
  268.             NOP
  269.             BCF         SCL
  270.             GOTO        XFQDDONE32
  271. XFQDWR1     BSF         SDA2        ;
  272.             BSF         TXBUF,0
  273.             BSF         SCL
  274.             NOP
  275.             NOP
  276.             BCF         SCL
  277.             BCF         SDA2
  278. XFQDDONE32  DECFSZ      BCOUNT,F    ;
  279.             GOTO        XFQDWLP
  280.             RETURN                   ;
  281. ;*************************************************
  282. XEEP2ROMDZJC        BTFSC    PORTD,0     ;
  283.                     GOTO     XC02JC     ;
  284.                     BTFSC    PORTD,1     ;
  285.                     GOTO     XC04JC     ;
  286.                     BTFSC    PORTD,2     ;
  287.                     GOTO     XC08JC     ;
  288.                     BTFSC    PORTD,3     ;
  289.                     GOTO     XC16JC     ;
  290.                     BTFSC    PORTD,4     ;
  291.                     GOTO     XC32JC     ;
  292.                     BTFSC    PORTD,5     ;
  293.                     GOTO     XC64JC     ;
  294.                     BSF      PORTE,2     ;
  295.                     GOTO     XEEP2ROMDZJC    ;
  296. XC02JC              BCF      PORTE,2      ;
  297.                     RETURN
  298. XC04JC      BCF      PORTE,2      ;
  299.             MOVLW       HGZJCQ    ;
  300.             MOVWF       TXBUF     ;
  301.             MOVLW       1
  302.             MOVWF       BCOUNT
  303.             BSF         STATUS,RP0
  304.             BCF         SDAIO2
  305.             BCF         STATUS,RP0
  306. XHG04WLP    RLF         TXBUF,F
  307.             BTFSC       STATUS,C
  308.             GOTO        XHG04WR1
  309.             BCF         SDA2         ;
  310.             BCF         TXBUF,0
  311.             BSF         SCL
  312.             NOP
  313.             NOP
  314.             BCF         SCL
  315.             GOTO        XHG04DONE32
  316. XHG04WR1    BSF         SDA2         ;
  317.             BSF         TXBUF,0
  318.             BSF         SCL
  319.             NOP
  320.             NOP
  321.             BCF         SCL
  322.             BCF         SDA2
  323. XHG04DONE32 DECFSZ      BCOUNT,F    ;
  324.             GOTO        XHG04WLP
  325.             RETURN
  326. XC08JC      BCF      PORTE,2      ;
  327.             MOVLW       HGZJCQ    ;
  328.             MOVWF       TXBUF     ;
  329.             MOVLW       2
  330.             MOVWF       BCOUNT
  331.             BSF         STATUS,RP0
  332.             BCF         SDAIO2
  333.             BCF         STATUS,RP0
  334. XHG08WLP    RLF         TXBUF,F
  335.             BTFSC       STATUS,C
  336.             GOTO        XHG08WR1
  337.             BCF         SDA2         ;
  338.             BCF         TXBUF,0
  339.             BSF         SCL
  340.             NOP
  341.             NOP
  342.             BCF         SCL
  343.             GOTO        XHG08DONE32
  344. XHG08WR1    BSF         SDA2         ;
  345.             BSF         TXBUF,0
  346.             BSF         SCL
  347.             NOP
  348.             NOP
  349.             BCF         SCL
  350.             BCF         SDA2
  351. XHG08DONE32 DECFSZ      BCOUNT,F    ;
  352.             GOTO        XHG08WLP
  353.             RETURN
  354. XC16JC      BCF         PORTE,2      ;
  355.             MOVLW       HGZJCQ    ;
  356.             MOVWF       TXBUF     ;
  357.             MOVLW       3
  358.             MOVWF       BCOUNT
  359.             BSF         STATUS,RP0
  360.             BCF         SDAIO2
  361.             BCF         STATUS,RP0
  362. XC32JC      BCF         PORTE,2      ;
  363.             MOVLW       HGZJCQ    ;
  364.             MOVWF       TXBUF     ;
  365.             MOVLW       4
  366.             MOVWF       BCOUNT
  367.             BSF         STATUS,RP0
  368.             BCF         SDAIO2
  369.             BCF         STATUS,RP0
  370. XHG32WLP    RLF         TXBUF,F
  371.             BTFSC       STATUS,C
  372.             GOTO        XHG32WR1
  373.             BCF         SDA2         ;
  374.             BCF         TXBUF,0
  375.             BSF         SCL
  376.             NOP
  377.             NOP
  378.             BCF         SCL
  379.             GOTO        XHG32DONE32
  380. XHG32WR1    BSF         SDA2         ;
  381.             BSF         TXBUF,0
  382.             BSF         SCL
  383.             NOP
  384.             NOP
  385.             BCF         SCL
  386.             BCF         SDA2
  387. XHG32DONE32 DECFSZ      BCOUNT,F    ;
  388.             GOTO        XHG32WLP
  389.             RETURN
  390. XHG64WLP    RLF         TXBUF,F
  391.             BTFSC       STATUS,C
  392.             GOTO        XHG64WR1
  393.             BCF         SDA2         ;
  394.             BCF         TXBUF,0
  395.             BSF         SCL
  396.             NOP
  397.             NOP
  398.             BCF         SCL
  399.             GOTO        XHG64DONE32
  400. XHG64WR1    BSF         SDA2         ;
  401.             BSF         TXBUF,0
  402.             BSF         SCL
  403.             NOP
  404.             NOP
  405.             BCF         SCL
  406.             BCF         SDA2
  407. XHG64DONE32 DECFSZ      BCOUNT,F    ;
  408.             GOTO        XHG64WLP
  409.             RETURN                   ;
  410. ;*******************************************
  411. XI2CSTOP    BCF         SDA2
  412.             BSF         STATUS,RP0
  413.             BCF         SDAIO2
  414.             BCF         STATUS,RP0
  415.             BSF         SCL
  416.             NOP
  417.             NOP                     
  418.             BSF         SDA2         ;
  419.             NOP
  420.             NOP
  421.             RETURN                   ;
  422.             END
  423. ;***************程序结束***********************
复制代码



回复

使用道具 举报

ID:401564 发表于 2021-9-6 22:29 | 显示全部楼层
学PIC的本来就少,你还是用汇编的,而且一个汉字注释都没有,你觉得别人能看明白?
这是我以前写的24C02的验证程序,已经在开发板上实际验证过的,你对比一下吧
我已经好久没有用PIC汇编了,指令都快忘记完了

    #include <p16f877a.inc>        ;包含了PIC16F877A的寄存器声称文件
    __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF;配置设置生成的代码

    CBLOCK  020H                ;定义连续变量
    COUNT                        ;计数用的
    DEL1                        ;用在延时子程序中
    DEL2                        ;用在延时子程序中
    DEL3                        ;
    DISP_ADDR                        ;显示地址用寄存器
    DISP_DATA                        ;显示数据用寄存器
    LED_1                        ;七段码的个位
    LED_10                        ;七段码的十位
    LED_100                        ;七段码的百位
    DIV_DATA                        ;除法用寄存器
    DATA_BUF                        ;数据写入和读出用的缓冲器
    SESHI                        ;测试用寄存器
    ENDC                        ;结束定义
#define    S1        PORTB,0                ;按置S1
#define    S2        PORTB,1                ;按置S2
#define    S3        PORTB,2                ;按置S3
#define           COM0        PORTD,0                ;
#define           COM1        PORTD,1                ;
#define           COM2        PORTD,2                ;
#define           COM3        PORTD,3                ;定义几个显示的RA端口
#define            CY        STATUS,0        ;C为标志位,减法有借位=0,无借位=1
#define            SCL        PORTD,4                ;时钟信号线
#define            SDA        PORTD,7                ;数据信号线
#define            SDA_C   TRISD,7        ;数据方向控制寄存器   
          
        ORG        00H                ;
        NOP                        ;这条指令是仿真要有的
        GOTO        MAIN                ;跳过中断子程序       
        ORG        020H                ;
MAIN        BSF        STATUS,RP0        ;RP0=1,RP1=0,指令选择BANK1
        BCF        STATUS,RP1        ;
;===============================================================================       
;以下是针对BANK1的操作==========================================================
        MOVLW   0FFH                ;
        MOVWF        TRISB                ;PORTB        作为输入
        BCF        OPTION_REG,7        ;启用RB的上拉电阻
        BCF        INTCON,3        ;
        MOVLW        00H                ;
        MOVWF        TRISC                ;PORTC        作为输出-数据
        MOVWF        TRISD                ;PORTD        作为输出-位选
        CLRF        TRISE                ;RD工作于正常的IO模式
;以下是针对BANK0的操作==========================================================
        BCF        STATUS,RP0        ;选择BANK0
        CLRF        PORTC                ;
        CLRF        PORTD
;===============================================================================
        MOVLW        D'123'                ;默认数据是000
        MOVWF        DISP_DATA
        MOVLW        D'8'                ;默认地址是0
        MOVWF        DISP_ADDR
;===============================================================================       
LOOP        BTFSS        S1        ;按键1是1就跳过下一条指令
        CALL        S1_DISP        ;调用S1处理程序
        BTFSS        S2        ;S2没有按下就跳过下一条指令
        CALL        S2_DISP        ;按下就调用S2处理子程序
        BTFSS        S3        ;S3没有按下就跳过下一条指令
        CALL        S3_DISP        ;按下就中用S3处理子程序
        CALL        DISPLAY        ;显示
        GOTO        LOOP        ;主程序在这循环
;===============================================================================       
READ_DATA;读出一个字节----------------------------------------------------------
        BCF        SCL            ;
        BSF        SDA            ;SDA1
        BSF        SCL            ;            1
        BCF        SDA            ;SDA1>>0,起始信号
        BCF        SCL            ;
        ;-----------------------------------------------------------------------
        MOVLW        0A0H            ;0A0H为写命令,完整的输入8个位的地址
        CALL        WRITE_BYTE  ;写入"写"模式指令
        MOVFW        DISP_ADDR   ;写入地址
        CALL        WRITE_BYTE  ;
        ;-----------------------------------------------------------------------
        BCF        SCL            ;
        BSF        SDA            ;SDA1
        BSF        SCL            ;               
        BCF        SDA            ;SDA1>>0,起始信号
        BCF        SCL            ;
        ;-----------------------------------------------------------------------
        MOVLW        0A1H            ;0A1H为读命令,完整的输入8个位的地址
        CALL        WRITE_BYTE  ;写入"写"模式指令
        CALL        READ_BYTE   ;读出一个字节
        MOVWF        DISP_DATA
        ;-----------------------------------------------------------------------
        BCF        SCL            ;
        BCF        SDA            ;SDA0
        BSF        SCL            ;
        BSF        SDA            ;SDA0>>1,停止信号
        BCF        SCL            ;
        BCF        SDA
        RETURN
;===============================================================================
WRITE_DATA;写入一个字节---------------------------------------------------------
        BCF        SCL            ;
        BSF        SDA            ;SDA1
        BSF        SCL            ;            1
        BCF        SDA            ;SDA1>>0,起始信号
        BCF        SCL            ;
        ;-----------------------------------------------------------------------
        MOVLW        0A0H            ;0A0H为写命令,完整的输入8个位的地址
        CALL        WRITE_BYTE  ;写入"写"模式指令
        MOVFW        DISP_ADDR   ;写入地址
        CALL        WRITE_BYTE  ;
        MOVFW        DISP_DATA
        CALL        WRITE_BYTE
;-----------------------------------------------------------------------
        BCF        SCL            ;
        BCF        SDA            ;SDA0
        BSF        SCL            ;
        BSF        SDA            ;SDA0>>1,停止信号
        BCF        SCL            ;
        BCF        SDA
        RETURN
;===============================================================================
READ_BYTE;读一个字节处理程序***************************************************
            BSF                STATUS,RP0  ;选择BANK1
            BSF                SDA_C            ;SDA作为输入
            BCF                STATUS,RP0  ;选择BANK0
            MOVLW        D'8'
            MOVWF        COUNT            ;要读出的字节是8
            BCF                SCL            ;时钟0
R_B_LOOP    BCF                CY            ;
            BSF                SCL            ;时钟上升沿
            BTFSC        SDA            ;是0就跳过下一条指令
            BSF                CY            ;是1,置位缓冲器的0位
            RLF                DATA_BUF,F  ;左移一次,从最高位开始读出
            BCF                SCL            ;时钟下降
            DECFSZ        COUNT,F            ;检测是否完成了8个字节
            GOTO        R_B_LOOP    ;
            MOVFW        DATA_BUF    ;读取到的数据保存到W
            BSF                STATUS,RP0  ;选择BANK1
            BCF                SDA_C            ;SDA作为输出
            BSF                SDA            ;
            BSF                SCL            ;
            BCF                SCL            ;
            BCF                SDA            ;
            BCF                STATUS,RP0  ;选择BANK0
RETURN
;===============================================================================
WRITE_BYTE;写入一个字节*********************************************************
            BSF                STATUS,RP0  ;选择BANK1
            BCF                SDA_C            ;SDA作为输出
            BCF                STATUS,RP0  ;选择BANK0
            MOVWF        DATA_BUF    ;
            MOVLW        D'8'            ;
            MOVWF        COUNT            ;
            BCF                SCL            ;时钟0
W_B_LOOP    BCF                SDA            ;清除输出线
            BTFSC        DATA_BUF,7  ;最高位如果是0就跳过下一条指令
            BSF                SDA            ;最高位是1,置位D_I
            CALL        DELAY_5MS   ;延时5mS
            BSF                SCL            ;时钟上升
            CALL        DELAY_5MS
            BCF                SCL            ;时钟下降
            CALL        DELAY_5MS
            RLF                DATA_BUF,F  ;左移一次,
            DECFSZ        COUNT,F            ;检测是否传送完成8个字节
            GOTO        W_B_LOOP    ;没有,跳去循环
            ;应答---------------------------------------------------------------
            BSF                SDA
            BSF                STATUS,RP0  ;选择BANK1
            BSF                SDA_C            ;SDA作为输入
            BCF                STATUS,RP0  ;选择BANK0
            BSF                SCL            ;
            CALL        DELAY_5MS   ;延时5mS
            BTFSC        SDA            ;SDA为0就跳过下一条指令
            GOTO        $-1            ;SDA为1,跳动循环
            BSF                STATUS,RP0  ;选择BANK1
            BCF                SDA_C            ;SDA作为输出
            BCF                STATUS,RP0  ;选择BANK0
            BCF                SCL            ;
            BCF                SDA
RETURN
;===============================================================================
;按一下,数据显示就加1               
S1_DISP;S1处理程序**************************************************************
            BTFSS        S1
            GOTO        $-1
            INCF        DISP_DATA,F ;数据加1,保存到F
            CALL        WRITE_DATA  ;写入数据
            CALL        DELAY_5MS
            CALL        READ_DATA   ;再读出数据
RETURN
;===============================================================================       
S2_DISP;S2处理程序**************************************************************
            BTFSS        S2
            GOTO        $-1
            DECF        DISP_DATA,F ;数据减1,保存到F
            CALL        WRITE_DATA  ;写入数据
            CALL        DELAY_5MS
            CALL        READ_DATA   ;再读出数据
RETURN
;===============================================================================
;按一下,地址就加1,最大显示到9   
S3_DISP        ;S2处理程序*************************************************************
            BTFSS        S3
            GOTO        $-1
            INCF        DISP_ADDR,F        ;地址的值加1
            MOVLW        D'10'                ;10传送到W
            SUBWF        DISP_ADDR,W        ;地址-W,结果保存到W
            BTFSC        CY                ;c进位为1,地址的值就是大于等于9了
            CLRF        DISP_ADDR        ;地址清零
            CALL        READ_DATA        ;再读出数据
RETURN
;===============================================================================
;显示程序***********************************************************************       
DISPLAY            BCF                STATUS,RP0  ;选择BANK0
            CLRF        LED_1
            CLRF        LED_10
            CLRF        LED_100
;除法部分-----------------------------------------------------------------------   
            MOVFW        DISP_DATA   ;送显示数据到W
DIV_100            MOVWF        DIV_DATA    ;W的值保存到寄存器
            MOVLW        D'100'            ;W等于100
            SUBWF        DIV_DATA,W  ;数据减去100,结果保存在W
            BTFSS        STATUS,C    ;C是1就跳过下一条指令,C=1,F就是大,还可以再减法
            GOTO        DIV_10            ;C=0,F已经小于100,跳转到减10
            INCF        LED_100,F   ;F大,百位加1
            GOTO        DIV_100            ;再去减一次
;-------------------------------------------------------------------------------            
DIV_10            MOVLW        D'10'            ;W等于10
            SUBWF        DIV_DATA,W  ;DIV_DATRA-10=
            BTFSS        STATUS,C    ;C=1,DIV_DATA就比W大
            GOTO        DIV_1            ;
            INCF        LED_10,F    ;
            MOVWF        DIV_DATA    ;W数据保存到寄存器
            GOTO        DIV_10            ;
;-------------------------------------------------------------------------------            
DIV_1            MOVFW        DIV_DATA
            MOVWF        LED_1
;显示部分-----------------------------------------------------------------------
            MOVFW        LED_1            ;数据送到W
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;W送到端口
            BCF                COM0            ;低电平,亮灯
            CALL        DELAY_5MS   ;延时5mS
            BSF                COM0            ;高电平,关灯
        ;-----------------------------------------------------------------------
            MOVFW        LED_10            ;
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;
            BCF                COM1            ;
            CALL        DELAY_5MS   ;
            BSF                COM1            ;
        ;-----------------------------------------------------------------------
            MOVFW        LED_100            ;
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;
            BCF                COM2            ;
            CALL        DELAY_5MS   ;
            BSF                COM2            ;
        ;-----------------------------------------------------------------------
            MOVFW        DISP_ADDR   ;显示地址
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;
            BCF                COM3            ;
            CALL        DELAY_5MS   ;
            BSF                COM3            ;
        ;-----------------------------------------------------------------------       
RETURN                                    ;
;===============================================================================
;5mS延时程序********************************************************************
DELAY_5MS   MOVLW        3H
            MOVWF        DEL3
            MOVLW        D'2'            ;
            MOVWF        DEL1            ;
LOOP_5MS1   MOVLW        D'1'            ;
            MOVWF        DEL2            ;
LOOP_5MS2   DECFSZ        DEL2,F            ;
            GOTO        LOOP_5MS2   ;100x2=200uS
            DECFSZ        DEL1,F            ;
            GOTO        LOOP_5MS1   ;
            DECFSZ        DEL3
            GOTO        LOOP_5MS1   ;       
RETURN                                    ;             
;===============================================================================
;BCD码的表**********************************************************************
TAB_LED            
            ADDWF        PCL,F        ;把W的内容叠加到PCL程序计数器上
            RETLW        0FCH        ;0
            RETLW        060H        ;1
            RETLW        0DAH        ;2
            RETLW        0F2H        ;3
            RETLW        066H        ;4
            RETLW        0B6H        ;5
            RETLW        0BEH        ;6
            RETLW        0E0H        ;7
            RETLW        0FEH        ;8
            RETLW        0F6H        ;9
            END

回复

使用道具 举报

ID:96682 发表于 2021-9-6 22:32 来自手机 | 显示全部楼层
代码不全吧
回复

使用道具 举报

ID:655665 发表于 2021-9-7 10:07 | 显示全部楼层
谢谢楼上两位大神。
经过排查发现,有三个调用,标号栏里没有,如下:
142.          CALL DMPYDJC
          ...................
150.   DMP1ZJ CALL DRDBYT
          ..................
214.          CALL XMPYDJC;


而MPYYD2、 MPYYD3、DMP1ZJ、DMPJS这几个标号无任何调用,它们之间有什么联系呢?
148.   MPYYD2 BCF PORTD,6
149.   MPYYD3 BCF PORTD,6
150.   DMP1ZJ CALL DRDBYT
151.         CALL DMNACK
152.   DMPJS CALL DI2CSTOP


1

1

2

2
3.jpg
回复

使用道具 举报

ID:655665 发表于 2021-9-7 22:21 | 显示全部楼层
Y_G_G 发表于 2021-9-6 22:29
学PIC的本来就少,你还是用汇编的,而且一个汉字注释都没有,你觉得别人能看明白?
这是我以前写的24C02的验证 ...

谢谢您的回复,受教了。最近在写E2PROM复制器的程序,就是将两个24C32,将其中一个里面的数据,通过单片机复制到另一个里面去,可总是写不好,思路一直混乱。请大神给指点个好的思路,按您的思路,我在重新写程序。
回复

使用道具 举报

ID:81196 发表于 2021-9-8 16:03 | 显示全部楼层
怎么还在用汇编,我已经全忘完了,只会C了
回复

使用道具 举报

ID:624769 发表于 2021-9-8 16:36 | 显示全部楼层
shumivan 发表于 2021-9-8 16:03
怎么还在用汇编,我已经全忘完了,只会C了

要提高编程能力,汇编是必须要学会的, 可以平时不用, 但必须要会, debug的时候,有问题,看一眼编译出来的汇编,立马就能明白是什么原因造成的,不会的话,会走很多弯路, 然后,C语言里不好控制的时序问题,进到汇编跟砍瓜切菜一样。
程序主体都用C, 有些地方(尤其是涉及底层操作的地方)用点汇编,我觉得还是比较有必要的。
回复

使用道具 举报

ID:155507 发表于 2021-9-8 18:58 | 显示全部楼层
我给你来个 C 程序试试



  1. #include <pic.h>           //调用PIC16F87XA单片机的头文件

  2. //根据选项,配置字应该如下所示:
  3. //__CONFIG(HS&WRTEN&WDTDIS&BOREN&PWRTDIS&UNPROTECT&DUNPROT&DEBUGDIS&LVPDIS);

  4. //实际使用中,这样太麻烦,对于默认选项,我们将其忽略掉:
  5. __CONFIG(HS&WDTDIS&LVPDIS);

  6. //---------------------------------------
  7. //1602液晶相关I/O设置
  8. #define E   RB3            //1602液晶的E脚接在RB3口上
  9. #define RW  RB4            //1602液晶的RW脚接在RB4口上
  10. #define RS  RB5            //1602液晶的RS脚接在RB5口上
  11. //---------------------------------------

  12. //---------------------------------------
  13. //软件模拟IIC相关I/O设置
  14. #define SCL   RC3      //AT24C02的 SCL 引脚接于单片机的RC3引脚上
  15. #define SDA   RC4      //AT24C02的 SDA 引脚接于单片机的RC4引脚上
  16. //---------------------------------------

  17. //---------------------------------------
  18. //1602液晶寄存器设置
  19. unsigned char DISbuf;     //设置8位的unsigend char型寄存器用来暂存1602要显示的内容
  20. //---------------------------------------



  21. void Delay(void)
  22. {
  23.      unsigned char k;      //定义一个8位寄存器用来做延时用
  24.      for(k=0;k<50;k++);    //延时约50微秒
  25. }



  26. void IICstart(void)
  27. {
  28.      SDA=1;                //先将SDA=1,以准备在SCL=1时,将SDA=0
  29.      SCL=1;                //时钟总线拉高
  30.      Delay();              //调用延时函数,略作延时
  31.      SDA=0;                //SCL=1时,将SDA拉低即产生启动信号
  32.      Delay();              //调用延时函数,略作延时
  33.      SCL=0;                //将SCL=0,完成启动信号操作
  34.      Delay();              //调用延时函数,略作延时
  35. }



  36. void IICstop(void)
  37. {
  38.      SDA=0;                //先将SDA=0,以准备在SCL=1时,将SDA=1
  39.      SCL=1;                //时钟总线拉高
  40.      Delay();              //调用延时函数,略作延时
  41.      SDA=1;                //SCL=1时,将SDA拉高即产生停止信号
  42.      Delay();              //调用延时函数,略作延时
  43.      SCL=0;                //将SCL=0,完成启动信号操作
  44.      Delay();              //调用延时函数,略作延时
  45. }



  46. void Write1Byte(unsigned char Buf1)
  47. {
  48.      unsigned char k;      //1个字节要分8次写入,需要定义一个寄存器用来计数
  49.      for(k=0;k<8;k++)      //做一个8次的循环,每次写入1位,需要写8次
  50.      {
  51.          if(Buf1&0x80)     //从最高位开始写
  52.          {
  53.              SDA=1;        //如果欲写入数据为1,就将数据线置1
  54.          }
  55.          else
  56.          {
  57.              SDA=0;        //如果欲写入数据为0,就将数据线写0
  58.          }
  59.          asm("NOP");       //略做延时
  60.          asm("NOP");       //略做延时
  61.          SCL=1;            //时钟线做一个上升沿,将一位数据写入
  62.          Buf1=Buf1<<1;     //数据左移一位,将下次要写入的位数据移到最高位
  63.          asm("NOP");       //略做延时
  64.          SCL=0;            //将SCL=0,以准备通过上升沿将数据写入
  65.          asm("NOP");       //略做延时
  66.      }
  67.      TRISC4=1;             //将RC4(SDA)设置为输入状态
  68.      asm("NOP");           //略做延时
  69.      SCL=1;                //将SCL=1,做个上升沿准备读应答信号
  70.      asm("NOP");           //略做延时
  71.      asm("NOP");           //略做延时
  72.      SCL=0;                //将SCL=0,结束应答信号读操作
  73.      TRISC4=0;             //将RC4(SDA)恢复为输出状态
  74. }



  75. unsigned char Read1Byte(void)
  76. {
  77.      unsigned char k;      //1个字节要分8次读出,需要定义一个寄存器用来计数
  78.      unsigned char t=0;    //定义一个寄存器用保存读出数据
  79.      TRISC4=1;             //将RC4(SDA)设置为输入状态
  80.      for(k=0;k<8;k++)      //做一个8次的循环,每次读入1位,需要读8次
  81.      {
  82.          t=t<<1;           //数据左移一位,空出最低位以准备保存读入的一位数据
  83.          SCL=1;            //将SCL=1,做个上升沿准备读一位数据
  84.          asm("NOP");       //略做延时
  85.          asm("NOP");       //略做延时
  86.          if(SDA==1)        //读一位数据,并判断
  87.          {
  88.              t=t|0x01;     //如果读入数据为1,就将接收缓冲区最低一位置1
  89.          }
  90.          else
  91.          {
  92.              t=t&0xfe;     //如果读入数据为0,就将接收缓冲区最低一位写0
  93.          }
  94.          SCL=0;            //SCL恢复为0,结束一位数据读操作
  95.          asm("NOP");       //略做延时
  96.          asm("NOP");       //略做延时
  97.      }
  98.      TRISC4=0;             //将RC4(SDA)恢复为输出状态
  99.      return t;             //将读入的一个字节返回
  100. }



  101. void WriteAT24C02(unsigned char Address,unsigned char Databuf)
  102. {                          //直接调用本函数即可对AT24C02的Address地址写Databuf
  103.     IICstart();            //IIC启动信号

  104.     Write1Byte(0xA0);      //发送AT24C02的器件地址和写信号

  105.     Write1Byte(Address);   //发送地址

  106.     Write1Byte(Databuf);   //发送数据

  107.     IICstop();             //产生IIC停止信号
  108. }



  109. unsigned ReadAT24C02(unsigned char Address)
  110. {                          //直接调用本函数即可从AT24C02的Address地址读出数据返回
  111.     unsigned char buf;     //定义一个寄存器用来暂存读出的数据
  112.     IICstart();            //IIC启动信号

  113.     Write1Byte(0xA0);      //发送AT24C02的器件地址和写信号

  114.     Write1Byte(Address);   //发送地址

  115.     IICstart();            //IIC启动信号

  116.     Write1Byte(0xA1);      //发送AT24C02的器件地址和读信号

  117.     buf=Read1Byte();//读一个字节数据

  118.     IICstop();             //产生IIC停止信号

  119.     return(buf);           //将读出数据返回
  120. }



  121. void Delay1602(unsigned int t)
  122. {
  123.      unsigned int k;      //定义一个16位寄存器用来做延时用
  124.      for(k=0;k<t;k++);    //延时
  125. }



  126. void LCD1602_busy(void)
  127. {
  128.      TRISD7=1;            //将RD7口设置为输入口,为读做准备
  129.      RS=0;                //RS=0、RW=1、E=1时,忙信号输出到DB7,由RD7读入
  130.      RW=1;                //RS=0、RW=1、E=1时,忙信号输出到DB7,由RD7读入
  131.      E=1;                 //RS=0、RW=1、E=1时,忙信号输出到DB7,由RD7读入
  132.      while(RD7==1);       //由RD7读入1,表示1602液晶忙,需要等待
  133.      E=0;                 //读完以后,恢复E的电平
  134.      TRISD7=0;            //将RD7口设置为输出口
  135. }



  136. void LCD1602_Write_com(unsigned char combuf)
  137. {
  138.      RS=0;                //选择指令寄存器
  139.      RW=0;                //选择写状态
  140.      PORTD=combuf;        //将命令字通过RD口送至DB
  141.      E=1;                 //E高电平将命令字写入1602液晶
  142.      asm("NOP");          //添加一个空操作,使高电平至少维持1us
  143.      E=0;                 //写完以后,恢复E的电平
  144. }



  145. void LCD1602_Write_com_busy(unsigned char combuf)
  146. {
  147.      LCD1602_busy();            //调用忙检测函数
  148.      LCD1602_Write_com(combuf); //调用忙检测函数
  149. }



  150. void LCD1602_Write_data_busy(unsigned char databuf)
  151. {
  152.      LCD1602_busy();      //调用忙检测函数
  153.      RS=1;                //选择数据寄存器
  154.      RW=0;                //选择写状态
  155.      PORTD=databuf;        //将命令字通过RD口送至DB
  156.      E=1;                 //E高电平将命令字写入1602液晶
  157.      asm("NOP");          //添加一个空操作,使高电平至少维持1us
  158.      E=0;                 //写完以后,恢复E的电平
  159. }



  160. void LCD1602_Write_address(unsigned char x,unsigned char y)
  161. {
  162.      x&=0x0f;             //列地址限制在0-15间
  163.      y&=0x01;             //行地址限制在0-1间
  164.      if(y==0)             //如果是第一行
  165.          LCD1602_Write_com_busy(x|0x80);        //将列地址写入
  166.      else                 //如果是第二行
  167.          LCD1602_Write_com_busy((x+0x40)|0x80); //将列地址写入
  168. }



  169. void LCD1602_init(void)
  170. {
  171.      Delay1602(1500);          //调用延时函数
  172.      LCD1602_Write_com(0x38);  //8位数据总线,两行显示模式,5*7点阵显示
  173.      Delay1602(500);           //调用延时函数
  174.      LCD1602_Write_com(0x38);  //8位数据总线,两行显示模式,5*7点阵显示
  175.      Delay1602(500);           //调用延时函数
  176.      LCD1602_Write_com(0x38);  //8位数据总线,两行显示模式,5*7点阵显示
  177.      LCD1602_Write_com_busy(0x38);  //8位数据总线,两行显示模式,5*7点阵显示
  178.      LCD1602_Write_com_busy(0x08);  //显示功能关,无光标
  179.      LCD1602_Write_com_busy(0x01);  //清屏
  180.      LCD1602_Write_com_busy(0x06);  //写入新的数据后,光标右移,显示屏不移动
  181.      LCD1602_Write_com_busy(0x0C);  //显示功能开,无光标
  182. }



  183. void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
  184. {
  185.      LCD1602_Write_address(x,y);    //先将地址信息写入
  186.      LCD1602_Write_data_busy(buf);  //再写入要显示的数据
  187. }



  188. void main(void)            //主函数,单片机开机后就是从这个函数开始运行
  189. {

  190.     TRISB=0B11000111;      //初始化RB7-RB0的输入输出方向
  191.     TRISC=0B11100111;      //初始化RC7-RC0的输入输出方向
  192.     TRISD=0B00000000;      //初始化RD7-RD0的输入输出方向
  193.     PORTB=0B00000000;      //初始化RB7-RB0的数值
  194.     PORTC=0B00000000;      //初始化RC7-RC0的数值
  195.     PORTD=0B00000000;      //初始化RD7-RD0的数值

  196.     LCD1602_init();        //调用1602液晶初始化函数

  197.         DISbuf=ReadAT24C02(0x18);   //从AT24C02中地址0X18读取数据
  198.           DISbuf++;                         //读出数据+1
  199.           WriteAT24C02(0x18,DISbuf);  //将+1后的数据保存到0X18中

  200.         LCD1602_Disp(0,0,'-');   //-
  201.         LCD1602_Disp(1,0,'-');   //-
  202.         LCD1602_Disp(2,0,'A');   //A
  203.         LCD1602_Disp(3,0,'T');   //T
  204.         LCD1602_Disp(4,0,'2');   //2
  205.         LCD1602_Disp(5,0,'4');   //4   
  206.         LCD1602_Disp(6,0,'C');   //C         
  207.         LCD1602_Disp(7,0,'0');   //0
  208.         LCD1602_Disp(8,0,'2');   //2

  209.         LCD1602_Disp(10,0,'T');  //T
  210.         LCD1602_Disp(11,0,'E');  //E
  211.         LCD1602_Disp(12,0,'S');  //S
  212.         LCD1602_Disp(13,0,'T');  //T
  213.         LCD1602_Disp(14,0,'-');   //-
  214.         LCD1602_Disp(15,0,'-');   //-

  215.         LCD1602_Disp(0,1,'B');   //B
  216.         LCD1602_Disp(1,1,'o');   //o
  217.         LCD1602_Disp(2,1,'o');   //o
  218.         LCD1602_Disp(3,1,'t');   //t
  219.    
  220.         LCD1602_Disp(5,1,'t');   //t         
  221.         LCD1602_Disp(6,1,'i');   //i
  222.         LCD1602_Disp(7,1,'m');   //m
  223.         LCD1602_Disp(8,1,'e');   //e
  224.         LCD1602_Disp(9,1,'s');   //s
  225.         LCD1602_Disp(10,1,':');   //:
  226.   
  227.         LCD1602_Disp(12,1,DISbuf/100+0x30);            //显示百位
  228.         LCD1602_Disp(13,1,(DISbuf%100)/10+0x30); //显示十位
  229.         LCD1602_Disp(14,1,DISbuf%10+0x30);            //显示个位
  230.     while(1)               //死循环,单片机初始化后,将一直运行这个死循环
  231.     {

  232.     }
  233. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表