找回密码
 立即注册
查看: 96|回复: 6

请教大家:关于STC32G汇编语言的EEPROM的读写程序

[复制链接]
  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    20

    主题

    104

    回帖

    230

    积分

    中级会员

    积分
    230
    发表于 2024-4-6 16:35:00 | 显示全部楼层 |阅读模式
    本帖最后由 newlined 于 2024-4-6 16:53 编辑

    大家好:我们这里有个产品,以前用的是STC8H的单片机,最近要用到CAN,所以改用STC32G的单片机,不想在读写EEPROM时遇到问题,程序好像有些跑飞。以前的程序读EEPROM时,调用方式如下:


    MOV                DPTR,#ADDR1                                        ;ADDR1是EEPROM的地址 16位
    LCALL              READ
    MOV                DATA1,A                                           ;读出的数据放到DATA1



    写入时,先擦除再写:


                                    MOV                DPTR,#ADDR1
                                    LCALL              SECTOR_ERASE                                        ;删除扇区
                                                                                            ;
                                    MOV                A,DATA1                                                        ;保存
                                    MOV                DPTR,#ADDR1
                                    LCALL              WRITE

    每次读写都是一个字节,为了不修改以前的主程序,我参照STC32G的例程,修改了读写程序,在主程序中用了F0寄存器,在程序中我加了PUSH PSW 和POP PSW 以保护 F0,
    我修改后的程序如下:因为只用了几个字节,所以 IAP_ADDRE我直接置为0,请大家看看哪里出了问题,谢谢。



    IAP_DISABLE:
                                    MOV     IAP_CONTR, #0       ; 禁止ISP/IAP操作
                                    MOV     IAP_CMD,  #0        ; 去除ISP/IAP命令
                                    MOV     IAP_TRIG, #0        ; 防止ISP/IAP命令误触发
                                    MOV     IAP_ADDRE, #0FFH    ; 清0地址高字节
                                    MOV     IAP_ADDRH, #0FFH    ; 清0地址中字节
                                    MOV     IAP_ADDRL, #0FFH    ; 清0地址低字节,指向非EEPROM区,防止误操作
                                    RET

    read:
                                    PUSH    AR2
                                    POP      PSW
            
                                    MOV     IAP_ADDRE, #0                            ; 送地址高字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_ADDRH, DPH                            ; 送地址中字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_ADDRL, DPL                           ; 送地址低字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_CONTR, #IAP_EN                      ; 允许ISP/IAP操作,送一次就够
                                    MOV     IAP_TPS, #TPS_WAIT      ; 设置等待时间,
                                    MOV     IAP_CMD, #1             ; ISP读出命令送字节读命令,命令不需改变时,不需重新送命令
                                    MOV     C, EA
                                    MOV     F0, C                                                                   ;保存EA

                                    CLR     EA                                                                              ; 禁止中断
                                    MOV     IAP_TRIG, #0x5A         ;ISP触发命令
                                    MOV     IAP_TRIG, #0xA5
                                    NOP     
                                    NOP
                                    NOP
                                    NOP
                                    MOV     C, F0
                                    MOV     EA, C       ; 允许中断(如果允许)
                                    LCALL   IAP_DISABLE

                                    MOV     A, IAP_DATA
                                    POP     PSW
                                    POP     AR2
                                    RET

    SECTOR_ERASE:
                                            ;扇区擦除,512字节/扇区。
                                    PUSH        PSW             ;扇区中任意一个字节地址都是扇区地址。
                                    MOV     IAP_ADDRE, #0    ; 送地址高字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_ADDRH, DPH    ; 送地址中字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_ADDRL, DPL    ; 送地址低字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_CONTR, #IAP_EN                      ; 允许ISP/IAP操作,送一次就够
                                    MOV     IAP_TPS, #TPS_WAIT                              ; 设置等待时间,
                                    MOV     IAP_CMD, #3                                                     ;送扇区擦除命令
                                    MOV     C, EA
                                    MOV     F0, C                                                                   ;保存EA
                                    CLR     EA                                                                      ;禁止中断
                                    MOV     IAP_TRIG, #0x5A         ;ISP触发命令
                                    MOV     IAP_TRIG, #0xA5
                                    NOP     
                                    NOP
                                    NOP
                                    NOP
                                    MOV     C, F0
                                    MOV     EA, C                               ; 允许中断(如果允许)
                                    LCALL   IAP_DISABLE
                                    POP      PSW
                                    RET

    WRITE:
                                    PUSH    AR2
                                    PUSH    PSW
                                    
                                    MOV     IAP_ADDRE, #0                                    ; 送地址高字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_ADDRH, DPH                                    ; 送地址中字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_ADDRL, DPL                                    ; 送地址低字节(地址需要改变时才需重新送地址)
                                    MOV     IAP_CONTR, #IAP_EN                      ; 允许ISP/IAP操作,送一次就够
                                    MOV     IAP_TPS, #TPS_WAIT                      ; 设置等待时间,
                                    MOV     IAP_CMD, #2                                     ;送字节写命令,命令不需改变时,不需重新送命令
                                    MOV     C, EA               
                                    MOV     F0, C                                                   ;保存EA

                                    MOV     IAP_DATA, A                                           ; 送数据到IAP_DATA,只有数据改变时才需重新送
                                    CLR     EA                                                      ; 禁止中断
                                    MOV     IAP_TRIG, #0x5A                         ;ISP触发命令
                                    MOV     IAP_TRIG, #0xA5
                                    NOP   
                                    NOP
                                    NOP
                                    NOP
                                    MOV     C, F0
                                    MOV     EA, C       ; 允许中断(如果允许)
                                    LCALL   IAP_DISABLE
                                    POP      PSW
                                    POP     AR2
                                    RET        


    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    20

    主题

    104

    回帖

    230

    积分

    中级会员

    积分
    230
     楼主| 发表于 2024-4-6 16:48:20 | 显示全部楼层
    顺便请教下,在程序中用到了 PUSH    AR2这个语句,貌似  AR2对应R2寄存器?英文实在太拉,那个帮助看不了
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    16

    主题

    724

    回帖

    2578

    积分

    超级版主

    积分
    2578
    发表于 2024-4-6 16:53:19 | 显示全部楼层
    本帖最后由 zhp 于 2024-4-6 16:55 编辑


    下面这句错了,应该是PUSH PSW
    截图202404061652452839.jpg


    另外,你的子程序里面没有使用到R2,
    所以不需要PUSH AR2和POP AR2
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    20

    主题

    104

    回帖

    230

    积分

    中级会员

    积分
    230
     楼主| 发表于 2024-4-6 16:55:47 | 显示全部楼层
    zhp 发表于 2024-4-6 16:53
    下面这句错了,应该是PUSH PSW

    谢谢版主,想不到是这样的错误我再试试。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    20

    主题

    104

    回帖

    230

    积分

    中级会员

    积分
    230
     楼主| 发表于 2024-4-7 09:14:29 | 显示全部楼层
    @ZHP,程序我修改了,比以前好多了,非常感谢,但还是运行不正常。读写EEPROM,只在主程序及主程序调用的子程序中用到,在中断中没有用到,读写EEPROM用到的寄存器DPTR(DPH,DPL),IAP_ADDRE, IAP_ADDRH,  IAP_ADDRL, IAP_CONTR, IAP_TPS, IAP_CMD,IAP_DATA在中断中是不是就没有必要没有保护?在主程序和中断中都用到了A和PSW,所以在中断中我保护了ACC,PSW,以前的程序运行正常,就是换了STC32G,只要加上读写EEPROM部分,就不正常了,还有哪里我没有做到?

    点评

    zhp
    如果你主循环和中断程序都需要同时访问EEPROM 则除了保护ACC、PDW外,IAP相关寄存器都需要保护 更好的方法是:IAP的读、写、擦除均修改为先关闭中断,再进行IAP操作 比如:IAP的读代码可作如下修改  详情 回复 发表于 2024-4-7 17:39
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    16

    主题

    724

    回帖

    2578

    积分

    超级版主

    积分
    2578
    发表于 2024-4-7 17:39:21 | 显示全部楼层
    本帖最后由 zhp 于 2024-4-7 17:40 编辑
    newlined 发表于 2024-4-7 09:14
    @ZHP,程序我修改了,比以前好多了,非常感谢,但还是运行不正常。读写EEPROM,只在主程序及主程序调用的子 ...

    如果你主循环和中断程序都需要同时访问EEPROM
    则除了保护ACC、PDW外,IAP相关寄存器都需要保护

    更好的方法是:IAP的读、写、擦除均修改为先关闭中断,再进行IAP操作
    比如:IAP的读代码可作如下修改
    1. read:
    2.     PUSH    PSW
    3.     MOV     C, EA
    4.     MOV     F0, C                   ;保存EA
    5.     CLR     EA                      ; 禁止中断
    6.     NOP
    7.     NOP
    8.     MOV     IAP_ADDRE, #0           ; 送地址高字节(地址需要改变时才需重新送地址)
    9.     MOV     IAP_ADDRH, DPH          ; 送地址中字节(地址需要改变时才需重新送地址)
    10.     MOV     IAP_ADDRL, DPL          ; 送地址低字节(地址需要改变时才需重新送地址)
    11.     MOV     IAP_CONTR, #IAP_EN      ; 允许ISP/IAP操作,送一次就够
    12.     MOV     IAP_TPS, #TPS_WAIT      ; 设置等待时间,
    13.     MOV     IAP_CMD, #1             ; ISP读出命令送字节读命令,命令不需改变时,不需重新送命令
    14.     MOV     IAP_TRIG, #0x5A         ;ISP触发命令
    15.     MOV     IAP_TRIG, #0xA5
    16.     NOP     
    17.     NOP
    18.     NOP
    19.     NOP
    20.     MOV     A, IAP_DATA
    21.     LCALL   IAP_DISABLE
    22.     MOV     C, F0
    23.     MOV     EA, C                   ; 允许中断(如果允许)
    24.     POP     PSW
    25.     RET
    复制代码
    擦除和写的代码类似修改


    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    20

    主题

    104

    回帖

    230

    积分

    中级会员

    积分
    230
     楼主| 发表于 2024-4-8 09:43:27 | 显示全部楼层
    zhp 发表于 2024-4-7 17:39
    如果你主循环和中断程序都需要同时访问EEPROM
    则除了保护ACC、PDW外,IAP相关寄存器都需要保护

    版主您好,我按照您的意见修改了程序,还是不行,我估计现在读写EEPROM是没有问题了,
    可能是别的地方出了问题,这个程序是多年前别人从另一种单片机移植过来的,一些问题当时
    没有显现出来,比如一些地址的定义?

    我猜测的,我再仔细检查下,有情况再过来请教,谢谢您的回复。
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-17 21:52 , Processed in 0.070362 second(s), 57 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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