马老师,请问一下,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 期待答案!!! Flash的页缓冲区,不是定义在SRAM中由用户直接操作的.它是AVR内部的,配合读写FLASH的缓冲区.
类似的EEPROM,FLASH存储器通常采用页写方式.如果一页有32个字节,那么在器件内部会有一个32位的页缓冲区.用户写入存储器的数据实际上是写在了该页缓冲区中,然后在由器件内部的电路工作,将页缓冲区中数据写入到EEPROM或FLASH存储器中.这也就是为什么EEPROM(24Cxx)不能跨页写操作的原因.
请多看看这些器件的手册,这就是积累.明白了一般的EEPROM,FLASH的操作,也就能明白AVR内部FLASH的操作了.
有些器件,如AT45DBxxx,内部有2组页缓冲区,这样可以提高芯片处理过程的效率. 谢谢马老师,已经理解了,也是猜成这个意思才确认的,只是觉得DATA SHEET 中直接说一个 Flash 页缓冲区 名词,一点解释都没有,它认为这是常识,而24C01 什么的有结构图及解释, 所以一时迷惑了。
=====================================================
对于要学习使用AVR的人,24C01就是基础了。
那个MCU的器件手册中,还介绍基础? 楼主,能不能把上面那段代码翻译成c语言,贴上来啊 。我数据存储器也不够用,需要通过FLASH来完成操作,但我AVR的汇编不怎么明白,能不能翻译成c语言啊 请问,怎样在EPGA64写FLASH?有没有具体实例或代码?谢谢
页:
[1]