li2587 发表于 2007-12-3 23:51:42

马老师,请问一下,Flash 页缓冲区 是我自己定义的一个SRAM 区,还是MCU 内部自己虚拟的啊

马老师,请问一下,Flash 页缓冲区 是我自己定义的一个SRAM 区,还是MCU 内部自己虚拟的啊?
以下是M88 上的范例BOOT LOADER 程序, 其中这段对 Flash 页缓冲区 的描述不了解,望指点迷津!
;-------此段已经通过调用do_spm 把数据写到flash
;-------如何此段还要调用do_spm 执行页写,我看2段程序就是赋值给spmcrval 不同,但无法理解上面的那段程序的意思
;-------还是我理解Flash 页缓冲区 是我自己定义的一个SRAM 区 的看法是错误的?

;***********************************************
;
;        简单的Boot Loader 汇编代码例子
;- 本例程将RAM 中的一页数据写入Flash
;Y 指针指向RAM 的第一个数据单元
;Z 指针指向Flash 的第一个数据单元
;- 本例程没有包括错误处理
;- 该程序必须放置于Boot 区( 至少Do_spm 子程序是如此)
; 在自编程过程中( 页擦除和页写操作) 只能读访问NRWW 区的代码
;- 使用的寄存器:r0,r1,a(r16),b(r17),looplo(r24),loophi(r25),spmcrval(r20)
; 在程序中不包括寄存器内容的保护和恢复
; 在牺牲代码大小的情况下可以优化寄存器的使用
;- 假设中断向量表位于Boot loader 区, 或者中断被禁止。
;
;***********************************************
.equ pagesizeb = pagesize*2                         ;PAGESIZEB 是以字节为单位的页大小,不是以字为单位
.org         smallbootstart
write_page:
        ldi         spmcrval,low((1<<pgers)|(1<<spmen))        ;页擦除
        call         do_spm

        ldi         spmcrval,low((1<<rwwsre)|(1<<spmen))        ;重新使能RWW 区
        call         do_spm

;-------此段已经通过调用do_spm 把数据写到flash
        ldi         looplo,low(pagesizeb)                 ;将数据从RAM 转移到Flash 页缓冲区,初始化循环变量
        ldi         loophi,high(pagesizeb)                 ;PAGESIZEB<=256 时不需要此操作
wrloop:
        ld         r0,y+
        ld         r1,y+
        ldi         spmcrval,low(1<<spmen)
        call         do_spm
        adiw         zh:zl,low(2)
        sbiw         loophi:looplo,low(2)                 ;PAGESIZEB<=256 时请使用subi
        brne         wrloop

;-------如何此段还要调用do_spm 执行页写,我看2段程序就是赋值给spmcrval 不同,但无法理解上面的那段程序的意思
;-------还是我理解Flash 页缓冲区 是我自己定义的一个SRAM 区 的看法是错误的?
        subi         zl,low(pagesizeb)                 ;执行页写,复位指针
        sbci         zh,high(pagesizeb)                 ;PAGESIZEB<=256 时不需要此操作
        ldi         spmcrval,low((1<<pgwrt)|(1<<spmen))
        call         do_spm

        ldi         spmcrval,low((1<<rwwsre)|(1<<spmen))        ;重新使能RWW 区
        call         do_spm

        ldi         looplo,low(pagesizeb)                 ;读回数据并检查,为可选操作,初始化循环变量
        ldi         loophi,high(pagesizeb)                 ;PAGESIZEB<=256 时不需要此操作
        subi         yl,low(pagesizeb)                 ;复位指针
        sbci         yh,high(pagesizeb)
rdloop:
        lpm         r0,z+
        ld         r1,y+
        cpse         r0,r1
        jmp         error
        sbiw         loophi:looplo,low(1)                 ;PAGESIZEB<=256 时请使用subi
        brne         rdloop

return:
        in         a,spmcsr                        ;返回到RWW 区,确保RWW 区已经可以安全读取
        sbrs         a,rwwsb                         ;若RWWSB 为"1",说明RWW 区还没有准备好
        ret
        ldi         spmcrval,low((1<<rwwsre)|(1<<spmen))        ;重新使能RWW 区
        call         do_spm
        rjmp         return

do_spm:
wait_spm:
        in         a,spmcsr                        ;检查先前的SPM 操作是否已经完成
        sbrc         a,spmen
        rjmp         wait_spm
        in         b,sreg                                ;输入:spmcrval 决定了SPM 操作
        cli                                        ;禁止中断,保存状态标志
wait_ee:
        sbic         eecr,eepe                        ;确保没有EEPROM 写操作
        rjmp         wait_ee
        out         spmcsr,spmcrval                        ;SPM 时间序列
        spm
        out         sreg,b                                ;恢复SREG ( 如果中断原本是使能的,则使能中断)
        ret

jacky2602000 发表于 2007-12-4 15:41:24

期待答案!!!

machao 发表于 2007-12-4 20:14:33

Flash的页缓冲区,不是定义在SRAM中由用户直接操作的.它是AVR内部的,配合读写FLASH的缓冲区.

类似的EEPROM,FLASH存储器通常采用页写方式.如果一页有32个字节,那么在器件内部会有一个32位的页缓冲区.用户写入存储器的数据实际上是写在了该页缓冲区中,然后在由器件内部的电路工作,将页缓冲区中数据写入到EEPROM或FLASH存储器中.这也就是为什么EEPROM(24Cxx)不能跨页写操作的原因.

请多看看这些器件的手册,这就是积累.明白了一般的EEPROM,FLASH的操作,也就能明白AVR内部FLASH的操作了.

有些器件,如AT45DBxxx,内部有2组页缓冲区,这样可以提高芯片处理过程的效率.

li2587 发表于 2007-12-5 10:00:10

谢谢马老师,已经理解了,也是猜成这个意思才确认的,只是觉得DATA SHEET 中直接说一个 Flash 页缓冲区 名词,一点解释都没有,它认为这是常识,而24C01 什么的有结构图及解释, 所以一时迷惑了。

=====================================================
对于要学习使用AVR的人,24C01就是基础了。

那个MCU的器件手册中,还介绍基础?

tong7127 发表于 2009-8-18 12:40:42

楼主,能不能把上面那段代码翻译成c语言,贴上来啊 。我数据存储器也不够用,需要通过FLASH来完成操作,但我AVR的汇编不怎么明白,能不能翻译成c语言啊

wodetianmyday 发表于 2009-10-22 17:34:17

请问,怎样在EPGA64写FLASH?有没有具体实例或代码?谢谢
页: [1]
查看完整版本: 马老师,请问一下,Flash 页缓冲区 是我自己定义的一个SRAM 区,还是MCU 内部自己虚拟的啊