首先需要明确,程序重头开始执行是指某一段程序(或者一个函数)重新开始执行,还是你所谓的“复位”让单片机重启?如果不是特殊需求,建议不要让单片机复位以使程序重新运行。
从你描述看,你所执行的程序肯定是长时间占有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;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)