打印
[AVR单片机]

各位大仙儿,暂停斗嘴,帮忙解决问题先

[复制链接]
4337|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
宇宙飞船| | 2010-8-11 22:01 | 只看该作者
把复位地址压入stack ,再执行返回指令。
ldi   temp,00
push   temp
push   temp
ret

使用特权

评论回复
板凳
原野之狼| | 2010-8-11 22:07 | 只看该作者
这样子复位要注意各寄存器的默认值问题

使用特权

评论回复
地板
highgear| | 2010-8-11 22:16 | 只看该作者
宇宙飞船, 不用那么复杂。
jmp 0 就可以了

使用特权

评论回复
5
ZALIN| | 2010-8-11 22:30 | 只看该作者
除了要注意各寄存器的默认值问题外,或许禁止中断也是必要的

有可能的话,最好是使用WDT复位

使用特权

评论回复
6
此心向学|  楼主 | 2010-8-11 22:32 | 只看该作者
本帖最后由 此心向学 于 2010-8-11 22:33 编辑

谢谢LS各位帮忙;
请问用C怎么写?
void (*reset)(void)=0x00000000;
假入我现在想把reset();放在从0x00000400处开始的位置???

编译环境是GCC

使用特权

评论回复
7
xuyiyi| | 2010-8-12 10:48 | 只看该作者
void reset (void)
{
    ((void (*) (void)) 0x0400) ();
}

int main(void)
{
   reset();
}

使用特权

评论回复
8
xuyiyi| | 2010-8-12 10:49 | 只看该作者
以上程序在WINGCC编译环境下编译通过。

使用特权

评论回复
9
mxh0506| | 2010-8-12 12:37 | 只看该作者
我是这样实现的(IAR):
#define                StartApp()                asm ("jmp 0")

使用特权

评论回复
10
hgjinwei| | 2010-8-12 20:20 | 只看该作者
难道AVR没有软复位指令?

使用特权

评论回复
11
此心向学|  楼主 | 2010-8-12 21:31 | 只看该作者
我的表述没有让大侠看明白,我再说具体点
我的意思是,reset();这段代码从0x00000400地址开始存放,而不是运行reset跳到0x00000400。。。
你的代码debug后:
+00000400:   FFFF        ???                      Data or unknown opcode
+00000401:   FFFF        ???                      Data or unknown opcode
+00000402:   FFFF        ???                      Data or unknown opcode
+00000403:   FFFF        ???                      Data or unknown opcode
+00000404:   FFFF        ???                      Data or unknown opcode
+00000405:   FFFF        ???                      Data or unknown opcode
+00000406:   FFFF        ???                      Data or unknown opcode

没有达到效果;
我想要的是这样的:

+00000400:   940C0000    JMP     0x00000000       Jump

……
+00000500:   940C0000    JMP     0x00000000       Jump
在未用地址填充这些指令,


7# xuyiyi

使用特权

评论回复
12
Xuxx416| | 2010-8-12 21:31 | 只看该作者
太讨厌了,新手先赚点点数先

使用特权

评论回复
13
此心向学|  楼主 | 2010-8-12 21:32 | 只看该作者
我想问的是如何将StartApp()放在0x00000400地址或者说放在任何指定的未用地址上 9# mxh0506

使用特权

评论回复
14
潜艇8421| | 2010-8-12 22:28 | 只看该作者
试试以下这种方法,
把复位函数写成单独的C文件,然后编译成以obj,再用连接定位器,定位在指定的物理地址。

使用特权

评论回复
15
dqyubsh| | 2010-8-13 08:48 | 只看该作者
同意5楼,最好用硬复位。

ATMEL网站上有个关于复位的手册,可以去学学。

使用特权

评论回复
16
123jj| | 2010-8-13 09:04 | 只看该作者
本帖最后由 123jj 于 2010-8-13 09:05 编辑
我想问的是如何将StartApp()放在0x00000400地址或者说放在任何指定的未用地址上 9# mxh0506
此心向学 发表于 2010-8-12 21:32


把函数StartApp()写成单独的C文件,然后编译时在下列菜单里,用连接器重定位,定位指向你希望的物理地址0x00000400。


使用特权

评论回复
17
此心向学|  楼主 | 2010-8-13 09:58 | 只看该作者
本帖最后由 此心向学 于 2010-8-13 10:02 编辑

这样设置对嘛????

debug结果:reset.c
int main(void)
{
while(1);
}
reset0.c
void (*reset)(void)=0x00000000;

还是不行


16# 123jj

使用特权

评论回复
18
xuyiyi| | 2010-8-13 11:19 | 只看该作者
请重点看一下,芯艺 的《AVR单片机GCC程序设计》,第
  2.6 avr-gcc 段(section)与再定位(relocation)  中描绘和实例。


《AVR单片机GCC程序设计》-芯艺.pdf (1.47 MB)

使用特权

评论回复
19
此心向学|  楼主 | 2010-8-13 13:35 | 只看该作者
谢谢大侠的资料
看了,比较愚钝,没弄明白
void reset(void) __attribute__ ((naked)) __attribute__ ((section ("0x0400")));
void reset(void)
{
     asm("JMP 0x0000");
}


int main(void)
{
while(1);
}

这样写,debug看,0x0400地址还是什么都没有。

.ORG $0400
……
这样用汇编写,查看0x0400地址就有代码

请大侠明示。。。

18# xuyiyi

使用特权

评论回复
20
123jj| | 2010-8-13 14:30 | 只看该作者
示范程序:

#include <avr/io.h>

void StartApp(void) __attribute__ ((section (".mysection")));
void StartApp(void)
{
DDRA=0xff;
PORTA=0x55;
}

int main(void)
{
  unsigned char i;
  for(i=0;i<0x100;i++)
    {
      StartApp();
    }
  while(1);
}

使用特权

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

本版积分规则

0

主题

70

帖子

1

粉丝