C 没有while(1)为什么MPLAB中的代码持续运行

C 没有while(1)为什么MPLAB中的代码持续运行,c,pic,microchip,mplab-5.45,C,Pic,Microchip,Mplab 5.45,在这段代码中,我没有使用while1,只有当它进入“if”条件时,它才会调用TIMER_ISR函数,该函数每250毫秒初始化一次。但当它进入else状态时,并没有任何定时器功能或任何东西,但也说明了它为什么会连续运行 #include <stdint.h> #include <stdlib.h> #include <string.h> #include "mcc_generated_files/mcc.h" #include "m

在这段代码中,我没有使用while1,只有当它进入“if”条件时,它才会调用TIMER_ISR函数,该函数每250毫秒初始化一次。但当它进入else状态时,并没有任何定时器功能或任何东西,但也说明了它为什么会连续运行

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/eusart1.h"
void main(void)
{
    SYSTEM_Initialize();    
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    char temp1[] = "ok";
    char temp2[3] = { '\0', '\0', '\0' };
    char temp3[3], temp4[3];
    int i, j;
    for (i = 0; temp1[i] != '\0'; i++)
    {
        temp3[i] = temp1[i] - 32;
        EUSART1_Write(temp3[i]);
    }
    EUSART1_String("\r\n");
    for (i = 0; i < 2; i++)
    {
        temp2[i] = EUSART1_Read();
        EUSART1_Write(temp2[i]);
    }

    EUSART1_String("\r\n");
    if (strcmp(temp1, temp2) == 0)
    {
        for (i = 0; temp1[i] != '\0'; i++)
        {
            if (temp1[i] >= 'a' && temp1[i] <= 'z')
            {
                temp1[i] = temp1[i] - 32;
            }
        }

        for (j = 0; temp1[j]; j++)
            EUSART1_Write(temp1[j]);
        //Timer initialization (timer is initialized for every 250mS)
        TMR0_Initialize();
    }
    else
        EUSART1_String("\r\nERROR GIVE'ok'");
}

如果问题是:在裸机MCU应用程序上从main返回,然后从TL返回,这有意义吗;医生:不,这没有意义,因为没有人可以回去。没有操作系统握着你的手-你的应用程序就是一切

详细说明:

所有现代MCU都有一个入口点,称为复位中断。当您通电时,或者看门狗电路重置MCU后,或者因为MCU重置引脚上有外部/重置信号,您可以结束

然后,程序计数器通过进入上电复位中断服务程序(有时称为复位向量)来启动程序。从这里开始,MCU上最基本的东西都设置好了,然后它通常会调用C运行时CRT,这是编译器特定的启动代码,用于初始化所有内存区域以启用标准C环境,例如初始化变量等。当CRT完成所有这些操作时,它会调用main

或者,如果您在汇编程序中编写了所有内容,您不必为CRT操心,但可以从重置ISR调用任何您喜欢的函数。这通常是通过直接跳转而不是函数调用来完成的,不需要堆叠任何参数,因为您不希望返回。你只会不必要地浪费堆放空间

这就是为什么嵌入式系统中最常见的main形式是void main void,而不是严格符合C的int main void——后者可能由于调用约定而不必要地浪费堆栈上的空间。在gcc编译器上,始终使用-ffreestanding选择嵌入式独立系统作为目标

现在,如果你用C语言编写程序,然后从main返回,你最多会崩溃回到CRT代码中,如果你幸运的话,有人为你写了一个;;{}在那里循环以捕获程序计数器。这在新手友好型环境中很常见。或者,您可以一路崩溃,返回到上电重置ISR

或者更可能的情况是,如果main是以上述方式从CRT或自定义代码调用的,那么由于没有保存返回地址,您直接跳入未知


从那里开始,程序计数器将在随机内存位置中运行,开始执行它在内存中遇到的任何内容,将这些单元格的内容解释为操作码,不管它们是不是操作码——你会得到失控代码,这是一种严重而危险的错误情况。它会一直这样做,直到它偶然发现导致硬件异常的东西,比如访问受保护的内存,或者直到看门狗重置所有东西,以防看门狗被启用。

请使用工具一致地缩进代码,如您是否询问在裸机MCU应用程序中从main返回是否有意义?不,它不是,你回到谁或什么?在嵌入式系统中,你总是应该使用一个无休止的循环。返回没有意义。一旦它进入else状态,它必须退出main know?,但在此情况下,它再次进入main。您的微控制器是否有看门狗定时器?