搜索
bottom↓
回复: 1

avr 引导程序

[复制链接]

出0入0汤圆

发表于 2007-12-29 14:53:22 | 显示全部楼层 |阅读模式
您好马潮老师! 我想用avr 的单片机做个仿真机,可是书上有一些引导程序的资料,但是还是没有搞明白,用汇编的程序老是编译不过。
希望马老师给点帮助意见。这是我的程序:我的QQ54709686,E-mail; mingtao8868@163.com
;- 本例程将RAM 中的一页数据写入Flash
; Y 指针指向RAM 的第一个数据单元
;Z 指针指向Flash 的第一个数据单元
;- 本例程没有包括错误处理
;- 该程序必须放置于Boot 区( 至少Do_spm 子程序是如此)
; 在自编程过程中( 页擦除和页写操作) 只能读访问NRWW 区的代码
;- 使用的寄存器:r0、 r1、 temp1 (r16)、 temp2 (r17)、 looplo (r24)、
; loophi (r25)、 spmcrval (r20)
; 在程序中不包括寄存器内容的保护和恢复
; 在牺牲代码大小的情况下可以优化寄存器的使用
;- 假设中断向量表位于Boot loader 区, 或者中断被禁止。
.include "m16def.inc" ;引用器件I/O配置文件

;定义程序中使用的变量名(在寄存器空间)
.def spmcrval = r20 ;2ms到标志
.def temp2 = r17 ;临时变量
.def temp1 = r16 ;临时变量
.def looplo = r24 ;临时变量(中断中使用)
.def loophi = r25 ;临时变量(中断中使用)
.equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB 是以字节为单位的页大小,不是以字为单位
.org         $1E00
Write_page:
; 页擦除
        ldi spmcrval, (1<<PGERS) | (1<<SPMEN)
        call Do_spm
; 重新使能RWW 区
        ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
        call Do_spm
; 将数据从RAM 转移到Flash 页缓冲区
        ldi looplo, low(PAGESIZEB) ; 初始化循环变量
        ldi loophi, high(PAGESIZEB) ;PAGESIZEB<=256 时不需要此操作
Wrloop:
        ld r0, Y+
        ld r1, Y+
        ldi spmcrval, (1<<SPMEN)
        call Do_spm

        adiw ZH:ZL, 2
        sbiw loophi:looplo, 2   ;PAGESIZEB<=256 时请使用subi
        brne Wrloop
; execute page write
        subi ZL, low(PAGESIZEB) ; 复位指针
        sbci ZH, high(PAGESIZEB) ;PAGESIZEB<=256 时不需要此操作
        ldi spmcrval, (1<<PGWRT) | (1<<SPMEN)
        call Do_spm
; 重新使能RWW 区
        ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
        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, 1 ;PAGESIZEB<=256 时请使用subi
        brne Rdloop
; 返回到RWW 区
; 确保RWW 区已经可以安全读取
Return:
        in temp1, SPMCR
        sbrs temp1, RWWSB ; 若RWWSB 为"1",说明RWW 区还没有准备好
        ret

; 重新使能RWW 区
        ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
        call Do_spm
        rjmp Return
Do_spm:
; 检查先前的SPM 操作是否已经完成
Wait_spm:
        in temp1, SPMCR
        sbrc temp1, SPMEN
        rjmp Wait_spm
; 输入:spmcrval 决定了SPM 操作
; 禁止中断,保存状态标志
        in temp2, SREG
        cli
; 确保没有EEPROM 写操作
Wait_ee:
        sbic EECR, EEWE
        rjmp Wait_ee
; SPM 时间序列
        out SPMCR, spmcrval
        spm
; 恢复SREG ( 如果中断原本是使能的,则使能中断)
        out SREG, temp2
        ret

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2007-12-29 17:38:13 | 显示全部楼层
关于这些内容,在我编写的<M128>一书中第五章中有实例介绍.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-22 17:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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