5

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

编辑:

我正在使用

void reset()
{
#asm 
  reset
#endasm
}

但必须有更好的方法

4

6 回答 6

8

The compilers usually have their own reset() function built in, but it just does exactly what your function does, and the actual name may vary from compiler to compiler.

You are already doing it the best possible way.

于 2008-10-20T15:43:32.473 回答
5

Your answer is the best way I know of. The key is that you have the assembly instruction inside a function call, all by itself. The compiler will not optimize a function that has inline assembly in it, so if you include the reset instruction inline to a very large function, the compiler will not optimize any of the code in that function. You have avoided this by putting Reset in its own function. The code in this function won't be optimized, but who cares, since it is such a small function.

于 2009-07-29T18:45:09.860 回答
2

这里有一个常见问题解答

问:如何重置微信?

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

#asm ljmp 0x0000

#endasm

这使用起来非常安全,即使在中断或过程中调用也是如此。PIC 16x 系列微控制器有 8 个堆栈级别。每次调用过程时,返回地址都会用完一层堆栈。它是一个循环缓冲区,因此即使 micro 有 7 个程序级深并且在调用复位时处于中断状态,这也是堆栈缓冲区的新开始,并且 micro 将照常继续。

Another way is to set watchdog the timer when the chip is programmed, and use CLRWDT() instructions all through the code. When you want the micro to reset, stop clearing the watchdog bit and the micro will reset after around 18ms to 2 seconds depending on the prescaler.

于 2008-10-17T18:51:24.577 回答
1

As Mike has edited this original question from 11 years ago it seems doubtful the Original Poster needs a comprehensive answer. In fact the OP seems to have asked about or responded on just 2 topics regarding microcontrollers in the past 9 years.

Given all that it may be helpful to look at some of the ways the PIC18F controller can be caused to begin execution from the reset vector with code that compiles with Hi-Tech C or XC8 as it is now called by Microchip.

This code has been tested using MPLABX v5.25, XC8 v2.05 and the PIC18F45K20 controller.

/*
 * 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();
        }
    }
}
于 2019-12-22T01:25:35.320 回答
0

除非编译器供应商的运行时库定义了一个库函数(如果这样的库甚至存在于微控制器世界中......但它应该存在),那么没有。C 本身当然不会帮助你,做“重置”对于 C 来说是一个太多特定于平台的问题,无法涵盖它。

于 2008-10-17T16:17:34.467 回答
0

我使用 ccsinfo.com 编译器,它有一个类似的 API 调用来重置 PIC,但我认为编译器的解决方案会做正确的事情。

于 2008-10-17T17:07:42.523 回答