51单片机如何实现“复位”

51单片机如何实现“复位”,第1张

首先需要明确,程序重头开始执行是指某一段程序(或者一个函数)重新开始执行,还是你所谓的“复位”让单片机重启?如果不是特殊需求,建议不要让单片机复位以使程序重新运行。

从你描述看,你所执行的程序肯定是长时间占有CPU导致不能实时监测红外信号,很明显不能用查询方式,改用中断即可,至于中断后如何停止原来运行的程序再重新开始运行就是你的事了。

那么我需求就是要检测到红外信号后“复位”单片机怎么办呢?直接将红外信号接到复位引脚上(假设你单片机是高电平复位),若是低电平复位,则取反。不过要注意:1、复位信号要持续一定时间才能复位;2、自然界中红外干扰很多,很有可能你单片机运行着运行着就复位了~~3、若红外接收器还肩负其他如信号传输任务,很明显这样不行!

不是这样的,单片机的中断分为内部中断和外部中断。外部中断就是当INT0或者是INT1端口满足条件即中断来了,不管此时程序在执行什么(除非此时的单片机正在运行其他中断指令),就会跳转到中断服务程序(就相当于是一个特殊的函数),执行完之后自动的返回。而内部中断就是利用定时器进行中断,设定一定的时间,时间到了cpu就转到内部中断程序(也是一个特殊的函数),执行完之后自动的返回,大概就是这样子……

你的目的是想进行复位是吗?如果是的话使用两个库函数即可:

__set_FAULTMASK(1);

NVIC_SystemReset();

我的STM32是F103系列,即CPU内核为Cortex M3,这两个函数在core_cm3h里面都有定义,

__set_FAULTMASK(1);是关闭所有中断的意思,目的是在执行NVIC_SystemReset();复位函数过程中不被中断所打断。

两个函数执行后系统复位重新执行代码,包括之前所配置好的外设寄存器也都回到复位状态。

如果你想要保持之前配置好的寄存器不变的话,那么你再程序跳转之前要先初始化堆栈,而且你程序跳转的地址不对,应该这样:

__set_MSP((__IO uint32_t) 0x08000000); 要先初始化堆栈指针

((void () (void)) ((vu32 )0x08000004) (); 这句才是程序跳转,注意了,是((vu32 )0x08000004

单片机有个中断入口地址,产生中断后CPU自动从中断向量取得入口地址,然后从这个地址执行程序 。如果你用汇编写代码,你会发现main函数其实也是一个中断函数,是个复位中断,和其它中断不同处是main没有返回。要执行中断里面的代码必须让程序指针指到中断里的代码,一是通过触发中断,二是手动改变PC指针(汇编直接用jmp指令跳转C由于编译器的限制比较难实现,可以嵌入汇编实现)

(void)interrupt n(using m)函数是个中断函数,当这个中断产生后,CPU就会通过中断向量找到这个函数的地址(中断入口),然后执行此函数,结束后返回主函数

你主函数中除了初始化的语句外,其它的处理部分都放在WHILE(1)的循环中啊,然后 外部中断中设置一个标志位,举例说明,比如。下面例子,是外中断一次,P0取反一次,你如果还想有其它数据处理,可以把语句写在WHILE(1)中。中断执行后,判断FLAG,然后会自动回到主函数中。

void main(void)

{

flag=0;

EA=1; //开放总中断

EX0=1; //允许使用外中断

IT0=1; //负跳变来触发外中断

P0=0xff;

while(1)

{

if(flag)

{

可以在此添加语句。

}

可以在此添加语句。 }

}

void it0(void) interrupt 0 using 0

{

P0=~P0; //每产生一次中断请求,P0取反一次。

flag=1;

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12183349.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存