Embedded 如何在C中重置PIC18?

Embedded 如何在C中重置PIC18?,embedded,pic,microchip,Embedded,Pic,Microchip,使用HiTech PIC18 C编译器的C代码重置PIC18的最佳方法是什么 编辑: 我现在正在使用 void reset() { #asm reset #endasm } 但是必须有更好的方法,除非编译器供应商的运行库定义了一个库函数(如果微控制器世界中甚至存在这样的库……但它应该存在),否则no.C本身肯定不会帮你,做“重置”对于C来说,这是一个太多的平台特定问题了。我使用ccsinfo.com编译器,它有一个类似的API调用来重置PIC,但我认为编译器的解决方案会做正确的事情 有一

使用HiTech PIC18 C编译器的C代码重置PIC18的最佳方法是什么

编辑:

我现在正在使用

void reset()
{
#asm 
  reset
#endasm
}

但是必须有更好的方法,除非编译器供应商的运行库定义了一个库函数(如果微控制器世界中甚至存在这样的库……但它应该存在),否则no.C本身肯定不会帮你,做“重置”对于C来说,这是一个太多的平台特定问题了。我使用ccsinfo.com编译器,它有一个类似的API调用来重置PIC,但我认为编译器的解决方案会做正确的事情

有一个

问:如何重置micro

一种方法是将所有变量重置为 它们的默认值,如PIC中所列 手册然后,使用汇编语言 跳转到中的位置0x0000 微型

#asm ljmp 0x0000

#收尾

这是相当安全的使用,即使在 在中断或 程序。PIC16X系列微型计算机 有8个堆栈级别。每一次 调用一个堆栈级别的过程 用于返回地址。信息技术 是一个循环缓冲区,因此即使 micro是7个程序级别,深度和 当重置被触发时,在中断中 这是新世纪的开始 堆栈缓冲区,微将 按正常程序继续

另一种方法是设置看门狗 芯片编程时的定时器,以及 始终使用CLRWDT()指令 密码。当你想让micro 复位,停止清除看门狗位 大约一周后,micro将复位 18毫秒到2秒,具体取决于 预分频器


编译器通常内置了自己的reset()函数,但它的功能与您的函数完全相同,并且实际名称可能因编译器而异


你已经在用最好的方法做了。

你的答案是我所知道的最好的方法。关键是在函数调用中包含汇编指令,这一切都是由它自己完成的。 编译器不会优化包含内联程序集的函数,因此,如果将重置指令内联到非常大的函数中,编译器将不会优化该函数中的任何代码。通过在其自身的函数中设置Reset,可以避免这种情况。这个函数中的代码不会被优化,但谁在乎呢,因为它是一个如此小的函数。

正如11年前编辑的这个原始问题一样,原始海报需要一个全面的答案似乎是可疑的。事实上,OP在过去9年中似乎只询问或回答了两个有关微控制器的主题

考虑到所有这些,看看PIC18F控制器从复位向量开始执行的一些方法可能会有所帮助,因为它不是由微芯片调用的,使用高科技C或XC8编译的代码

该代码已使用MPLABX v5.25、XC8 v2.05和PIC18F45K20控制器进行了测试

/*
 * File:     main.c
 * Author:   dan1138
 * Target:   PIC18F45K20
 * Compiler: XC8 v2.05
 *
 *                                                             PIC18F46K20
 *                 +---------+                 +---------+                 +----------+                 +----------+
 *           <>  1 : RC7/RX  :           -- 12 : NC      :           <> 23 : RA4      :           -- 34 : NC       :
 *      LED4 <>  2 : RD4     :           -- 13 : NC      :           <> 24 : RA5      : 32.768KHz -> 35 : RC1/SOSI :
 *      LED5 <>  3 : RD5     :           <> 14 : RB4     :           <> 25 : RE0      :           <> 36 : RC2      :
 *      LED6 <>  4 : RD6     :           <> 15 : RB5/PGM :           <> 26 : RE1      :           <> 37 : RC3      :
 *       GND ->  5 : VSS     :       PGC <> 16 : RB6/PGC :           <> 27 : RE2      :      LED0 <> 38 : RD0      :
 *       3v3 ->  6 : VDD     :       PGD <> 17 : RB7/PGD :       3v3 -> 28 : VDD      :      LED1 <> 39 : RD1      :
 *       SW1 <>  7 : RB0/INT :       VPP -> 18 : RE3/VPP :       GND -> 29 : VSS      :      LED2 <> 40 : RD2      :
 *           <>  8 : RB1     :       POT <> 19 : RA0/AN0 :      4MHz -> 30 : RA7/OSC1 :      LED3 <> 41 : RD3      :
 *           <>  9 : RB2     :           <> 20 : RA1     :      4MHz <- 31 : RA6/OSC2 :           <> 42 : RC4      :
 *           <> 10 : RB3     :           <> 21 : RA2     : 32.767KHz <- 32 : RC0/SOSO :           <> 43 : RC5      :
 *      LED7 <> 11 : RD7     :           <> 22 : RA3     :           -- 33 : NC       :           <> 44 : RC6/TX   :
 *                 +---------+                 +---------+                 +----------+                 +----------+
 *                                                              TQFP-44
 *
 *
 * Created on December 21, 2019, 2:26 PM
 */

/* Target specific configuration words */
#pragma config FOSC = INTIO67, FCMEN = OFF
#pragma config IESO = OFF, PWRT = OFF, BOREN = SBORDIS, BORV = 18
#pragma config WDTEN = OFF, WDTPS = 32768, CCP2MX = PORTC, PBADEN = OFF
#pragma config LPT1OSC = ON, HFOFST = ON
#pragma config MCLRE = ON, STVREN = ON, LVP = OFF, XINST = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF
#pragma config CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config WRTC = OFF, WRTB = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
#pragma config EBTRB = OFF

/* Target specific definitions for special function registers */
#include <xc.h>

/* Declare the system oscillator frequency setup by the code */
#define _XTAL_FREQ (4000000UL)

/* reset instruction */
void ResetMethod_1(void)
{
    asm(" reset");
}

/* long jump to absolute address zero */
void ResetMethod_2(void)
{
    INTCON = 0;
    asm(" pop\n ljmp 0");
}

/* return to absolute address zero */
void ResetMethod_3(void)
{
    INTCON = 0;
    asm(" clrf TOSU\n clrf TOSH\n clrf TOSL\n");
}

/* provoke stackoverflow reset */
void ResetMethod_4(void)
{
    INTCON = 0;
    while (1) 
    {
        asm(" push\n");
    }
}

/* provoke stackunderflow reset */
void ResetMethod_5(void)
{
    INTCON = 0;
    STKPTR = 0;
}

/* clear the program counter */
void ResetMethod_6(void)
{
    INTCON = 0;
    asm(" clrf PCLATU\n clrf PCLATH\n clrf PCL\n");
}

void main(void)
{
    INTCON = 0;             /* Disable all interrupt sources */
    PIE1 = 0;
    PIE2 = 0;
    INTCON3bits.INT1IE = 0;
    INTCON3bits.INT2IE = 0;

    OSCCON = 0x50;          /* set internal oscillator to 4MHz */
    OSCTUNEbits.TUN = 0;    /* use factory calibration of internal oscillator */
    ANSEL = 0;
    ANSELH = 0;

    if(!RCONbits.nPOR)
    {
        RCONbits.nPOR = 1;
        LATD = 0;
    }

    TRISD = 0;
    /*
     * Application loop
     */
    while(1)
    {
        __delay_ms(500);
        if (LATDbits.LD0 == 0)
        {
            LATDbits.LD0 = 1;
            ResetMethod_1();
        }

        if (LATDbits.LD1 == 0)
        {
            LATDbits.LD1 = 1;
            ResetMethod_2();
        }

        if (LATDbits.LD2 == 0)
        {
            LATDbits.LD2 = 1;
            ResetMethod_3();
        }

        if (LATDbits.LD3 == 0)
        {
            LATDbits.LD3 = 1;
            ResetMethod_4();
        }

        if (LATDbits.LD4 == 0)
        {
            LATDbits.LD4 = 1;
            ResetMethod_5();
        }

        if (LATDbits.LD5 == 0)
        {
            LATDbits.LD5 = 1;
            ResetMethod_6();
        }
    }
}
/*
*文件:main.c
*作者:丹1138
*目标:PIC18F45K20
*编译器:XC8 v2.05
*
*PIC18F46K20
*                 +---------+                 +---------+                 +----------+                 +----------+
*1:RC7/RX:--12:NC:23:RA4:--34:NC:
*LED42:RD4:--13:NC:24:RA5:32.768KHz->35:RC1/SOSI:
*LED5 3:RD5:14:RB4:25:RE0:36:RC2:
*LED6 4:RD6:15:RB5/PGM:26:RE1:37:RC3:
*GND->5:VSS:PGC 16:RB6/PGC:27:RE2:LED0 38:RD0:
*3v3->6:VDD:PGD 17:RB7/PGD:3v3->28:VDD:LED1 39:RD1:
*SW17:RB0/INT:VPP->18:RE3/VPP:GND->29:VSS:LED2 40:RD2:
*8:RB1:POT 19:RA0/AN0:4MHz->30:RA7/OSC1:LED3 41:RD3:

*9:RB2:20:RA1:4MHz跳转到0x0000不会重置任何硬件外围设备。我会使用watchdog或reset汇编指令。我知道这是一个非常老的问题,但我偶然发现了一个类似的问题。根据Microchip youtube页面,图片中添加了一些新的增强指令。其中一个是重置指令。我还没有让它工作,也找不到太多关于它的信息,但似乎有办法。@DanTwining:谢谢你的更新。对于Microchip来说,在过去的3年中添加此增强功能是有意义的:)跳到0x0000不会重置堆栈,在一个函数中执行此操作足够多次,您将得到堆栈溢出@科布斯夫:这个答案是7岁。更具建设性的做法是建议对其进行编辑,使其符合现代答案,以帮助那些无意中发现这个问题的人。在这里,我把它变成了“社区维基”,使更新更容易。有没有比调用单个ASM指令更好的方法呢?为什么需要重置整个控制器?您是否打算重置所有外围设备?刚刚写入PGM闪存?(这大概是做这件事的唯一好借口)