2016-05-13 3 views
1

Я новичок в программировании на микроконтроллерах, и я пытаюсь написать программу таймера для PICLF1571. Каждый раз, когда он просыпается от сна, он должен записываться во флэш-память. Когда я отлаживаю его с помощью симуляции, он может писать один раз, но как только он петли, программа застревает в подпрограмме прерывания. Если я прокомментирую процедуру прерывания, симуляция переходит в другое место или переходит в 0x00. Единственный раз, когда я вижу, что программа застревает, - это когда используется функция flash_write.Нежелательный переход на прерывание MPLAB X IDE v.3.30

Что может быть причиной прерываний, если флаги не запускаются?

установки пин

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

Возможно, вы имели в виду PIC12F1571? Нет устройства PICLF1571. – Clifford

ответ

0

0000h является вектором сброса адреса; после записи последующие сбрасывания перейдут на 0x3fff, что не является допустимым адресом на устройстве с только 0x3ff словами вспышки. Обратите внимание, что поскольку 0x3fff - это стертое состояние флэш-памяти, запись в этом случае фактически не имеет эффекта, который уже не вызван стиранием.

Также поймите, что флэш-память PIC12 представляет собой слово-запись/стирание строк, а строка - 16 слов. Таким образом, операция стирания уничтожит всю таблицу векторов и начало области программы. Вы по существу модифицируете код, но не в манере, чем имеет смысл (если это имеет смысл вообще).

Вы должны зарезервировать область вспышки, используя соответствующие директивы компоновщика и вдали от таблицы векторов (возможно, всю последнюю строку в 0x3f0, чтобы предотвратить линкер местонахождение кода в пространстве вы хотите написать во время выполнения.

Другая проблема заключается в том, что выносливость флеш-памяти на PIC12F1571 составляет всего 10000 циклов стирания/записи - вы уверены, что хотите писать на один и тот же адрес каждый раз, когда устройство загружается? Если вы «полоскаете» зарезервированную строку и записываете в каждую из 16 слов в очереди, прежде чем стирать строку и перезапустить, вы увеличите выносливость до 160000 циклов. Добавьте больше строк, чтобы получить большую выносливость. Поскольку стертая вспышка имеет значение 0x3fff (14 бит слов), чтобы найти «текущее значение», которое вам нужно для сканирования зарезервированных строк (строк) для последнего значения, которое не равно 0x 3fff (0x3fff неявно, следовательно, не является действительным фактическим значением).

Смежные вопросы