PDA

View Full Version : Cho em hỏi về TUT-UART


kien_war
28-06-2007, 07:41 PM
Em đã đọc TUT-UART trên picvietnam nhưng có vài chỗ em còn chưa hiểu.
Sau đây là đoạn chương trình lập trình giap tiếp UART truyền nhận giữa PIC và PC qua RS232:

list p=16f877A
#include <p16f877A.inc>
__CONFIG 0x393A
errorlevel -302

w_temp EQU 0x71
status_temp EQU 0x72
pclath_temp EQU 0x73
ACC EQU 0x74

R2 EQU 0x7A
R3 EQU 0x7B
R4 EQU 0x7C


;************************************************* *********************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program

ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move STATUS register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,W ; move PCLATH register into W register
movwf pclath_temp ; save off contents of PCLATH register

;================================================= ============================
BANKSEL RCREG
MOVF RCREG,W
MOVWF PORTD
MOVWF PORTB ; Chuyen du lieu nhan duoc ra PortB
BANKSEL TXREG ;
MOVWF TXREG ; Chuyen du lieu nguoc lai PC
;================================================= =============================

movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie

main
BANKSEL ADCON1
MOVLW 0x06
MOVWF ADCON1
CALL Init_serialport
BANKSEL TRISB
CLRF TRISB ; Cho dang PORTB la dang out
CLRF TRISD
BSF INTCON,GIE
BSF INTCON,PEIE
GOTO $

Init_serialport ; Module khoi tao cho Serial
BANKSEL TXSTA
BSF TRISC,7 ; Chon chan rb2 la dang in
BCF TRISC,6
MOVLW B'00100100' ; Chon che do 8 bit, Hightbaudrate
MOVWF TXSTA
MOVLW D'25' ; Chon che do 9.600
MOVWF SPBRG
BSF PIE1,RCIE ; Cho phep ngat ( receive )
BANKSEL RCSTA
MOVLW B'10010000' ;
MOVWF RCSTA
RETURN

DELAY255 ; Ham delay
movlw 0xff ; delay 255 mS
D0 movwf R2
D1 movlw 0xC7 ; delay 1mS
movwf R3
movlw 0x01
movwf R4
Delay_0
decfsz R3, f
goto $+2
decfsz R4, f
goto Delay_0

decfsz R2 ,f
goto D1
retlw 0x00

END ; directive 'end of program'


;//////////////////////////////////////

Em có vài điều muốn hỏi:

1. list p=16f877A, __CONFIG 0x393A, errorlevel -302 có ý nghĩa gì
2. Các biến dùng cho pic16F877A nằm trong khoảng từ bao nhiêu 0xab đến bao nhiêu oxcd ?!
3. Khi chạy hết main nó có lệnh: "goto $" ... sau câu lệnh đó nó nhảy đến đâu ?! Có phải là vị trí "ORG 0x004" không ?!
4. Ba câu lệnh sau đây có ý nghĩa gì ?!
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie
5. Hàm delay em đã đọc và hiểu, nhưng em ko thấy nó dùng trong chương trình, vậy viết để làm gì
6. ADCON1 có tác dụng gì ?! Sao lại phải truyền giá trị ox06 cho nó ?!
7. Thanh ghi PCLATH là thanh ghi gì vậy, sao lại phải lưu lại nó ?!
8. Biến ACC em thấy có khai báo nhưng ko được sử dụng ?!
9. Ở hàm Delay255ms có label D0 nhưng em ko thấy sử dụng, và ở TUT-Delay cũng ko có nhãn nằm ở vị trí này ?!

... Nếu có gì ngu dốt mong các anh bỏ qua và giúp đỡ cho em, em cần câu trả lời gấp lắm ạ, thx các anh đã đọc topic này !!!

namqn
28-06-2007, 08:39 PM
Em đã đọc TUT-UART trên picvietnam nhưng có vài chỗ em còn chưa hiểu.
Em có vài điều muốn hỏi:

1. list p=16f877A, __CONFIG 0x393A, errorlevel -302 có ý nghĩa gì
2. Các biến dùng cho pic16F877A nằm trong khoảng từ bao nhiêu 0xab đến bao nhiêu oxcd ?!
3. Khi chạy hết main nó có lệnh: "goto $" ... sau câu lệnh đó nó nhảy đến đâu ?! Có phải là vị trí "ORG 0x004" không ?!
4. Ba câu lệnh sau đây có ý nghĩa gì ?!
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie
5. Hàm delay em đã đọc và hiểu, nhưng em ko thấy nó dùng trong chương trình, vậy viết để làm gì
6. ADCON1 có tác dụng gì ?! Sao lại phải truyền giá trị ox06 cho nó ?!
7. Thanh ghi PCLATH là thanh ghi gì vậy, sao lại phải lưu lại nó ?!
8. Biến ACC em thấy có khai báo nhưng ko được sử dụng ?!
9. Ở hàm Delay255ms có label D0 nhưng em ko thấy sử dụng, và ở TUT-Delay cũng ko có nhãn nằm ở vị trí này ?!

... Nếu có gì ngu dốt mong các anh bỏ qua và giúp đỡ cho em, em cần câu trả lời gấp lắm ạ, thx các anh đã đọc topic này !!!
1. list là directive liệt kê một số tham số dòng lệnh cho trình biên dịch, trong ví dụ này là p=16f877A, cho biết bộ vi điều khiển là PIC16F877A. __CONFIG là directive dùng để thiết lập giá trị của từ cấu hình, trong trường hợp này là 0x393A (xem trong datasheet của chip để biết ý nghĩa của các bit trong từ cấu hình). errorlevel -302 dùng để chặn các thông báo về việc thanh ghi không nằm trong bank 0 (302 Register in operand not in bank 0. Ensure that bank bits are correct), đây chỉ là thông báo nhắc nhở.

2. Trong hình 2-3 của datasheet của PIC16F877A có vẽ vị trí các thanh ghi đặc biệt và các vùng nhớ công dụng chung (thường dùng cho các biến), bạn có thể tham khảo để biết phạm vi địa chỉ có thể dùng cho các biến. Cụ thể, các vùng nhớ sau đây được dành cho các biến: 0x20 - 0x7F, 0xA0 - 0xFF, 0x110 - 0x17F, 0x190 - 0x1FF. Các vùng nhớ này thuộc 4 bank khác nhau, và chú ý là các địa chỉ 0xF0 - 0xFF, 0x170 - 0x17F, và 0x1F0 - 0x1FF được ánh xạ vào vùng 0x70 - 0x7F.

3. Lệnh goto $ là nhảy đến lệnh hiện tại (chính là lệnh goto đó), $ là địa chỉ lệnh hiện tại. Như vậy lệnh này là lệnh lặp vô hạn (cho đến khi chip hết chạy), giống như while (1); trong ngôn ngữ C.

4. Lệnh 1 hoán đổi 2 nibble của w_temp và ghi lại kết quả vào w_temp, còn lệnh 2 hoán đổi 2 nibble của w_temp 1 lần nữa (như vậy có lại w_temp ban đầu) và ghi kết quả vào W. Sau hai lệnh này thì nội dung của w_temp được copy vào W mà không làm thay đổi các cờ trạng thái. Lệnh 3 dùng để thoát khỏi chương trình xử lý ngắt, tiếp tục thực thi lệnh nằm ngay sau lệnh đã bị ngắt ở vị trí nào đó trong chương trình.

5., 8. và 9. Những gì được khai báo nhưng không dùng trong chương trình thì không có vấn đề, chỉ có những gì được dùng trong chương trình nhưng không hề được khai báo thì mới gây lỗi biên dịch. Có khả năng người viết thay đổi ý định khi viết chương trình, dẫn đến một số biến, chương trình con, nhãn đã khai báo nhưng không cần thiết nữa.

6. Thanh ghi ADCON1 dùng để thiết lập một số chức năng cho module ADC của PIC, tuy nhiên, nó cũng quyết định các chân vừa là analog vừa là digital nào của PIC sẽ được dùng như chân analog hay digital. Do đó, dù tutorial này không dùng module ADC, nhưng các chân của PORTA cần được thiết lập là chân digital bằng cách đặt 4 bit thấp nhất của thanh ghi ADCON1 là 0x6 hay 0x7.

7. Thanh ghi PCLATH là thanh ghi chốt byte cao của thanh ghi đếm chương trình PC, thanh ghi này cần được lưu lại để chương trình xử lý ngắt có thể trở về đúng chỗ đã bị ngắt, có thể nằm ở các trang chương trình khác với trang chứa đoạn code xử lý ngắt.

Thân,

kien_war
28-06-2007, 08:53 PM
oa oa .. cam on bac' namqn nhieu !!!!!!!!!

kien_war
28-06-2007, 09:05 PM
Anh ơi cho em hỏi thêm cái nữa là:
1.Tại sao lại có lệnh CLRF PORTD (nằm trong hàm main) ... trong đây ta đâu đụng gì đến cổng D của 16F877A ?!
2.
MOVF RCREG,W
MOVWF PORTD
Trong ngắt có 2 lệnh này, thật ra là dư thừa vì trong mạch test ta ko có kết nối LED vào PortD !
3. Em sửa lại như vầy có được ko ạ:

list p=16f877A
#include <p16f877A.inc>
__CONFIG 0x393A
errorlevel -302

w_temp EQU 0x71
status_temp EQU 0x72
pclath_temp EQU 0x73

;************************************************* *********************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program

ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move STATUS register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,W ; move PCLATH register into W register
movwf pclath_temp ; save off contents of PCLATH register

;================================================= ============================
BANKSEL RCREG
MOVF RCREG,W
MOVWF PORTB ; Chuyen du lieu nhan duoc ra PortB
BANKSEL TXREG ;
MOVWF TXREG ; Chuyen du lieu nguoc lai PC
;================================================= =============================

movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie

main
BANKSEL ADCON1
MOVLW 0x06
MOVWF ADCON1
CALL Init_serialport
BANKSEL TRISB
CLRF TRISB ; Cho dang PORTB la dang out
BSF INTCON,GIE
BSF INTCON,PEIE
GOTO $

Init_serialport ; Module khoi tao cho Serial
BANKSEL TXSTA
BSF TRISC,7 ; Chon chan rb2 la dang in
BCF TRISC,6
MOVLW B'00100100' ; Chon che do 8 bit, Hightbaudrate
MOVWF TXSTA
MOVLW D'25' ; Chon che do 9.600
MOVWF SPBRG
BSF PIE1,RCIE ; Cho phep ngat ( receive )
BANKSEL RCSTA
MOVLW B'10010000' ;
MOVWF RCSTA
RETURN

END ; directive 'end of program'

namqn
28-06-2007, 10:22 PM
Theo tôi thì người viết có ý định xuất dữ liệu ra cả PORTD lẫn PORTB để có thể sử dụng một trong hai port này tùy theo phần cứng hiện có. Việc có thừa một lệnh xuất ra port B không làm ảnh hưởng gì đến mục tiêu của tutorial, là tìm cách sử dụng USART của PIC16F877A. Code sửa lại của bạn là ok.

Thân,

kien_war
29-06-2007, 02:28 AM
Thật sự là em gà mờ quá, sợ nhỡ thêm vào portD thì chương trình nó mới chạy được, vì em cũng mới biết VXL mà ^^ ... Các anh đọc thì thông cảm cho em nhé!!!
Không biết phải hỏi ... đúng ko các anh ^^ (thx anh namqn nhiều nhiều !!!)

kien_war
01-07-2007, 11:29 PM
Em có thêm 1 vấn đề cần hỏi:

Khi chưa gởi tín hiệu qua RS232 ... pic vừa được nạp điện thì đèn sẽ sáng 1 cách bất kì (có khi sáng hết 8 bóng, có khi 2-3 bóng) !
Có cách nào làm cho đèn ko sáng cho đến khi pic nhận được tín hiệu từ PC ko ?!

namqn
02-07-2007, 12:34 AM
Em có thêm 1 vấn đề cần hỏi:

Khi chưa gởi tín hiệu qua RS232 ... pic vừa được nạp điện thì đèn sẽ sáng 1 cách bất kì (có khi sáng hết 8 bóng, có khi 2-3 bóng) !
Có cách nào làm cho đèn ko sáng cho đến khi pic nhận được tín hiệu từ PC ko ?!
Tất nhiên là có. Trong chương trình chính, dùng 1 lệnh đặt trạng thái ban đầu cho PORT nối với LED, ở bất kỳ vị trí nào miễn là nằm trước lệnh GOTO $ (chương trình chính của bạn là từ nhãn main đến lệnh GOTO $).

Thân,

kien_war
04-07-2007, 09:40 AM
Em hiểu rồi, cảm ơn anh ^^