2016-05-13 5 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にジャンプします。この0x3fffは、0x3ffワードのフラッシュのみを持つデバイス上の有効なアドレスではありません。 0x3fffはフラッシュメモリの消去状態なので、この場合の書き込みは、実際には消去だけでは発生していない効果はないことに注意してください。

また、PIC12フラッシュメモリはワードライト/ロウ消去であり、ロウは16ワードです。そのため、消去操作はベクタテーブル全体とプログラム領域の開始部分を消去します。基本的にはコードを変更していますが、意味をなさずに(あまり意味をなさない場合)はそうではありません。

あなたは、実行時に書きたい空間にリンカ位置決めコードを防ぐために、0x3f0で十分に離れベクタテーブルから適当なリンカーディレクティブを使用してフラッシュの面積と(おそらく全体の最後の行を確保しなければならない。

もう1つの問題は、PIC12F1571のフラッシュセル耐久性が10000イレーズ/ライトサイクルにすぎないことです。デバイスが起動するたびに同じアドレスに書き込むことを確かめていますか?予約された行を「ストライプ化」し、順番に16ワードを消去して再起動すると、160000サイクルに耐えられるようになります。耐久性を高めるために行を追加します。消去されたフラッシュの値は0x3fff(14ビットワード)であるため、必要な "現在の値" 0xでない最後の値の予約済み行をスキャンする3fff(0x3fffは暗黙的に有効な実際の値ではありません)。

関連する問題