[英]Unwanted Jump to interrupt MPLAB X IDE v.3.30
我是微控制器编程的新手,我正在尝试为PICLF1571编写一个定时器程序。 每次从睡眠中唤醒时,都应该写入闪存。 当我用模拟调试它时,它能够写一次,但是一旦它循环,程序就会陷入中断程序。 如果我注释掉中断例程,模拟跳转到另一个地方或转到0x00。 我看到程序卡住的唯一一次是使用函数flash_write时。
如果没有触发标志,可能会导致中断发生的原因是什么?
引脚设置
void init(void){
ANSELA = 0x0; //|-> Pin setup
TRISA = 0x0;
TRISAbits.TRISA5 = 1;
PORTA = 0x0;
LATA = 0x0;
INTCONbits.GIE = 1; //|-> Interrupt setup
INTCONbits.IOCIE = 1;
IOCAP = 0x0;
IOCAPbits.IOCAP5 = 0;
INTCONbits.IOCIF = 0;
IOCAF = 0x0;
IOCAFbits.IOCAF5 = 0;
WDTCONbits.SWDTEN = 1; //|-> Watchdog Timer setup
WDTCONbits.WDTPS = 0b00001;// reconfigure for correct speed
//currently 0b10001
}
主要
//#include <stdio.h>
#include <xc.h>
#include "init.h"
#include "Interrupt.h"
#include "flash.h"
int main(void){
init();
unsigned short ad = 1;
unsigned short f = 0x3FFF;
unsigned short a = 0x0000;
unsigned short ret = 0x0000;
flash_erase(0x0000);
while(1) {
asm("sleep");
flash_write(a,f);
//flash_erase(a);
//flash_read1(a,&ret);
}
return 1;
}
flash_write函数。 基于数据表中的流程图的说明
void flash_write(unsigned short addr, unsigned short data){
INTCONbits.GIE = 0; //||]->start write
PMCON1bits.CFGS = 0;//||]
PMADRH = (unsigned char)((addr >> 8) & 0xFF);
PMADRL = (unsigned char)(addr & 0xFF);
PMCON1bits.FREE = 0;//||]->enable write
PMCON1bits.LWLO = 1;//||]
PMCON1bits.WREN = 1;//||]
PMDATH = (unsigned char)((data >> 8) & 0xFF);
PMDATL = (unsigned char)(data & 0xFF);
PMCON1bits.LWLO = 0;
PMCON2 = 0x55; //||]->unlock sequence
PMCON2 = 0xAA; //||]
PMCON1bits.WR = 1; //||]
NOP(); //||]
NOP(); //||]
PMCON1bits.WREN = 0;//]->end write
INTCONbits.GIE = 1;
asm("RETURN");
}
中断程序
#include <xc.h>
void interrupt button(void){
if (INTCONbits.IOCIE == 1 && IOCAFbits.IOCAF5 == 1 ){
int time = 0;
while (PORTAbits.RA5 == 1){//RA5 in sim never changes. always 0
time++;
if (time >= 20000 && PORTAbits.RA5 == 1){
LATA = 0x0;
asm("NOP");
break;
}
if ( time < 20000 && PORTAbits.RA5 == 0){
asm("NOP");
break;
}
}
IOCAF = 0x0;
INTCONbits.IOCIF = 0;
asm("RETFIE");
}
}
0000h是复位向量地址; 一旦写入,后续复位将跳转到0x3fff,这不是一个只有0x3ff闪存字的设备上的有效地址。 请注意,由于0x3fff是闪存的擦除状态,因此在这种情况下写入实际上没有单独擦除引起的效果。
另外要了解的是,PIC12闪存是字写/行擦除,行是16个字。 因此擦除操作也将擦除整个向量表和程序区域的开始。 你本质上是修改代码,但不是以一种有意义的方式修改(如果它完全有意义的话)。
您应该使用适当的链接器指令保留一个闪存区域,并远离向量表(可能是0x3f0处的整个最后一行),以防止链接器在运行时要在要写入的空间中定位代码。
另一个问题是PIC12F1571上的闪存单元耐用性仅为10000次擦除/写入周期 - 您确定每次设备启动时都要写入同一地址吗? 如果您“删除”保留行并在擦除行并重新启动之前依次写入16个字中的每个字,则会将耐久性提高到160000个周期。 添加更多行以获得更大的耐力。 由于擦除闪存的值为0x3fff(14位字),要查找“当前值”,您需要扫描保留行中的最后一个值不是0x3fff(因此0x3fff隐式地不是有效的实际值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.