會員登陸
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站導航
最新下載
訪問統計 (自2012/5/3)


正在流覽:   1 名訪客



(1) 2 »


(急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
初級會員
註冊日期:
2013/01/21 11:28
所屬群組:
註冊會員
文章: 38
等級: 4; EXP: 94
HP : 0 / 98
MP : 12 / 1700
離線
不好意思,每次打貴司電話都很少人接,但有時又很急

首先是15344這顆IC,這顆IC沒有EEPROM,但有另外一個儲存功能叫NVM可以用,DATASHEET上面寫的READ和ERASE翻成C語言基本上沒什麼問題,但重點就是WRITE這段,小弟真的不太了解其組語這段運用到STATUS跟FSR0的用意,那個MOVIW也不太瞭解怎麼用C語言表達

BANKSEL NVMADRH
MOVF ADDRH,W
MOVWF NVMADRH ; Load initial address
MOVF ADDRL,W
MOVWF NVMADRL
MOVLW LOW DATA_ADDR ; Load initial data address
MOVWF FSR0L
MOVLW HIGH DATA_ADDR
MOVWF FSR0H
BCF NVMCON1,NVMREGS ; Set Program Flash Memory as write location
BSF NVMCON1,WREN ; Enable writes
BSF NVMCON1,LWLO ; Load only write latches
LOOP
MOVIW FSR0++
MOVWF NVMDATL ; Load first data byte
MOVIW FSR0++
MOVWF NVMDATH ; Load second data byte
MOVF NVMADRL,W
XORLW 0x1F ; Check if lower bits of address are 00000
ANDLW 0x1F ; and if on last of 32 addresses
BTFSC STATUS,Z ; Last of 32 words?
GOTO START_WRITE ; If so, go write latches into memory
CALL UNLOCK_SEQ ; If not, go load latch
INCF NVMADRL,F ; Increment address
GOTO LOOP

希望這能有C語言範例CODE能參考,或希望有用過此功能的前輩能引導一下,拜託謝謝

--------------------------

再來是MPLAB編譯問題,先說明一下,程式用在之前版本的MPLAB編譯是完全沒問題的,但不知道為什麼,最新版5.05,中斷副程式一直發生錯誤
main.c:694:6: error: variable has incomplete type 'void'
void interrupt ISR()
^
main.c:694:15: error: expected ';' after top level declarator
void interrupt ISR()

把中斷副程式先/**/掉,編譯就可以過,但警告跳出來變成是我其他所有副程式都沒被呼叫過,而且我include <xc.h>這行一直有燈泡驚嘆號顯示There are unresolved include inside <xc.h>,但我把同樣程式都搬去比較舊版的MPLAB都沒問題,不知道有沒有人也有發生同樣的問題,如何解決,感謝解答

11月19日 14:28:26
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
資深會員
註冊日期:
2012/05/04 19:18
所屬群組:
註冊會員
文章: 209
等級: 13; EXP: 48
HP : 0 / 312
MP : 69 / 6039
離線
void DATAEE_WriteByte(uint16_t bAdd, uint8_t bData)
{
uint8_t GIEBitValue = INTCONbits.GIE;

NVMADRH = ((bAdd >> 8) & 0xFF);
NVMADRL = (bAdd & 0xFF);
NVMDATL = bData;
NVMCON1bits.NVMREGS = 0;
NVMCON1bits.WREN = 1;
INTCONbits.GIE = 0; // Disable interrupts
NVMCON2 = 0x55;
NVMCON2 = 0xAA;
NVMCON1bits.WR = 1;
// Wait for write to complete
while (NVMCON1bits.WR)
{
}

NVMCON1bits.WREN = 0;
INTCONbits.GIE = GIEBitValue; // restore interrupt enable
}

11月19日 15:56:30
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14564
等級: 73; EXP: 16
HP : 1082 / 1804
MP : 4854 / 77126
離線

11月20日 16:24:02
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
初級會員
註冊日期:
2013/01/21 11:28
所屬群組:
註冊會員
文章: 38
等級: 4; EXP: 94
HP : 0 / 98
MP : 12 / 1700
離線
引用:

Edison_yu 寫道:
void DATAEE_WriteByte(uint16_t bAdd, uint8_t bData)
{
uint8_t GIEBitValue = INTCONbits.GIE;

NVMADRH = ((bAdd >> 8) & 0xFF);
NVMADRL = (bAdd & 0xFF);
NVMDATL = bData;
NVMCON1bits.NVMREGS = 0;
NVMCON1bits.WREN = 1;
INTCONbits.GIE = 0; // Disable interrupts
NVMCON2 = 0x55;
NVMCON2 = 0xAA;
NVMCON1bits.WR = 1;
// Wait for write to complete
while (NVMCON1bits.WR)
{
}

NVMCON1bits.WREN = 0;
INTCONbits.GIE = GIEBitValue; // restore interrupt enable
}


前輩你好,我有套用你得程式下去試,但還是怪怪的,請問NVM到底跟EEPROM有什麼差別嗎?他可以寫得位址有哪些呢?網路上感覺很少人在用,我遇到的問題是,我寫97 98 99 100 等等數字進去位址0x0fff,看起來是OK,但是我寫可能60 70 80 90就無法寫入,我同樣都有清除在寫入,但讀取就是255,也就是沒寫入

希望還有前輩能幫幫忙,感謝

11月21日 14:07:24
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
資深會員
註冊日期:
2012/05/04 19:18
所屬群組:
註冊會員
文章: 209
等級: 13; EXP: 48
HP : 0 / 312
MP : 69 / 6039
離線
其實說穿了NVM就是如同Program flash memory一樣,Program flash memory組成NVM, 而EEPROM就是可以重複抹寫的記憶體,但Microchip的NVM也是可以重複寫入,只是壽命或次數好像比EEPROM較低!

查看DATASHEET,一次清除要一個ROW(32 Words)做清除,再來你不能清除道你有放程式指令的地方,也就是說你要留一些PFM的空間來當你用來替代EEPROM的空間,
所以你的程式不能寫滿整個Program Flash 4096 Words

你要不要用MCC產生NVM的CODE,然後貼到你的專案的程式內去試試看,應該可以才對,再來我不知道你如何觀察你寫得值對不對?是將整個IC內的內容讀回來再觀看嗎?
還是用程式指令讀回來,然後用USART印出來看呢?

11月21日 17:20:45
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
版主
註冊日期:
2004/04/28 12:58
所屬群組:
註冊會員
DISTI
文章: 337
等級: 17; EXP: 14
HP : 0 / 403
MP : 112 / 17266
離線
恰恰好我用過PIC16LF15344, 並且把它的FLASH拿來存放資料,當作類似EEPROM來使用。
我用的方法是:

使用MCC,啟用Peripherals中的MEMORY項目,讓它產生相關的函式。
如同樓上說的,可以用哦!

程式碼如下 (給我佔一下篇幅)

uint16_t FLASH_ReadWord
(uint16_t flashAddr)
{
    
uint8_t GIEBitValue = INTCONbits.GIE;   // Save interrupt enable
    
    
INTCONbits.GIE = 0;     // Disable interrupts
    
NVMADRL = (flashAddr & 0x00FF);
    
NVMADRH = ((flashAddr & 0xFF00) >> 8);

    
NVMCON1bits.NVMREGS = 0;    // Deselect Configuration space
    
NVMCON1bits.RD = 1;      // Initiate Read
    
NOP();
    
NOP();
    
INTCONbits.GIE = GIEBitValue;    // Restore interrupt enable

    
return ((NVMDATH << 8) | NVMDATL);
}

void FLASH_WriteWord(uint16_t flashAddr, uint16_t *ramBuf, uint16_t word)
{
    
uint16_t blockStartAddr = (uint16_t)(flashAddr & ((END_FLASH-1) ^ (ERASE_FLASH_BLOCKSIZE-1)));
    
uint8_t offset = (uint8_t)(flashAddr & (ERASE_FLASH_BLOCKSIZE-1));
    
uint8_t i;

    
// Entire row will be erased, read and save the existing data
    
for (i=0; i<ERASE_FLASH_BLOCKSIZE; i++)
    {
        
ramBuf[i] = FLASH_ReadWord((blockStartAddr+i));
    }

    
// Write at offset
    
ramBuf[offset] = word;

    
// Writes ramBuf to current block
    
FLASH_WriteBlock(blockStartAddr, ramBuf);
}

int8_t FLASH_WriteBlock(uint16_t writeAddr, uint16_t *flashWordArray)
{
    
uint16_t    blockStartAddr  = (uint16_t )(writeAddr & ((END_FLASH-1) ^ (ERASE_FLASH_BLOCKSIZE-1)));
    
uint8_t     GIEBitValue = INTCONbits.GIE;   // Save interrupt enable
    
uint8_t i;

    
    
// Flash write must start at the beginning of a row
    
if( writeAddr != blockStartAddr )
    {
        return -
1;
    }

    
INTCONbits.GIE = 0;         // Disable interrupts

    // Block erase sequence
    
FLASH_EraseBlock(writeAddr);

    
// Block write sequence
    
NVMCON1bits.NVMREGS = 0;    // Deselect Configuration space
    
NVMCON1bits.WREN = 1;    // Enable wrties
    
NVMCON1bits.LWLO = 1;    // Only load write latches

    
for (i=0; i<WRITE_FLASH_BLOCKSIZE; i++)
    {
        
// Load lower 8 bits of write address
        
NVMADRL = (writeAddr & 0xFF);
        
// Load upper 6 bits of write address
        
NVMADRH = ((writeAddr & 0xFF00) >> 8);

    
// Load data in current address
        
NVMDATL = flashWordArray[i];
        
NVMDATH = ((flashWordArray[i] & 0xFF00) >> 8);

        if(
i == (WRITE_FLASH_BLOCKSIZE-1))
        {
            
// Start Flash program memory write
            
NVMCON1bits.LWLO = 0;
        }

        
NVMCON2 = 0x55;
        
NVMCON2 = 0xAA;
        
NVMCON1bits.WR = 1;
        
NOP();
        
NOP();

    
writeAddr++;
    }

    
NVMCON1bits.WREN = 0;       // Disable writes
    
INTCONbits.GIE = GIEBitValue;   // Restore interrupt enable

    
return 0;
}

void FLASH_EraseBlock(uint16_t startAddr)
{
    
uint8_t GIEBitValue = INTCONbits.GIE;   // Save interrupt enable
    

    
INTCONbits.GIE = 0; // Disable interrupts
    // Load lower 8 bits of erase address boundary
    
NVMADRL = (startAddr & 0xFF);
    
// Load upper 6 bits of erase address boundary
    
NVMADRH = ((startAddr & 0xFF00) >> 8);

    
// Block erase sequence
    
NVMCON1bits.NVMREGS = 0;    // Deselect Configuration space
    
NVMCON1bits.FREE = 1;    // Specify an erase operation
    
NVMCON1bits.WREN = 1;    // Allows erase cycles

    // Start of required sequence to initiate erase
    
NVMCON2 = 0x55;
    
NVMCON2 = 0xAA;
    
NVMCON1bits.WR = 1;      // Set WR bit to begin erase
    
NOP();
    
NOP();

    
NVMCON1bits.WREN = 0;       // Disable writes
    
INTCONbits.GIE = GIEBitValue;    // Restore interrupt enable
}

/**
  Section: Data EEPROM Module APIs
*/

void DATAEE_WriteByte(uint16_t bAdd, uint8_t bData)
{
    
uint8_t GIEBitValue = INTCONbits.GIE;

    
NVMADRH = ((bAdd >> 8) & 0xFF);
    
NVMADRL = (bAdd & 0xFF);
    
NVMDATL = bData;    
    
NVMCON1bits.NVMREGS = 1;
    
NVMCON1bits.WREN = 1;
    
INTCONbits.GIE = 0;     // Disable interrupts
    
NVMCON2 = 0x55;
    
NVMCON2 = 0xAA;
    
NVMCON1bits.WR = 1;
    
// Wait for write to complete
    
while (NVMCON1bits.WR)
    {
    }

    
NVMCON1bits.WREN = 0;
    
INTCONbits.GIE = GIEBitValue;   // restore interrupt enable
}

uint8_t DATAEE_ReadByte(uint16_t bAdd)
{
    
NVMADRH = ((bAdd >> 8) & 0xFF);
    
NVMADRL = (bAdd & 0xFF);
    
NVMCON1bits.NVMREGS = 1;    
    
NVMCON1bits.RD = 1;
    
NOP();  // NOPs may be required for latency at high frequencies
    
NOP();

    return (
NVMDATL);
}

11月21日 22:37:48
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
初級會員
註冊日期:
2013/01/21 11:28
所屬群組:
註冊會員
文章: 38
等級: 4; EXP: 94
HP : 0 / 98
MP : 12 / 1700
離線
感謝眾多前輩解說,那我還想知道一個問題,如果我先把NVM刪掉,我可以編譯好後知道我有記憶體哪些地方沒用到再下去補NVM嗎?有辦法知道我有哪些區塊沒用到嗎?我只要一個位址的空間就好,因為案子的應用就只是設定一個數值後存入記憶體,開機時去讀取那個值而已,那個值也不會超過255,就這樣而已

感謝各位前輩相助

11月22日 17:05:41
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
資深會員
註冊日期:
2012/05/04 19:18
所屬群組:
註冊會員
文章: 209
等級: 13; EXP: 48
HP : 0 / 312
MP : 69 / 6039
離線
程式編譯完成應該就可以知道你用了多少空間,我想你可以預留最後一個row的空間來存放,這是我猜測可行的方式,你可以試試看阿!

11月22日 17:29:09
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14564
等級: 73; EXP: 16
HP : 1082 / 1804
MP : 4854 / 77126
離線
如果該元件有 HEF 的功能,那就放在 HEF 的位址,否則就從 Flash 的最後有效位址往前看算要使用多少記憶體就從那裡的節區起始位址開始。

Flash memory 寫入時是先做清除的動作。清除的時候是一眾大區塊,寫入的時候的是一個小區塊的寫入。

11月22日 17:45:55
轉換PDF檔 列印


Re: (急!!!)PIC16F15344 NVM問題 以及 新版MPLAB編譯找不到xc.h的問題
初級會員
註冊日期:
2013/01/21 11:28
所屬群組:
註冊會員
文章: 38
等級: 4; EXP: 94
HP : 0 / 98
MP : 12 / 1700
離線
所以前輩們的意思是,我把它寫在最後面0X0FFF應該是最保險的嗎?

11月23日 13:27:03
轉換PDF檔 列印



(1) 2 »



無法在此發表文章
可以在此觀看文章
無法回覆文章
無法編輯自己的文章
無法刪除自己的文章
無法發起投票調查
無法在此投票
無法上傳附加檔案
無法不經審核直接發表文章

[進階搜尋]


搜尋
Microchip連結

網頁捷徑
2019 Winter Elite 報名
教育訓練
其它網站連結
電話: 02-25000405
產品技術問題產品技術支援專線:0800-717718 台北02-25088600 新竹03-5778366 Ext. 8600 高雄07-2137830 MicrochipDIRECT 專線: 07-2137830
Powered by XOOPS © 2001-2012 The XOOPS Project