2016-05-13 3 views
1

Ich bin neu in der Programmierung von Mikrocontrollern und versuche ein Timerprogramm für den PICLF1571 zu schreiben. Jedes Mal, wenn es aus dem Schlaf erwacht, sollte es in den Flash-Speicher schreiben. Wenn ich es mit der Simulation debugge, ist es in der Lage, einmal zu schreiben, aber sobald es Schleifen macht, bleibt das Programm in der Unterbrechungsroutine stecken. Wenn ich die Unterbrechungsroutine auskommentiere, springt die Simulation zu einer anderen Stelle oder geht zu 0x00. Das einzige Mal, wenn ich sehe, dass das Programm hängen bleibt, ist die Funktion flash_write.Unerwünscht Sprung zum Interrupt MPLAB X IDE v.3.30

Was könnten einige Ursachen für Interrupts sein, wenn keine Flags ausgelöst werden?

pin Setup

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 
} 

Haupt

//#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 Funktion. Anweisungen basierend auf Flussdiagramm in Datenblatt

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"); 
} 

Interruptroutine

#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"); 
    } 
} 
+0

Meinten Sie PIC12F1571? Es gibt kein Gerät PICLF1571. – Clifford

Antwort

0

0000h der Rücksetzvektoradresse ist; Einmal geschrieben, werden nachfolgende Rücksetzungen zu 0x3fff springen, was keine gültige Adresse auf einem Gerät mit nur 0x3ff Flash-Wörtern ist. Beachten Sie, dass, da 0x3fff der gelöschte Zustand des Flash-Speichers ist, der Schreibvorgang in diesem Fall tatsächlich keinen Effekt hat, der nicht bereits allein durch den Löschvorgang verursacht wird.

Verstehen Sie auch, dass der PIC12-Flash-Speicher Word-Write/Row-Erase ist und eine Zeile 16 Wörter. Die Löschoperation löscht also auch die gesamte Vektortabelle und den Start des Programmbereichs. Sie modifizieren den Code im Wesentlichen, aber nicht in einer Weise, die einen Sinn ergibt (wenn es überhaupt Sinn macht).

Sie sollten eine Fläche von Flash unter Verwendung geeigneter Linker-Richtlinien und weit weg von der Vektortabelle reservieren (wahrscheinlich die gesamte letzte Zeile an 0x3f0, den Linker zu verhindern Lokalisierungscode in den Raum Sie wollen während der Laufzeit schreiben.

Ein weiteres Problem ist, dass die Lebensdauer der Flash-Zelle auf PIC12F1571 nur 10000 Lösch-/Schreibzyklen beträgt - möchten Sie sicher jedes Mal, wenn das Gerät hochfährt, auf die gleiche Adresse schreiben? Die 16 Wörter nacheinander, bevor die Reihe gelöscht und neu gestartet wird, erhöhen Sie Ausdauer zu 160000 Zyklen. Fügen Sie mehr Reihen hinzu, um größere Ausdauer zu erhalten. Da gelöschter Blitz einen Wert 0x3fff (14-Bit-Wörter) hat, um den "gegenwärtigen Wert" zu finden um die reservierten Zeilen nach dem letzten Wert zu durchsuchen, der nicht 0x ist 3fff (0x3fff ist daher implizit kein gültiger tatsächlicher Wert).