Embedded 如何在C中重置PIC18?
使用HiTech PIC18 C编译器的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,但我认为编译器的解决方案会做正确的事情 有一
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闪存?(这大概是做这件事的唯一好借口)