PDA

View Full Version : Đọc ghi Flash Program Memory


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.

; 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
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
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
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:
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
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
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 đó.


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:


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
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 đó.


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:


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ờ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=228697&mpage=1&key=𸁴.

falleaf
15-02-2007, 02:47 PM
Trong hai cách sửa XORLW, thì cách đảo INCF với MOVF của bạn hungpq hiệu quả hơn và chuẩn hơn so với cách sửa XORLW 0x00.

Tuy nhiên bạn dùng lệnh RETURN rất không ổn. Bản thân lệnh RETURN nó không làm gì hết, nhưng có có một nhiệm vụ là lôi cái Top of Stack ra và nhảy tới đó.

Giả sử đoạn chương trình trên của bạn, bạn viết dạng CALL thì lập tức nó nhảy về chỗ CALL đó mà không thực hiện tiếp lệnh bên dưới. Nhưng nếu bạn không sử dụng CALL, và TOS đang trống!!?

Do vậy, cách viết an toàn là GOTO $+3
Rồi nếu bạn dùng CALL thì ngay sau dòng GOTO LOOP, bạn sử dụng RETURN. Nếu bạn không dùng CALL, thì bạn có thể làm gì đó cũng được, ngay sau đó.

Hồi F viết, F hay đặt một cái nhãn chỗ RETURN và nếu cần RETURN thì F nhảy tới đó. Viết như vậy để giữ cấu trúc:


CALL LOOP
...
...
LOOP
..
RETLOOP RETURN


Đây chỉ là một gợi ý, có thể bạn không thích kiểu viết này, chỉ là một cái recommend, không quan trọng lắm.

Về phần bạn hỏi về ghi WR, đã gần 3 năm F không đụng tới PIC, cho nên F không thực sự nhớ rõ lắm. Tuy nhiên, bạn thử kiểm tra lại đoạn này. Đó là khi ghi Flash thì WR sẽ được tự xóa, và nó hoàn toàn được thực hiện bởi phần cứng. Khi đó nó không hề được xử lý gì cả. Có nghĩa là việc thì bạn có quyền bật trong chương trình, nhưng sau đó, thì bạn sẽ không thấy gì cả mà tự động tắt.

Trong MPLAB, nó cho bạn xem EEPROM bằng MPLAB SIM. Vì vậy, bạn có thể theo dõi kết quả EEPROM có được ghi hay chưa. Bạn cũng có thể xem PROGRAMME MEMORY. Bạn chọn View và chọn các mục tương ứng để quan sát tại các địa chỉ mà bạn tương tác.

Chúc vui

namqn
17-02-2007, 08:49 AM
Tôi xin lỗi vì một số nhận định không chính xác ở các post trước. Tôi (và có lẽ nhiều người dùng lâu năm) thường tin tưởng một cách chủ quan vào các datasheet của nhà sản xuất.

Tôi xin xác nhận là những ý kiến của bạn hungpq về sai sót của đoạn code mẫu trong datasheet của PIC16F87xA là chính xác: đoạn code đó chỉ thực thi 1 lần nếu đúng theo các điều kiện ban đầu được đặt ra, và cách sửa tốt là bỏ lệnh XOR và đổi BTFSC thành BTFSS.

Thân,

hungpq
22-02-2007, 10:18 AM
Chào các bác mải ăn tết lâu quá nay mới ghé thăm, cáo lỗi các bác. Thưa các bác như vậy là chúng ta đã thống nhất với nhau rằng đoạn code mẫu thực hiện ghi vào bộ nhớ FLASH trong datasheet của con PIC16f877A là bị sai. Thú thực là tôi không bất ngờ với việc code mẫu trong các datasheet bị sai bởi vì tôi đã gặp rất nhiều lần rồi. Còn việc sửa lại đoạn code này như thế nào cho hợp lý thì theo tôi không cần thiết. Bởi vì với mỗi ứng dụng, với mỗi chương trình, đều có những cách thể hiện riêng của nó để cho nó tối ưu nhất. Đúng như vậy không các bác. Còn nếu có thể thì các bác cho một yêu cầu về một hàm ghi dữ liệu vào bộ nhớ Flash của con 16f877a để mọi người cùng thảo luận và xây dựng.

falleaf
22-02-2007, 04:06 PM
Trong datasheet thực tế là sai rất nhiều chỗ, lúc trước F mở ra cái box MPASM này là có ý đồ để các bạn viết MPASM và chuẩn hóa lại các đoạn code.

Thực tế như các bạn thấy, nếu như F có viết những lời mào đầu, thì giả sử như có đúng, có sai... Như vậy, nếu F có viết thì cũng làm sao bằng cái kho datasheet của Microchip, và cũng không thể bằng được cái kho thư viện thuật toán của piclist.

Tuy nhiên, một điều hơi sai ý đồ, đó là vì nghĩ như vậy, cho nên F dành thời gian ban đầu, tập trung vào Cơ bản về PIC, và chính cái tên cơ bản về PIC cũng thu hút rất nhiều người đọc. Cuối cùng, ngay cả bài viết này, các bạn cũng tập trung vào box Cơ bản về PIC này, mà không chú ý viết bài ở phần MPASM

Một số vấn đề về thuật toán cao cấp hơn, vd như các bạn chưa ai thử viết một mạch lọc bằng MPASM, hoặc viết các đoạn biến đổi số,...

Hãy bắt đầu bằng các thảo luận ở đây nếu các bạn muốn.

Chúc vui.

hungpq
27-02-2007, 02:17 PM
Thực ra ở đây ý của tôi là muốn mọi người cùng xây dựng một hàm ghi số liệu vào bộ nhớ Flash của con 16f877a, để cho mọi người có nhu cầu sử dụng thì có thể lấy về để dùng. Bởi vì tôi nghĩ rằng có nhiều người làm trong lĩnh vực thu thập số liệu và điều khiển phân tán (SCADA), cho nên sẽ cần phải ghi, lưu trữ số liệu. Còn đối với các bài toán dạng như xây dựng các bộ lọc số, biến đổi số... thì có lẽ phải dùng công cụ khác thì mới có hiệu quả hơn.

falleaf
27-02-2007, 04:58 PM
Mình ủng hộ hoạt động này của bạn, mình sẽ dán luồng này lên cao dạng Chú ý để hỗ trợ hoạt động của bạn.

Chúng ta có thể cùng nhau xây dựng từ từ, và F mong rằng hoạt động này sẽ được sự ủng hộ của các thành viên.

Chúc vui

tdm
03-03-2007, 03:38 PM
Ví Dụ Ghi Dọc:
#INCLUDE "P16F877A.INC"
__CONFIG 0x3F72
CBLOCK 0x20
BYTE_CAO
BYTE_THAP
TAM
DU_LIEU
endc
;***************************************
;********* MACRO DEFINITIONS ***********
;***************************************
INCLUDE "BANK.INC"
;***************************************
org 0000
BANK0
MOVLW B'0000010'
MOVWF BYTE_CAO
MOVLW B'00000000'
MOVWF BYTE_THAP
MOVLW B'00000000'
MOVWF DU_LIEU
BANK1
MOVLW .00
MOVWF TRISB
CALL DL
CALL DL
BANK0
MOVF BYTE_CAO,0
BANK2
MOVWF EEADRH
BANK0
MOVF BYTE_THAP,0
BANK2
MOVWF EEADR
LOOP
BANK0
MOVF DU_LIEU,0
BANK2
MOVWF EEDATH
MOVWF EEDATA
BANK3
BSF EECON1,EEPGD
BSF EECON1,WREN
BCF INTCON,GIE
MOVLW 0x55
MOVWF EECON2
MOVLW 0xAA
MOVWF EECON2
BSF EECON1,WR
nop
nop
BCF EECON1,WREN
BANK2
MOVF EEADR,W
ANDLW 0x03
XORLW 0x03
BTFSC STATUS,Z ;
GOTO DOC_DU_LIEU
INCF EEADR,1
BANK0
INCF DU_LIEU,1
GOTO LOOP
DOC_DU_LIEU
LAP_LAI
BANK0
MOVLW .4
MOVWF TAM
BANK2
MOVLW 0xFF
MOVWF EEDATA
BANK0
MOVF BYTE_CAO,0
BANK2
MOVWF EEADRH
BANK0
MOVF BYTE_THAP,0
BANK2
MOVWF EEADR
LAP
BANK3
BSF EECON1,EEPGD
BSF EECON1,RD
NOP
NOP
BCF EECON1,RD
BANK2
MOVF EEDATA,0
BANK0
MOVWF PORTB;XUAT DU LIEU RA PORTB
CALL DL
BANK2
INCF EEADR,1
BANK0
DECFSZ TAM,1
GOTO LAP
GOTO LAP_LAI
;******DL*********
DL
BANK0
CLRF T1CON
CLRF TMR1H
CLRF TMR1H
CLRF INTCON
BANK1
CLRF PIE1
BANK0
CLRF PIR1
MOVLW 0x30 ;1:8
MOVWF T1CON
BSF T1CON,TMR1ON
CHO
BTFSS PIR1,TMR1IF
GOTO CHO
BCF T1CON,TMR1ON
BCF PIR1,TMR1IF
CLRF TMR1H
CLRF TMR1H
RETLW .00
END

hungpq
05-03-2007, 05:15 PM
Dạo này bận quá đã không xây dựng được một hàm ghi dữ liệu vào bộ nhớ FLASH của con 16f877a được để cho các bác cho ý kiến. Bác TDM và các bác thân mến tôi định xây dựng một hàm ghi sao cho về mặt cấu trúc phải rõ ràng, chặt chẽ, code ngắn gọn, tốc độ nhanh, và dễ sử dụng để nhiều người sử dụng được. Đại loại như thế này.
- Các tham số đầu vào của hàm:
+ Dữ liệu cần ghi.
+ Địa chỉ ghi dữ liệu.
+ ................
- Các tham số đầu ra:
+ Kết quả ghi
+ ...............
- Nội dung cơ bản của hàm:
+ Kiểm tra các tham số đầu vào.
+ Ghi dữ liệu.
+ Trả kết quả.
Mong các bác chỉ giúp xem như thế có được chưa, cần bổ sung thêm bớt gì không? Nếu được mong các bác cùng xây dựng giúp? Cám ơn các bác nhiều.

falleaf
05-03-2007, 05:33 PM
Nếu viết thì nên viết dạng gọi hàm. Chúng ta cần thống nhất một số thông số như sau:

Dữ liệu vào: DATATOROM
Địa chỉ ROM: ROMADDR
Tên hàm ghi: SAVETOROM
Dữ liệu ra: ROMTODATA
Tên hàm đọc: READFRROM

Quá trình ghi sẽ được thực hiện như sau:
1) Chọn giá trị ROMADDR
2) Ghi giá trị từ biến bất kỳ vào DATATOROM
3) CALL SAVETOROM

Quá trình đọc sẽ được thực hiện như sau:
1) Chọn giá trị ROMADDR
2) CALL READFRROM (dữ liệu đã nằm trong biến ROMTODATA)
3) Chuyển dữ liệu từ ROMTODATA vào biến cần dùng

F nghĩ, trước tiên cần thực hiện cái việc đơn giản này trước, sau đó, sẽ mở rộng lên, cho phép ghi mảng dữ liệu, và khai báo mảng. Sau đó sẽ mở rộng ra ghi nhiều mảng.

Chúc vui.

namqn
05-03-2007, 05:34 PM
Dạo này bận quá đã không xây dựng được một hàm ghi dữ liệu vào bộ nhớ FLASH của con 16f877a được để cho các bác cho ý kiến. Bác TDM và các bác thân mến tôi định xây dựng một hàm ghi sao cho về mặt cấu trúc phải rõ ràng, chặt chẽ, code ngắn gọn, tốc độ nhanh, và dễ sử dụng để nhiều người sử dụng được. Đại loại như thế này.
- Các tham số đầu vào của hàm:
+ Dữ liệu cần ghi.
+ Địa chỉ ghi dữ liệu.
+ ................
- Các tham số đầu ra:
+ Kết quả ghi
+ ...............
- Nội dung cơ bản của hàm:
+ Kiểm tra các tham số đầu vào.
+ Ghi dữ liệu.
+ Trả kết quả.
Mong các bác chỉ giúp xem như thế có được chưa, cần bổ sung thêm bớt gì không? Nếu được mong các bác cùng xây dựng giúp? Cám ơn các bác nhiều.
Nếu tôi chỉ ghi 1, 2 word thì như thế nào? Có giới hạn gì đối với địa chỉ ghi dữ liệu không?

Thân,

hungpq
06-03-2007, 08:48 AM
Cám ơn các bác đã góp ý. Tôi nghĩ rằng trước tiên chỉ cần xây dựng một hàm ghi thật cơ bản trước sau đó mới thực hiện các hàm tiếp theo. Để xây dựng hàm ghi này cần phải dựa vào đặc điểm bộ nhớ flash của con 16f877a: đó là phải ghi đồng thời liên tiếp 4 Word.
Còn về gợi ý của bác namqn để có thể ghi vào địa chỉ bất kỳ trong vùng bộ nhớ thì hoàn toàn có thể thực hiện được không khó khăn gì lắm. Nhưng tôi nghĩ rằng trước tiên cần xây dựng một hàm ghi thật cơ bản trước đã.

ThieuQP
28-10-2009, 04:40 PM
Nếu tôi chỉ ghi 1, 2 word thì như thế nào? Có giới hạn gì đối với địa chỉ ghi dữ liệu không?

Thân,

Em chào thầy.
Em tìm mãi trên diễn đàn không thấy được hàm nào ghi vào Flash cả, mặc dù nhắc đến khá nhiều.

ThieuQP
28-10-2009, 04:43 PM
Nếu viết thì nên viết dạng gọi hàm. Chúng ta cần thống nhất một số thông số như sau:

Dữ liệu vào: DATATOROM
Địa chỉ ROM: ROMADDR
Tên hàm ghi: SAVETOROM
Dữ liệu ra: ROMTODATA
Tên hàm đọc: READFRROM

Quá trình ghi sẽ được thực hiện như sau:
1) Chọn giá trị ROMADDR
2) Ghi giá trị từ biến bất kỳ vào DATATOROM
3) CALL SAVETOROM

Quá trình đọc sẽ được thực hiện như sau:
1) Chọn giá trị ROMADDR
2) CALL READFRROM (dữ liệu đã nằm trong biến ROMTODATA)
3) Chuyển dữ liệu từ ROMTODATA vào biến cần dùng

F nghĩ, trước tiên cần thực hiện cái việc đơn giản này trước, sau đó, sẽ mở rộng lên, cho phép ghi mảng dữ liệu, và khai báo mảng. Sau đó sẽ mở rộng ra ghi nhiều mảng.

Chúc vui.

Anh ơi cho em hỏi đã ai viết hàm này chưa ạ? em tìm trên diễn đàn mà không có.