打印

AVR单片机通用寄存器的配置问题

[复制链接]
3311|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
renhuan333|  楼主 | 2011-5-25 09:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1. AVR汇编定义通用寄存器为临时变量的时候,为什么只能定义r16以后的寄存器(包括r16),改成r16之前就出错。提示:invalid register
2.汇编中必须得定义地址指针寄存器进行初始化定义,如我没定义用如下指令:
...
ldi r16,5
....

delay:  //调用延迟函数
push r16
del1: dec r16
brne  del1
pop  r16
ret
当运行到pop r16的时候,我看到出栈后r16值为:0x20,请问这个数据时怎么来的.主要想知道为什么出现的错误时这个数值,而不是报错!希望高手帮忙解答一下,谢谢!

相关帖子

沙发
NE5532| | 2011-5-25 17:15 | 只看该作者
1.你用的纯汇编还是C和汇编混合编程?
2.求完整程序,实在看不懂。

使用特权

评论回复
板凳
renhuan333|  楼主 | 2011-5-25 19:38 | 只看该作者
用的是纯汇编,新手学习现在是依葫芦画瓢,就是想把各个环节给弄明白了。
第一个问题我查出来了,因为程序里用到了ser这个置位寄存器指令,而它能置位的区间只能是r16 ~r31,所以如果定义r16之前的寄存器,后边再使用ser这个指令就会提示错误(有些指令只能用在r16 ~r31,自己没注意)。
第二个问题现在只找到出来部分原因,就是AVR的压栈是从SAM的最高位(0x045F)开始从上往下的,如果不配置SP指针寄存器默认是从0xFFFF开始的。
我的程序是:(新手学的秒闪烁器,从AVR单片机嵌入式系统原理与应用第一个程序照搬过来的,调试的时候加了些自己的想法)
.include"m16def.inc"
.def temp1=r17// 定义通用寄存器r20用符号名(变量名)temp1来代替

.org $0000//代码段起始地址
        jmp reset//系统上电复位,跳转到主程序
             //中断向量区
.org $002A//代码段定位,同时跳过中断向量区,中断向量区:$0000~$0028,21个中断向量,每个中断向量占2个字

reset:
ldi r16,high(RAMEND)//取RAMEND的高位字节,LDI指令只能让一个8位立即数传送到数据寄存器R16~R31中
out sph,r16         //将RAMEND的高位字节送堆栈寄存器SP的高位字节中
ldi r16,low(RAMEND) //取RAMEND的高位字节
out spl,r16         //将RAMEND的高位字节送堆栈寄存器SP的高位字节中
ser temp1           //将temper1(r20)置0xff
out ddrc,temp1      //把temper1的值送ddrc(c口的方向控制寄存器)即设定为输出模式
out portc,temp1     //PC口全部输出为1,
ldi r16,5          //设置延迟参数

loop:
cbi portc,0
rcall delay
sbi  portc,0
rcall delay
rjmp loop

delay: push r16
del1:  push r16
del2:  dec r16
       brne del2
           pop  r16
           dec  r16
           brne del1
           pop  r16
           ret
问题就是,如果不配置SP指针寄存器,当运行到倒数第二行pop r16的时候,我看到出栈后r16值为:0x20,这个值不知道是怎么出现的,求解!

使用特权

评论回复
地板
renhuan333|  楼主 | 2011-5-25 19:39 | 只看该作者
还有想买一个单片机学习开发板,也请高手推荐,谢谢!

使用特权

评论回复
5
xiaotann| | 2011-5-26 10:09 | 只看该作者
用如下指令

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

37

帖子

1

粉丝