PDA

View Full Version : thắc mắc


wave_zx
22-01-2008, 12:33 AM
;************************************************* ***************************************
PROCESSOR P16F877A
INCLUDE <P16F877A.inc>
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC & _LVP_OFF &_BODEN_OFF
;************************************************* ***************************************
ORG 0X20
COUNT1 EQU 0X20
COUNT2 EQU 0X21
COUNT3 EQU 0X22
;************************************************* ***************************************
ORG 0X0000
GOTO MAIN
; ORG 0X0004
; GOTO INTERRUPT
;************************************************* ****************************************
ORG 0X0005
MAIN
BCF STATUS,RP1
BSF STATUS,RP0 ;BANK1
CLRF TRISC ;PORTC IS OUTPUT
BCF STATUS,RP0 ;BANK0
CLRF PORTC
GOTO C0
C0
BSF PORTC,0
CALL DELAY_LONG
BCF PORTC,0
CALL DELAY_LONG
C1
BSF PORTC,1
CALL DELAY_LONG
C2
BSF PORTC,2
CALL DELAY_LONG
BCF PORTC,2
CALL DELAY_LONG
GOTO C0

;************************************************* ****************************************
DELAY_LONG
MOVLW D'5'
MOVWF COUNT3
DELAY_LONG_START
DECFSZ COUNT3,F
GOTO $+2
RETURN
CALL DELAY
GOTO DELAY_LONG_START
;************************************************* *****************************
DELAY
MOVLW D'255'
MOVWF COUNT1
LOOP1
MOVLW D'255'
MOVWF COUNT2
DECFSZ COUNT1,F
GOTO LOOP2
RETURN
LOOP2
DECFSZ COUNT2,F
GOTO LOOP2
GOTO LOOP1

END


ĐOẠN CODE TRÊN EM VIẾT THỬ CHO PORTC, EM THẮC MẮC LÀ TẠI SAO BIT1 NÓ SÁNG RỒI TẮT.NHỜ MỌI NGƯỜI CHỈ HỘ.CẢM ƠN NHIỀU.

namqn
22-01-2008, 01:51 AM
Bạn chú thích các lệnh từ nhãn C2 đến lệnh GOTO C0 như sau:
C2
; BSF PORTC,2
; CALL DELAY_LONG
; BCF PORTC,2
; CALL DELAY_LONG
GOTO C0
xem chuyện gì xảy ra.

Thân,

wave_zx
22-01-2008, 09:38 AM
Em đã Thử Rồi ạh. Bit1 Vẫn. Cứ Sáng Rồi Tắt.nếu Thử Bit Khác Của Portc Nó Cũng Thế.?

namqn
22-01-2008, 07:50 PM
À, tôi quên. Chương trình lại chạy lại từ C0, nên vẫn bị ảnh hưởng của các lệnh bật tắt RC0. Bạn sửa lại như sau và thử lại xem.
C2
; BSF PORTC,2
; CALL DELAY_LONG
; BCF PORTC,2
; CALL DELAY_LONG
GOTO C2
Thân,

wave_zx
23-01-2008, 08:05 AM
Nếu Ghi Chú Thích Như đoạn Anh Nói Thì Bit1 Sẽ Sáng Hoài.nhưng Nói Như Vậy Nghĩa Là Các Bit Của Portc Ko độc Lập Với Nhau.cứ Tác động Bit Này Là ảnh Hưởng Bit Kia A.em Thử Porta Cũng Thế. Còn Portb Thì Ko Bị ảnh Hưởng.liệu Có Cách Nào để Bật Tắt Các Bit Portc độc Lập Ko ạ.mong Các Anh Giúp đỡ. :)

namqn
23-01-2008, 08:06 PM
Nếu Ghi Chú Thích Như đoạn Anh Nói Thì Bit1 Sẽ Sáng Hoài.nhưng Nói Như Vậy Nghĩa Là Các Bit Của Portc Ko độc Lập Với Nhau.cứ Tác động Bit Này Là ảnh Hưởng Bit Kia A.em Thử Porta Cũng Thế. Còn Portb Thì Ko Bị ảnh Hưởng.liệu Có Cách Nào để Bật Tắt Các Bit Portc độc Lập Ko ạ.mong Các Anh Giúp đỡ. :)
Bạn đang gặp vấn đề liên quan đến hoạt động read-modify-write. Vì bạn mới bắt đầu học PIC (tôi đoán như vậy), bạn có thể chưa cần tìm hiểu sâu về nó. Cách đơn giản nhất để bật tắt các bit của các port ngõ ra một cách độc lập là dùng một ô nhớ 8-bit trung gian làm ảnh trạng thái của port ngõ ra, sau đó thao tác các bit của ô nhớ đó, rồi ghi ô nhớ đó ra port ngõ ra.

Sau đó, nếu bạn muốn tìm hiểu thêm về hoạt động read-modify-write, bạn có thể tìm đọc trên diễn đàn (ở đây chẳng hạn: http://www.picvietnam.com/forum//showthread.php?p=8949, post #68), hay đọc datasheet của PIC (dùng chức năng tìm kiếm của phần mềm để tìm cụm từ 'read-modify-write').

Thân,

wave_zx
26-01-2008, 11:30 AM
sao mà sử dụng con pic6f877a này khác nhiều so với con pic6f84a quá. em xem về cấu trúc port của 2 con cũng gần giống nhau.em nghĩ thì việc đưa chân output ra mức cao ko có gì khó, thế mà giờ nó rối quá.:((.ko biết có ai gặp trường hợp như em ko. việc I/0 mà cũng fải dùng đến thanh gi khác làm ảnh thì rắc rối wá.
về read-modify-write ,theo em hiểu thì thanh gi được đọc, rồi chỉnh sửa , rồi ghi lại.viêc đọc được thực hiện ngay cả khi lệnh là 1 lệnh gi vào.chẳng lẽ có bước nào đã chạy sai trong 3 bước trên.

wave_zx
26-01-2008, 11:48 AM
Không đúng vậy đâu newuser, mặc định là ghi vào thanh ghi f. Vấn đề ở đây là hoạt động read-modify-write của các lệnh thao tác dữ liệu như COMF, BSF chẳng hạn. Lấy ví dụ, khi dùng lệnh COMF PORTA, PIC sẽ đọc trạng thái từ PORTA trước, lấy bù giá trị đó, và xuất ra PORTA. Do đó nếu dùng PORTA nối vào các LED đã được nối theo kiểu anode chung (nghĩa là PORTA xuất 0x00 để làm cho tất cả các LED sáng) thì khi đó PIC đọc vào sẽ được 0xFF, và sau đó COMF sẽ có 0x00, các LED sẽ sáng. Đến lần chạy lênh COMF kế tiếp thì tình trạng vẫn diễn ra như vậy, khiến chúng ta nghĩ rằng lệnh không tác động lên PORTA được.

Vấn đề sẽ không xảy ra nếu bạn dùng một ô nhớ để lưu trạng thái của PORTA, khi đó bạn sẽ thao tác trạng thái của PORTA thông qua biến trung gian, và không bị ảnh hưởng của hoạt động read-modify-write (vì ô nhớ không bị ảnh hưởng của hoạt động này).

Bạn newuser viết nhầm chỗ thanh ghi TRISA luôn, để PORTA là các ngõ ra thì phải đặt TRISA = 0x00.

Thân,
__________________
Biển học mênh mông, sức người có hạn.


theo như bài trên thì khi porta đã xuất ra là 0x00 thì đèn sẽ sáng. như vậy lúc này giá trị ở porta là 0x00 rồi, thế nhưng tại sao việc đọc lại sẽ là 0xff được ạ.port đã được định nghĩa là output rồi thì tại sao khi đọc lại lấy giá trị từ ngoài truyền vào.
Mong anh giải thích giùm em.cảm ơn anh đã trả lời.

namqn
27-01-2008, 02:23 AM
theo như bài trên thì khi porta đã xuất ra là 0x00 thì đèn sẽ sáng. như vậy lúc này giá trị ở porta là 0x00 rồi, thế nhưng tại sao việc đọc lại sẽ là 0xff được ạ.port đã được định nghĩa là output rồi thì tại sao khi đọc lại lấy giá trị từ ngoài truyền vào.
Mong anh giải thích giùm em.cảm ơn anh đã trả lời.
Đọc thanh ghi PORTx luôn luôn đọc giá trị ở chân I/O của PIC (nếu như đã thiết lập đúng chế độ làm việc cho port đó). Ví dụ ở trên của tôi chỉ là 1 trong những khả năng có thể xảy ra (xuất 0x00 ra PORTA rồi COMF PORTA ngay sau đó, với tần số thực thi lệnh rất cao). Giải thích như sau: giả sử trước đó PORTA là 0xFF, sau đó lệnh xuất 0x00 ra PORTA được thực thi, rồi lệnh COMF PORTA được thực thi. Nhưng vì tần số thực thi lệnh rất cao, và chân I/O cũng như mạch ngoài nối vào có một điện dung nhất định, nên khi xuất 0x00 ra PORTA thì bộ đệm ra của PIC đang kéo chân I/O từ mức Vdd về 0V, trong khi đó lệnh COMF PORTA đã được thực thi tiếp đó. Lệnh COMF này sẽ đọc trạng thái của các chân I/O của PORTA, lúc này vẫn chưa giảm về 0 V, và có thể được hiểu là mức '1', tức là PORTA có thể được đọc về là 0xFF, sau đó lệnh COMF sẽ lấy complement của giá trị 0xFF, rồi ghi ra thanh ghi đệm ngõ ra của PORTA, tức là ghi 0x00. Dẫn đến kết quả thực thi lệnh COMF PORTA vẫn là xuất 0x00 ra PORTA. Cho nên mới có nhận định của bạn leduy173 rằng lệnh COMF PORTA có vẻ không thay đổi được trạng thái của PORTA. Đây chỉ là một trong những khả năng có thể xảy ra thôi.

Tóm lại, với các PIC16 (PIC12, và PIC10), hãy dùng một ô nhớ trung gian khi muốn thao tác trạng thái của thanh ghi PORTx.

Thân,

xhieu1908
17-05-2009, 12:04 PM
search thấy có thắc mắc như mình nhg mình vẫn chưa hiểu nên đành đào mộ cổ vậy
;RA0-3 - output
;RA0-3 noi voi LED
;LED dau K chung - GND
include <p16f628.inc>
__config h'3fe6'
org 0x0
goto init
init
bsf STATUS, RP0
movlw h'f0'
movwf TRISA
bcf OPTION_REG, PS1 ;WDT 1:64, khoang nua giay se reset
bcf STATUS, RP0
bsf PORTA, 0
loop
nop
bsf PORTA, 1
nop
sleep
nop
bsf PORTA, 2
nop
sleep
nop
bsf PORTA, 3
nop
sleep
nop
clrf PORTA
nop
goto loop
end

mình thấy khi debug thì mọi chuyện suôn sẻ, nhg khi lắp vào mạch thật thì lại xay ra hiện tượng là khi bật được LED này thì LED trước tắt. Ai giải thích giùm mình với!!