PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   MPASM (http://www.picvietnam.com/forum/forumdisplay.php?f=34)
-   -   Đọc ghi Flash Program Memory (http://www.picvietnam.com/forum/showthread.php?t=934)

hungpq 02-02-2007 03:50 PM

Các bác ơi giúp tôi với. Tôi muốn ghi dữ liệu vào bộ nhớ Flash của con 16f877a mà không sao ghi được. Tôi đã làm theo hướng dẫn trong datasheet nhưng vẫn không được. Mong các cao thủ giúp đỡ.

hungpq 05-02-2007 10:31 AM

Cám ơn bác namqn đã quan tâm giúp đỡ. Tôi dùng hợp ngữ để lập trình cho PIC và dùng Mplap để mô phỏng. Tôi sử dụng đoạn Code dưới đây trong datasheet của con pic16f877a để thực hiện, nhưng mô phỏng chẳng thấy nó chạy đúng gì cả. Không hiểu là nó sai hay mình mô phỏng không đúng. Mong bác chỉ giúp.

Code:

; This write routine assumes the following:
;
; 1. A valid starting address (the least significant bits = ‘00’)is loaded in ADDRH:ADDRL
; 2. The 8 bytes of data are loaded, starting at the address in DATADDR
; 3. ADDRH, ADDRL and DATADDR are all located in shared data memory 0x70 - 0x7f
;
          BSF        STATUS,RP1    ;
          BCF        STATUS,RP0    ; Bank 2
          MOVF      ADDRH,W        ; Load initial address
          MOVWF    EEADRH            ;
          MOVF      ADDRL,W          ;
          MOVWF    EEADR            ;
          MOVF      DATAADDR,W    ; Load initial data address
          MOVWF    FSR ;
          LOOP      MOVF INDF,W    ; Load first data byte into lower
          MOVWF    EEDATA            ;
          INCF        FSR,F              ; Next byte
          MOVF      INDF,W            ; Load second data byte into upper
          MOVWF    EEDATH          ;
          INCF        FSR,F              ;
          BSF          STATUS,RP0    ; Bank 3
          BSF          EECON1,EEPGD  ; Point to program memory
          BSF          EECON1,WREN  ; Enable writes
          BCF          INTCON,GIE      ; Disable interrupts (if using)
          MOVLW    55h                ; Start of required write sequence:
          MOVWF    EECON2          ; Write 55h
          MOVLW    AAh                ;
          MOVWF    EECON2          ; Write AAh
          BSF          EECON1,WR      ; Set WR bit to begin write
          NOP                                        ; Any instructions here are ignored as processor
                                                ; halts to begin write sequence
          NOP                              ; processor will stop here and wait for write complete
                                                ; after write processor continues with 3rd instruction
          BCF        EECON1,WREN    ; Disable writes
          BSF        INTCON,GIE        ; Enable interrupts (if using)
          BCF        STATUS,RP0      ; Bank 2
          INCF        EEADR,F            ; Increment address
          MOVF      EEADR,W          ; Check if lower two bits of address are ‘00’
          ANDLW    0x03                ; Indicates when four words have been programmed
          XORLW    0x03                ;
          BTFSC      STATUS,Z          ; Exit if more than four words,
          GOTO      LOOP                ; Continue if less than four words


namqn 06-02-2007 06:45 PM

Trích:

Nguyên văn bởi hungpq (Post 7227)
Cám ơn bác namqn đã quan tâm giúp đỡ. Tôi dùng hợp ngữ để lập trình cho PIC và dùng Mplap để mô phỏng. Tôi sử dụng đoạn Code dưới đây trong datasheet của con pic16f877a để thực hiện, nhưng mô phỏng chẳng thấy nó chạy đúng gì cả. Không hiểu là nó sai hay mình mô phỏng không đúng. Mong bác chỉ giúp.

MPLAB SIM mô phỏng EEPROM với thời gian ghi là khoảng 10 ms (làm tròn đến số nguyên lần chu kỳ máy gần nhất), do đó sau lệnh set bit WR của EECON1 thì bộ xử lý sẽ dừng trong một số chu kỳ tương đương với 10 ms thời gian thực.

Bạn cần cho biết thêm 'chẳng thấy nó chạy đúng' là như thế nào, và đọc thêm phần nói về mô phỏng ngoại vi của PIC16 trong tài liệu "MPLAB IDE User's Guide" (DS51519), mục 16.3.3.

Thân,

hungpq 07-02-2007 10:26 AM

Bác namqn ơi tôi đã đọc đoạn tài liệu đó rồi nhưng nó chỉ nói sơ qua về việc thực hiện mô phỏng với bộ nhớ EEPROM thôi. Còn ở đây tôi muốn hỏi bác về việc thực hiện ghi vào bộ nhớ Flash cơ. Tôi đã thực hiện chạy debug bình thường và sau khi chạy xong đoạn code đó thì xem lại bộ nhớ Flash xem có ghi được không, nhưng không thấy ghi được. Không biết đoạn code đó sai hay là MPLAB không cho mình xem dữ liệu ghi vào Flash.

namqn 07-02-2007 08:42 PM

Trích:

Nguyên văn bởi hungpq (Post 7269)
Bác namqn ơi tôi đã đọc đoạn tài liệu đó rồi nhưng nó chỉ nói sơ qua về việc thực hiện mô phỏng với bộ nhớ EEPROM thôi. Còn ở đây tôi muốn hỏi bác về việc thực hiện ghi vào bộ nhớ Flash cơ. Tôi đã thực hiện chạy debug bình thường và sau khi chạy xong đoạn code đó thì xem lại bộ nhớ Flash xem có ghi được không, nhưng không thấy ghi được. Không biết đoạn code đó sai hay là MPLAB không cho mình xem dữ liệu ghi vào Flash.

Ghi vào Flash thì vẫn phải chờ một khoảng thời gian, nếu MPLAB SIM mô phỏng đúng thì bạn cũng phải chờ một số chu kỳ máy tương đương với thời gian thực tự ghi vào Flash (theo datasheet thì bằng với thời gian đó của EEPROM). Những đoạn code kiểu này thì tôi chỉ chạy trên chip thực chứ không mô phỏng bao giờ.

Thân,

hungpq 08-02-2007 09:11 AM

Nếu nói về mặt thời gian chờ cho hết chu kỳ ghi thì có lẽ là hơi nhiều so với thực tế thời gian ghi của Flash. Bởi vì khi ta debug thì thời gian là rất lớn. Chỉ có điều tôi thấy rằng không hiểu tại sao khi thực hiện lệnh set bit WR của thanh ghi EECON1 thì không thấy bit này được set lên. Theo tôi ở đây có hai giả thiết được đặt ra:
- Thời gian bit này được set là rất nhỏ ( trong thực tế sẽ là như vậy) và khi ta dùng MPLAB để mô phỏng thì không nhìn thấy được trạng thái set lên của nó.
- Thứ hai là MPLAB không thực hiện mô phỏng việc ghi vào bộ nhớ Flash.

Vậy theo bác namqn thì giả thiết nào đúng hay có vấn đề nào khác ở đây. Trong thực tế việc ghi vào Flash thì bác dùng những lệnh nào và với những dòng code như trên thì có ghi được vào Flash hay không?

falleaf 08-02-2007 10:05 AM

Trích:

Nguyên văn bởi hungpq (Post 7278)
Nếu nói về mặt thời gian chờ cho hết chu kỳ ghi thì có lẽ là hơi nhiều so với thực tế thời gian ghi của Flash. Bởi vì khi ta debug thì thời gian là rất lớn. Chỉ có điều tôi thấy rằng không hiểu tại sao khi thực hiện lệnh set bit WR của thanh ghi EECON1 thì không thấy bit này được set lên.

Bạn đọc trong datasheet, có đoạn này:
Trích:

Initiates a write cycle. The bit is cleared by hardware once write is complete. The WR bit can only be set (not cleared) in software.
Như vậy, bit này sẽ tự động được xóa. Khi bạn set lên, thì nó sẽ được tự động xóa. Bạn kiểm tra kỹ lại lúc bạn mô phỏng xem thử, bạn có dừng đúng vị trí set không. Ngoài ra, những bit đặc biệt này, đã mấy năm rồi F không viết PIC, cho nên không còn nhớ chính xác việc mô phỏng và kiểm tra như thế nào. Nhưng nguyên tắc, bạn có thể debug từng chu kỳ máy một dùng MPLAB SIM, và khi bạn set bit, thì nó sẽ có thể thấy được nó set lên, và nó sẽ tự xóa, nên nếu bạn chờ, bạn sẽ không thể thấy, bạn phải chuyển vào chế độ debug.

Chúc vui

hungpq 08-02-2007 03:02 PM

Cám ơn bác falleaf đã quan tâm. Về mặt dùng MPLAB để debug từng dòng lệnh một, quan sát sự thay đổi nội dung của các thanh ghi thì tôi thực hiện hoàn toàn đúng và dòng datasheet mà bác giới thiệu thì tôi cũng đã đọc rất nhiều lần. Nhưng quả thật là tôi không quan sát thấy bit WR của thanh ghi EECON1 được set lên. Cho nên tôi mới đặt ra giả thiết rằng MPLAB không hỗ trợ việc mô phỏng ghi vào bộ nhớ chương trình (FLASH). Không biết như vậy có đúng không mong các bác quan tâm giúp đỡ.

namqn 08-02-2007 08:20 PM

Trích:

Nguyên văn bởi hungpq (Post 7278)
Nếu nói về mặt thời gian chờ cho hết chu kỳ ghi thì có lẽ là hơi nhiều so với thực tế thời gian ghi của Flash. Bởi vì khi ta debug thì thời gian là rất lớn. Chỉ có điều tôi thấy rằng không hiểu tại sao khi thực hiện lệnh set bit WR của thanh ghi EECON1 thì không thấy bit này được set lên. Theo tôi ở đây có hai giả thiết được đặt ra:
- Thời gian bit này được set là rất nhỏ ( trong thực tế sẽ là như vậy) và khi ta dùng MPLAB để mô phỏng thì không nhìn thấy được trạng thái set lên của nó.
- Thứ hai là MPLAB không thực hiện mô phỏng việc ghi vào bộ nhớ Flash.

Vậy theo bác namqn thì giả thiết nào đúng hay có vấn đề nào khác ở đây. Trong thực tế việc ghi vào Flash thì bác dùng những lệnh nào và với những dòng code như trên thì có ghi được vào Flash hay không?

Tôi quên nhắc bạn rằng Flash của PIC16F877A có 4 thanh ghi đệm khi ghi, có nghĩa là bạn phải ghi vào cả 4 thanh ghi đệm đó rồi mới bật bit WR của thanh ghi EECON1, nếu bạn không ghi vào đủ 4 thanh ghi đệm thì PIC sẽ không thực hiện xóa block đó và ghi vào 4 ô nhớ chương trình. Bạn xem thêm trong datasheet của PIC16F877A, mục 3.6, hình 3-1.

Trong thực tế thì tôi cũng chỉ dùng các lệnh trong đoạn required sequence đó thôi. Có điều trong thực tế thì ghi vào thanh ghi đệm 4 lần mới thực sự xảy ra việc xóa và ghi vào block 1 lần.

Thân,

namqn 12-02-2007 08:31 PM

Trích:

Nguyên văn bởi hungpq (Post 7345)
Báo cáo với các bác là tôi đã ghi được dữ liệu vào bộ nhớ Flash của con pic16f877a. Đoạn code trong datasheet của con 16f877a nó bị sai các bác ah, còn MPLAB vẫn cho mô phỏng việc ghi flash bình thường, chỉ có điều nó không cho mình xem bit WR trong thanh ghi EECON1 set lên.

Bạn có thể chỉ ra chỗ sai hay không? (Cho biết version của datasheet mà bạn đang dùng luôn nhé).

Thân,

hungpq 13-02-2007 09:17 AM

Báo cáo với bác namqn là cái datasheet mà tôi tham khảo là DS39582B. Còn đoạn code đầy đủ của nó tôi đã đưa lên nhờ bác xem giúp rồi đó.

Code:

LOOP.....
      .
      .
      INCF            EEADR,F
      MOVF          EEADR,W
      ANDLW        0X03
      XORLW        0X03
      BTFSC          STATUS,Z
      GOTO          LOOP

Đây chính là đoạn code mà nó bị sai các bác ah. Ở đây có hai cái sai chính.
- Thứ nhât: Giá trị thanh ghi EEADR được tăng trước khi nó được kiểm tra, cho nên nó không bao giờ tăng đủ giá trị cần thiết cả (tăng 4 địa chỉ so với địa chỉ ban đầu).
- Thứ hai: Khi dùng câu lệnh
BTFSC STATUS,Z
GOTO LOOP
Đoạn code này chỉ được thực hiện một lần duy nhất. Trong khi đó để ghi vào bộ nhớ Flash thì cần phải thực hiện ghi dữ liệu vào 4 thanh ghi đệm của nó ( Đoạn code trên cần phải được thực hiện 4 lần).
Tôi đã thực hiện sửa lại đoạn code trên một cách đơn giản như sau:

Code:

LOOP.....
      .
      .
      MOVF          EEADR,W
      ANDLW        0X03
      XORLW        0X03
      BTFSC          STATUS,Z
      RETURN
      INCF            EEADR,F
      GOTO          LOOP

Tôi đã thử thấy nó cũng ghi vào được bình thường.

namqn 13-02-2007 09:29 PM

Trích:

Nguyên văn bởi hungpq (Post 7349)
Báo cáo với bác namqn là cái datasheet mà tôi tham khảo là DS39582B. Còn đoạn code đầy đủ của nó tôi đã đưa lên nhờ bác xem giúp rồi đó.

Code:

LOOP.....
      .
      .
      INCF            EEADR,F
      MOVF          EEADR,W
      ANDLW        0X03
      XORLW        0X03
      BTFSC          STATUS,Z
      GOTO          LOOP

Đây chính là đoạn code mà nó bị sai các bác ah. Ở đây có hai cái sai chính.
- Thứ nhât: Giá trị thanh ghi EEADR được tăng trước khi nó được kiểm tra, cho nên nó không bao giờ tăng đủ giá trị cần thiết cả (tăng 4 địa chỉ so với địa chỉ ban đầu).
- Thứ hai: Khi dùng câu lệnh
BTFSC STATUS,Z
GOTO LOOP
Đoạn code này chỉ được thực hiện một lần duy nhất. Trong khi đó để ghi vào bộ nhớ Flash thì cần phải thực hiện ghi dữ liệu vào 4 thanh ghi đệm của nó ( Đoạn code trên cần phải được thực hiện 4 lần).
Tôi đã thực hiện sửa lại đoạn code trên một cách đơn giản như sau:

Code:

LOOP.....
      .
      .
      MOVF          EEADR,W
      ANDLW        0X03
      XORLW        0X03
      BTFSC          STATUS,Z
      RETURN
      INCF            EEADR,F
      GOTO          LOOP

Tôi đã thử thấy nó cũng ghi vào được bình thường.

Vòng lặp trong ví dụ của Microchip đã viết đúng, bạn hiểu không chính xác rồi.

Theo điều kiện đã ghi chú thì ở đầu vòng lặp phải có 2 bit thấp nhất của EEADR là '00', như vậy thì ghi dữ liệu trước rồi tăng địa chỉ sau là đúng. Và các giá trị lần lượt của 2 bit thấp nhất đó sẽ là 00, 01, 10, và 11, khi đó đến lần tăng thứ năm thì 2 bit đó sẽ về lại '00', và chúng ta đã ghi đủ giá trị vào 4 thanh ghi đệm.

Thân,

hungpq 14-02-2007 08:53 AM

Trời ơi bác namqn bác tính lại đi, vòng lặp này của nó chỉ chạy được 3 vòng thôi. Tôi nghĩ rằng đây là vấn đề đơn giản nên không giải thích rõ.

Giá trị ban đầu của hai bit D1, D0 của thanh ghi EEADR là '00'. Ta tạm gán cho nó 1 cái tên V, gái trị ban đầu V = 00.

- Lần 1: V = 00 -> V tăng lên 1 -> V = 01 -> kiểm tra V, lúc này V = 01 => Tiếp tục vòng lặp.

- Lần 2: V = 01 -> V tăng lên 1 -> V = 10 -> kiểm tra V, lúc này V = 10 => Tiếp tục vòng lặp.

- Lần 3: V = 10 -> V tăng lên 1 -> V = 11 -> kiểm tra V, lúc này V = 11 => Thoát khỏi vòng lặp và kết thúc.

Như vậy vòng lặp này chỉ chạy được 3 vòng và không bao giờ ghi được vào đủ 4 thanh ghi đệm.

namqn 14-02-2007 06:57 PM

Trích:

Nguyên văn bởi hungpq (Post 7356)
Trời ơi bác namqn bác tính lại đi, vòng lặp này của nó chỉ chạy được 3 vòng thôi. Tôi nghĩ rằng đây là vấn đề đơn giản nên không giải thích rõ.

Giá trị ban đầu của hai bit D1, D0 của thanh ghi EEADR là '00'. Ta tạm gán cho nó 1 cái tên V, gái trị ban đầu V = 00.

- Lần 1: V = 00 -> V tăng lên 1 -> V = 01 -> kiểm tra V, lúc này V = 01 => Tiếp tục vòng lặp.

- Lần 2: V = 01 -> V tăng lên 1 -> V = 10 -> kiểm tra V, lúc này V = 10 => Tiếp tục vòng lặp.

- Lần 3: V = 10 -> V tăng lên 1 -> V = 11 -> kiểm tra V, lúc này V = 11 => Thoát khỏi vòng lặp và kết thúc.

Như vậy vòng lặp này chỉ chạy được 3 vòng và không bao giờ ghi được vào đủ 4 thanh ghi đệm.

Vâng, bạn nói vòng lặp này chỉ chạy được 3 vòng thì đúng, tôi không chú ý lắm đến nó vì không viết vòng lặp theo kiểu như vậy. Có lẽ chỉ là lỗi đánh máy của lập trình viên thôi. Nếu sửa lệnh XORLW thành XORLW 0x00 thì ok.

Trước đó bạn nói vòng lặp chỉ chạy được 1 lần nên tôi mới khẳng định là nó chạy được nhiều lần.

Phân tích kỹ hơn thì có thể thấy là lệnh XORLW bị thừa, vì khi ANDLW với 0x03 thì đồng thời đã che các bit cao và kiểm tra 2 bit thấp có bằng '00' luôn rồi.

Thân,

hungpq 15-02-2007 09:41 AM

Bác namqn phân tích hoàn toàn đúng, ở đây câu lệnh XORLW bị thừa. Nhưng nếu để nguyên như cũ của nó thì vòng lặp này đúng là chỉ chạy được một vòng duy nhất thôi bác ah.

namqn: bạn nói chính xác, đã được xác nhận từ các người dùng có kinh nghiệm trên diễn đàn của Microchip: http://forum.microchip.com/tm.aspx?m...1&key=&#229492.


Múi giờ GMT. Hiện tại là 03:55 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam