PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Học PIC trong 1 ngày (Upd. 01/01/2006) (http://www.picvietnam.com/forum/showthread.php?t=5)

newuser 24-05-2006 12:27 PM

đúng thế đấy bạn, nếu bạn xuất led mà không có dòng CLRF PORTx là thấy chạy sai liền, Protues mô phỏng y chang...

falleaf 30-05-2006 04:00 PM

Từ hôm nay, F cắt các bài trong phần Học PIC trong 1 ngày ra thành Thảo luận xung quanh Học PIC trong 1 ngày, lý do rằng một số bài đi lan man, và cứ nhấn tới các câu hỏi.

Trong luồng này, chỉ lưu các tutorial của picvietnam, nhưng câu hỏi và trả lời liên quan đến bài học, nhằm giúp đỡ những người mới học tham gia và đọc một cách dễ dàng nhất.

Vì vậy, khi quyết định viết bài vào luồng này, các bạn phải thật cân nhắc, nếu không bài của các bạn sẽ bị di chuyển sang luồng khác.

http://www.picvietnam.com/forum/showthread.php?t=446

Liên quan đến bài học là thế nào? Là bạn đọc bài học ở đây, làm theo và có thắc mắc, hoặc là bạn có viết thêm các tutorial để bổ sung vào luồng này cho người học có thêm tài liệu phong phú. Nếu không phải là một trong hai trường hợp này, đề nghị các bạn không viết bài vào luồng này, để tránh các thành viên mới rất khó kiếm bài và rất khó hệ thống tài liệu học.

Chúc vui.

dtnbk 05-07-2006 12:46 AM

Sao Em Download File Tập Lệnh Về Lại Ko Thể Mở Xem Duoc Vậy Nhỉ.
Nó Cứ Bảo File Damaged And Could Not Repair....

falleaf 05-07-2006 01:42 AM

Nhiều người download thành công, và F cũng kiểm tra lại rồi, mọi thứ ok. Có thể đường truyền ở Việt Nam có vấn đề, cho nên đôi khi download giữa chừng nó bị hỏng, và dẫn tới file down về bị hư.

Chúc vui

friends 04-08-2006 09:36 AM

Interrupt
 
Cac anh cho em hoi, khi dung chuong trinh ngat theo mau nhu ben duoi ,thi co can khai bao cac vung ram ben duoi khong

Vi du: co can khai bao nhu the nay khong?

…………….

Org 0x20
W_SAVE
STAT_SV
PCH_SV
FSR_SV
ORG 0X0000
…………………..

;DAY LA CHUONG TRINH NGAT THEO MAU
;================================================= ===========================================
INTERRUPT

;-------------------------------------------
;Doan ma bat buoc de vao ngat
;-------------------------------------------

MOVWF W_SAVE ;W_SAVE(bank unknown!) = W
SWAPF STATUS, W
CLRF STATUS ; force bank 0 for remainder of handler
MOVWF STAT_SV ; STAT_SV = swap_nibbles( STATUS )
; STATUS = 0
MOVF PCLATH, W
MOVWF PCH_SV ; PCH_SV = PCLATH
CLRF PCLATH ; PCLATH = 0
MOVF FSR, W
MOVWF FSR_SV ; FSR_SV = FSR
; 10 cycles from interrupt to here!

;-----------------------------------
;Doan chuong trinh ngat
;-----------------------------------

; cac ban se viet chuong trinh ngat o day

;--------------------------------------------------
;Doan ma bat buoc de ket thuc ngat
;--------------------------------------------------

MOVF FSR_SV, W
MOVWF FSR ; FSR = FSR_SV
MOVF PCH_SV, W
MOVWF PCLATH ; PCLATH = PCH_SV
SWAPF STAT_SV, W
MOVWF STATUS ; STATUS = swap_nibbles( STAT_SV )
SWAPF W_SAVE, F
SWAPF W_SAVE, W ; W = swap(swap( W_SAVE )) (no change Z bit)

BSF INTCON, GIE
RETFIE
;================================================= ==================================================

newuser 04-08-2006 08:29 PM

chắc chắn là cần lưu giữ giá trị các thanh ghi W, STATUS và PCLATH nếu bạn muốn chương trình chạy đúng sau khi trở về từ ngắt. Cách khai báo hình như không đúng...mình thường viết như thế này:
W_TEMP EQU 0X20
STATUS_TEMP EQU 0X21
PCLATH_TEMP EQU 0X22

riêng FSR có cần lưu trữ nó không nhỉ?

namqn 04-08-2006 08:46 PM

Trích:

Nguyên văn bởi newuser
chắc chắn là cần lưu giữ giá trị các thanh ghi W, STATUS và PCLATH nếu bạn muốn chương trình chạy đúng sau khi trở về từ ngắt. Cách khai báo hình như không đúng...mình thường viết như thế này:
W_TEMP EQU 0X20
STATUS_TEMP EQU 0X21
PCLATH EQU 0X22

riêng FSR có cần lưu trữ nó không nhỉ?

Cách khai báo địa chỉ biến của bạn friends vẫn dịch ra đúng, mặc dù cách dùng không hay lắm, nên dùng cblock ... endc thì tốt hơn.

Còn cách định nghĩa hằng của em:
Code:

PCLATH EQU 0X22
liệu có hợp lệ hay không?

Thân,

newuser 04-08-2006 09:03 PM

ủa, thôi chết, em viết thiếu, đại loại phải như vầy (đúng là nhanh nhảu đoảng... hic)
PCLATH_TEMP EQU 0X22

cách khai báo như bạn friend vẫn đúng? anh có thể giải thích rõ hơn không?

namqn 04-08-2006 09:45 PM

À, anh xem lướt qua nên không phát hiện lỗi ở lần đầu.

Phần khai báo của bạn friends dịch không có lỗi, nhưng chạy chương trình sẽ bị sai (vì các địa chỉ biến được đặt không đúng). Toàn bộ 4 biến đó đều sẽ có địa chi 0x20. Bạn friends cần phải chỉnh lại như sau thì mới có chương trình đúng:
Code:

Org 0x20
W_SAVE res 1
STAT_SV res 1
PCH_SV res 1
FSR_SV res 1
ORG 0X0000

Giải thích thêm về phần này. Directive org chỉ làm thay đổi bộ đếm địa chỉ của trình hợp dịch. Với đoạn code như trên, chúng ta sẽ có W_SAVE là nhãn ở địa chỉ 0x20, STAT_SV là nhãn ở địa chỉ 0x21, và cứ thế. Từ khóa res và giá trị 1 sẽ làm bộ đếm địa chỉ tăng 1 đơn vị. Cách này không hay vì các địa chỉ biến thực chất là địa chỉ của các nhãn được hiểu là sẽ được dùng làm đích của các lệnh chuyển điều khiển (hay nói cách khác chúng là các địa chỉ của các từ lệnh), nếu dùng chúng trong các PIC18 chẳng hạn thì sẽ bị sai (vì các từ lệnh cách nhau 2 byte, và PIC18 dùng địa chỉ byte).

Thân,

vudinhlieu 10-08-2006 03:54 PM

Chào bang chủ ,đệ tử nhập môn thật vất vả để viết chương trình đầu tiên !
thứ 1 : vì chưa biết gì về MPLAB thế nên sau khi cài đặt đọc mãi hướng dẫn sử dụng mới có thể làm được mong bang chủ thêm phần hướng dẫn cơ bản sử dụng MPLAB trong 1 ngày học PIC
thứ 2 : Ngay trong bài tập đầu tiên Bang chủ đã gài pan thêm dấu . kế lệnh END làm trình dịch báo lổi mà ko biết mò đâu mà sửa ! dù sao thì đệ cũng đã làm được bài tập đầu tiên !

namqn 10-08-2006 06:38 PM

Trích:

Nguyên văn bởi vudinhlieu
Chào bang chủ ,đệ tử nhập môn thật vất vả để viết chương trình đầu tiên !
thứ 1 : vì chưa biết gì về MPLAB thế nên sau khi cài đặt đọc mãi hướng dẫn sử dụng mới có thể làm được mong bang chủ thêm phần hướng dẫn cơ bản sử dụng MPLAB trong 1 ngày học PIC
thứ 2 : Ngay trong bài tập đầu tiên Bang chủ đã gài pan thêm dấu . kế lệnh END làm trình dịch báo lổi mà ko biết mò đâu mà sửa ! dù sao thì đệ cũng đã làm được bài tập đầu tiên !

Về thứ 1: Cá nhân tôi không nghĩ rằng mình có thể sử dụng ngay một phần mềm mới ngay sau khi cài đặt, ít nhất tôi cũng phải đọc qua các tutorial của phần mềm (nếu có), và sau đó là hướng dẫn sử dụng. Ngoài ra, ít nhất là đâu đó trong diễn đàn này đã có các hướng dẫn về MPLAB, chẳng hạn như luồng này:
http://www.picvietnam.com/forum/showthread.php?t=354

Về thứ 2: đó chưa hẳn là một pan được gài, MPLAB đã trải qua nhiều lần nâng cấp kể từ khi chú F viết bài tập đó, đến nay thì directive END được dùng cho các chương trình hợp ngữ dành cho các vi điều khiển 8-bit (PIC10, PIC12, PIC16 và PIC18, nhưng directive .END vẫn được dùng cho các chương trình hợp ngữ dành cho các vi điều khiển và DSC 16-bit (PIC24, dsPIC30, dsPIC33).

Thân,

vudinhlieu 12-08-2006 07:06 PM

Vì quá kém cỏi đành xin trưởng lão thọ giáo thêm chút nữa !
vì sao chương trình này em viết dịch bị lỗi !

Code:

;====================================
; bai tap 2
; mach den chop 8 led tu trai qua phai
;ngay bat dau :12/08/2006
;nguoi thuc hien : vu dinh lieu
;mo ta phan cung : Dung PIC16F628A - thach anh 4MHz
;                : LED giao tiep voi PORTB
;                : Cuc am cua LED noi voi GND
;                : RB0 - RB7 la cac chan output
; Chu thich        :
; dùng thanh ghi W ghi vào giá tri 00000001
; xuat ra PORTB
; delay
; dùng lenh dich trai portB 
; xuat ra PORTB                                                      15
;====================================================================
                TITLE                "Mach chop 8 LED_1"
                PROCESSOR        P16F628A
                INCLUDE        <P16F628A.inc>
                __CONFIG          _CP_OFF        & _PWRTE_ON & _WDT_OFF &_HS_OSC

;=======================================================
count1 EQU 0x20 ; cac bien dung cho doan chuong trinh delay
counta EQU 0x21
countb EQU 0x22
;===============================================================================
                ORG        0x0000
                GOTO        MAIN
                ORG        0x0005
MAIN                                                             
                BANKSEL        TRISB                ; bank select
                CLRF        TRISB                ; trisb = 00000000
; portb = output
LOOP
                BANKSEL        PORTB
                MOVLW        0x01
                MOVWF        PORTB                ; rb = 00000001
                CALL        delay_100ms
                RLF                PORTB,f
                GOTO        LOOP
                GOTO                $                ; dung chuong trinh tai day
                                                ; vong lap tai cho^~
                                                ; khong bao gio ket thuc
delay_100ms ; label bat dau chuong trinh con
                MOVLW d'100' ; doan code cho chuong trinh con delay 100 ms
                MOVWF count1
d1
                MOVLW d'199'
                MOVWF counta
                MOVLW d'1'                             
                MOVWF countb
delay_0
                DECFSZ        counta,f
                GOTO        $+2
                DECFSZ        countb,f
                GOTO        delay_0
                DECFSZ        count1,f
                GOTO        d1 
                RETURN       
                END

và các lỗi nhận cược nhu sau
Make: The target "E:\pic1\baitap2.o" is out of date.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPAsmWin.exe" /q /p16F628A "baitap2.asm" /l"baitap2.lst" /e"baitap2.err" /o"baitap2.o"
Warning[215] E:\PIC1\BAITAP2.ASM 18 : Processor superseded by command line. Verify processor symbol.
Message[302] E:\PIC1\BAITAP2.ASM 32 : Register in operand not in bank 0. Ensure that bank bits are correct.
Error[113] E:\PIC1\BAITAP2.ASM 54 : Symbol not previously defined ( )
Error[112] E:\PIC1\BAITAP2.ASM 54 : Missing operator
Error[113] E:\PIC1\BAITAP2.ASM 57 : Symbol not previously defined (f )
Error[113] E:\PIC1\BAITAP2.ASM 58 : Symbol not previously defined (d1 )
Halting build on first failure as requested.
BUILD FAILED: Sat Aug 12 18:02:25 2006

namqn 12-08-2006 09:41 PM

Chương trình này không có lỗi cú pháp, tất nhiên cái warning về bộ xử lý do MPLAB chọn tại dòng lệnh và cái message về thanh ghi không nằm trong bank 0 là hợp lý. Tôi cho là bạn đang gặp khó khăn trong việc biên dịch chương trình. Nhân tiện bạn cho biết bạn đang dùng MPLAB phiên bản nào.

Với các bản MPLAB IDE mới, cách đơn giản để bạn biên dịch chương trình chỉ gồm 1 tập tin .asm là chọn loại bộ xử lý cho đúng trong mênu "Configure", lệnh "Select Device ...", sau đó bạn chọn trong mênu "Project" lệnh "Quickbuild <tentaptin.asm>", với <tentaptin.asm> là tập tin .asm mà bạn đang soạn thảo (nó đã được mở ra và đang active).

Thân,

BVT_BK 13-08-2006 03:28 PM

O Day Cac Bac Noi Ve Cach Dung Pic Co Ban Nhat
Nhung Nhung Ung Dung Khac Thi Chua Thay Cac Bac De Cap Nhieu
Hi Vong Cac Bac Post Them Nhieu De Anh Em Ta Cung Hoc Nhanh Hon
Vi Du Nhu Timer0, 1, 2
Truyen Thong Du Lieu
Pwm...
Thank You

BVT_BK 13-08-2006 03:31 PM

Cac Bac Toan Viet Delay Nho Decfsz A
Cai Lay Dung Cung Duoc
Nhung Ma Thoi Gian De Lay Khong Chinh Xac Lam
Em Thu Dung Timer0 Cua 16f877a De Tao Tre
Nhung Ma Tim Mai Khong Thay Lenh Khoi Dong Timer0 Dau
Bac Nao Viet Chuong Trinh Tao Tre Nho Timer0 Thi Chi Cho Em Voi
Hinh Nhu Voi Con Pic877a No Tu Khoi Dong Timer0 Hay Sao Day
Bac Nao Ro Thi Giup Em Voi
Thank You!

vudinhlieu 14-08-2006 04:47 PM

rất cám ơn trưởng lão !

tinhthanthep 16-08-2006 11:29 AM

Nếu mẫu khai báo biến như faleaf trình bày bên trên không tối ưu thì mong bác namp viết lại cho chuẩn. Đây là mẫu khai báo biến của faleaf:
;================================================= ========
; KHAI BAO BIEN
;--------------
; Bien nam o bank 0
;----------------------------------------------------------------------
ORG 0x020
COUNT_L RES 1
COUNT_H RES 3
;----------------------------------------------------------------------
; BiEn NAM O bank 1
;----------------------------------------------------------------------
ORG 0x0A0
COUNT1_L RES 1
;----------------------------------------------------------------------
; Bien nam o bank 2
;----------------------------------------------------------------------
ORG 0x120
;================================================= =======
2. Trong chuong trình ngắt theo tôi chỉ cần lưu giá trị của thanh ghi W và STATUS vì thanh ghi PC đã được lưu trong stack. Đồng thời trong quá trình xử lý 1 ngắt thì bit toàn cục GIE đã bị clear nên sẽ không có ngắt nào khác hoạt động được nữa lên không sợ tràn stack.
3. Ở cuối chuong trình ngắt không cần phải set bit GIE vì khi ra khỏi chương trình ngắt thì bit GIE tự động được set lên. Chỉ phải clear flag trước khi ra khỏi chương trình ngắt.

newuser 16-08-2006 11:52 AM

Trích:

Nguyên văn bởi tinhthanthep
2. Trong chuong trình ngắt theo tôi chỉ cần lưu giá trị của thanh ghi W và STATUS vì thanh ghi PC đã được lưu trong stack. Đồng thời trong quá trình xử lý 1 ngắt thì bit toàn cục GIE đã bị clear nên sẽ không có ngắt nào khác hoạt động được nữa lên không sợ tràn stack.

Đồng ý với tinhthanthep ở những điểm còn lại trừ điểm trên, theo tôi thì phải lưu giữ cả thanh ghi PCLATH, theo datasheet của P16F877A nói là PCLATH sẽ không bị thay đổi giá trị ngay sau lệnh RETFIE, giả sử chương trình ngắt của bạn đặt tại Page2, vậy thì khi trở về từ ngắt, liệu có đảm bảo chương trình của bạn sẽ chạy đúng???
vì thế không cần lưu trữ giá trị thanh ghi PCLATH chỉ chính xác với những dòng PIC có bộ nhớ chương trình <=2K (2^11=2048 địa chỉ).

tinhthanthep 16-08-2006 02:59 PM

Các bác cho hỏi trong khi thực hiện chương trình ngắt ta thường lưu giá trị các thanh ghi W và status vào địa chỉ 0x70, 0x71.... Mấy cái địa chỉ này nằm ở bank 0. Nhưng nếu khi vào chương trình ngắt mà ta đang ở bank 1 thì sao nhỉ? Theo tôi hiểu là trước khi lưu giá trị thanh ghi W và STATUS ta phải chuyển về bank 0 trước đúng không? nhưng tôi thấy các chương trình ngắt viết mẫu đều không thấy làm điều này? Hình như nó tự động hiểu được à? Các bác có thể giải thích cái địa chỉ ghi tạm giá trị thanh ghi W, status được không?

tinhthanthep 16-08-2006 04:27 PM

Tiện thể hỏi thêm một câu nữa: để chuyển giá trị các thanh ghi đặc biệt vào các thanh ghi lưu trữ thì chỉ cần dùng các lệnh mov là được sao thấy trong tài liệu hướng dẫn và cũng thấy một số bạn trên này hay dùng lệnh swapf?

namqn 16-08-2006 08:28 PM

Trích:

Nguyên văn bởi tinhthanthep
Tiện thể hỏi thêm một câu nữa: để chuyển giá trị các thanh ghi đặc biệt vào các thanh ghi lưu trữ thì chỉ cần dùng các lệnh mov là được sao thấy trong tài liệu hướng dẫn và cũng thấy một số bạn trên này hay dùng lệnh swapf?

Lệnh swapf không làm thay đổi cờ Z, còn lệnh movf thì làm thay đổi cờ Z. Nếu trước đó bạn đã phục hồi thanh ghi STATUS, sau đó bạn phục hồi thanh ghi khác bằng lệnh movf thì cờ Z có thể bị đổi trạng thái, lúc đó có phải việc phục hồi thanh ghi STATUS trở thành công cốc hay không?

Thân,

namqn 16-08-2006 08:48 PM

Trích:

Nguyên văn bởi tinhthanthep
Các bác cho hỏi trong khi thực hiện chương trình ngắt ta thường lưu giá trị các thanh ghi W và status vào địa chỉ 0x70, 0x71.... Mấy cái địa chỉ này nằm ở bank 0. Nhưng nếu khi vào chương trình ngắt mà ta đang ở bank 1 thì sao nhỉ? Theo tôi hiểu là trước khi lưu giá trị thanh ghi W và STATUS ta phải chuyển về bank 0 trước đúng không? nhưng tôi thấy các chương trình ngắt viết mẫu đều không thấy làm điều này? Hình như nó tự động hiểu được à? Các bác có thể giải thích cái địa chỉ ghi tạm giá trị thanh ghi W, status được không?

Tôi dịch phần hướng dẫn của Microchip về lưu ngữ cảnh khi ngắt (lấy từ datasheet của PIC16F87xA):

Trích:

Khi xử lý ngắt, chỉ có giá trị trở về của PC được lưu vào ngăn xếp. Thông thường, người dùng có thể muốn lưu các thanh ghi chính khi xử lý ngắt (nghĩa là thanh ghi W và thanh ghi STATUS). Điều này phải được thực hiện bằng phần mềm.

Với các chip PIC16F873A/874A, thanh ghi W_TEMP phải được định nghĩa trong cả bank 0 lẫn bank 1 và phải được định nghĩa ở cùng offset từ địa chỉ nền của bank (nghĩa là, nếu W_TEMP được định nghĩa tại 0x20 trong bank 0, nó cũng phải được định nghĩa tại 0xA0 trong bank 1). Các thanh ghi PCLATH_TEMP và STATUS_TEMP chỉ được định nghĩa trong bank 0.

Vì có tối đa 16 byte của mỗi bank (người dịch: địa chỉ 0x70-0x7F) là được dùng chung trong các chip PIC16F876A/877A, các thanh ghi tạm nên được đặt ở đây. 16 ô nhớ này không cần chuyển bank và do đó sẽ làm cho việc lưu và phục hồi ngữ cảnh dễ dàng hơn.
Hy vọng là bạn đã nắm được các lý do khiến chương trình mẫu được viết như vậy.

Thân,

tinhthanthep 16-08-2006 09:29 PM

Bây giờ thì đã thông. Thanks namqn

newuser 18-08-2006 12:14 PM

Trong P16F877A, một vài thanh ghi SFR có mặt trong cả 4 bank như: PCL, FSR, STATUS, PCLATH... như thế giá trị của chúng sẽ được tham chiếu qua lại và ta đều có thể truy cập đến mà không cần quan tâm đến vị trí bank hiện tại. Việc lưu trữ giá trị thanh ghi Status theo em chỉ có ý nghĩa đối với các bit cờ C, DC, Z,PD\ và TO\ thôi, còn các bit chọn bank thì không cần vì mỗi khi cần truy cập đến thanh ghi nào thì chỉ cần banksel thanhghi là ổn, hoặc có thói quen luôn có dòng page0 mỗi khi hoàn thành việc truy cập đến SFR.
riêng về PCLATH thì dòng note trang 30/phần PCL và PCLATH đã có chú ý rồi.
còn phần này:
Trích:

Vì có tối đa 16 byte của mỗi bank (người dịch: địa chỉ 0x70-0x7F) là được dùng chung trong các chip PIC16F876A/877A, các thanh ghi tạm nên được đặt ở đây. 16 ô nhớ này không cần chuyển bank và do đó sẽ làm cho việc lưu và phục hồi ngữ cảnh dễ dàng hơn.
như thế theo em hiểu thì giá trị nằm trong các thanh ghi ở địa chỉ này cũng có khả năng tham chiếu qua lại? sao trogn datasheet em không thấy nói đến nhỉ? Anh Nam có thể giải thích dùm em được không?

namqn 18-08-2006 07:35 PM

Cái này được dịch từ datasheet của PIC16F87xA mà em, có điều em tìm ở chỗ không có nói, còn chỗ này có nói đến nó thì có lẽ em chưa tìm. Nó nằm ở mục 14.12 của DS39582B, trang 154.

Thân,

leduy173 24-08-2006 02:18 AM

em đang làm chớp tắt trên led bằng TMR0 ;ngõ ra là porta ;sao khi làm em thấy 1 số lệnh như Comf portA và incf portA khi thực hiện nó ko xuất ra portA dc, muốn thực hiện điều đó thì em phải tác động qua 1 thanh ghi trung gian sau đó mới chuyển giá trị từ thanh ghi trung gian đó vào portA thì nó mới hiển thị!!!không hiểu tai sao lun!!!mong được chỉ thêm!

newuser 24-08-2006 05:15 PM

Trích:

Nguyên văn bởi leduy173
em đang làm chớp tắt trên led bằng TMR0 ;ngõ ra là porta ;sao khi làm em thấy 1 số lệnh như Comf portA và incf portA khi thực hiện nó ko xuất ra portA dc, muốn thực hiện điều đó thì em phải tác động qua 1 thanh ghi trung gian sau đó mới chuyển giá trị từ thanh ghi trung gian đó vào portA thì nó mới hiển thị!!!không hiểu tai sao lun!!!mong được chỉ thêm!

bạn viết hai lệnh đó không có thêm chỉ số nào đằng sau thanhghi à? nếu tôi nhớ không lầm thì chương trình biên dịch sẽ tự hiểu là bạn đang ghi giá trị đó vào thanh ghi W (bạn kiểm tra lại dùm)
COMF PORTA; lấy bù PORTA rồi ghi giá trị này vào W, giá trị PORTA không thay đổi.
bạn sửa lại như thế này: COMF PORTA,F; lấy bù PORTA rồi ghi vào chính nó.
và nhớ thiết lập PORTA là ngõ xuất:
MOVLW H'FF'; W=0xFF
MOVWF TRISA
chắc bạn đang tư duy theo tập lệnh 8051 nên mới thế

namqn 24-08-2006 07:01 PM

Trích:

Nguyên văn bởi newuser
bạn viết hai lệnh đó không có thêm chỉ số nào đằng sau thanhghi à? nếu tôi nhớ không lầm thì chương trình biên dịch sẽ tự hiểu là bạn đang ghi giá trị đó vào thanh ghi W (bạn kiểm tra lại dùm)
COMF PORTA; lấy bù PORTA rồi ghi giá trị này vào W, giá trị PORTA không thay đổi.
bạn sửa lại như thế này: COMF PORTA,F; lấy bù PORTA rồi ghi vào chính nó.
và nhớ thiết lập PORTA là ngõ xuất:
MOVLW H'FF'; W=0xFF
MOVWF TRISA
chắc bạn đang tư duy theo tập lệnh 8051 nên mới thế

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,

leduy173 25-08-2006 12:32 AM

bạn newuser ah mình cũng đã đặt portA la output và cũng đặt các đích nguồn của lệnh comf là thanh ghi F mà vẫn bị như vậy!
Anh namqn có thể nói rõ hơn về vấn đề đó ko , và những lệnh nào bi ảnh hưởng theo kiểu đó , nếu em ko lầm thì chỉ có những lệnh toán học thôi phải ko?phải bắt buộc phải thao tác qua thanh ghi trung gian như để có thể có kết quả hiển thị trên các port khi mình thao tác trực tiếp trên nó sao ???

namqn 28-08-2006 11:54 PM

Trích:

Nguyên văn bởi leduy173 (Post 4618)
bạn newuser ah mình cũng đã đặt portA la output và cũng đặt các đích nguồn của lệnh comf là thanh ghi F mà vẫn bị như vậy!
Anh namqn có thể nói rõ hơn về vấn đề đó ko , và những lệnh nào bi ảnh hưởng theo kiểu đó , nếu em ko lầm thì chỉ có những lệnh toán học thôi phải ko?phải bắt buộc phải thao tác qua thanh ghi trung gian như để có thể có kết quả hiển thị trên các port khi mình thao tác trực tiếp trên nó sao ???

Ví dụ như vậy là rõ lắm rồi, làm sao nói rõ hơn được. Về các lệnh thuộc loại read-modify-write thì đoạn trích sau đây từ tài liệu của Microchip đã nói (mặc dù vẫn không liệt kê hết các lệnh):
Trích:

Actually, any instruction that depends on a value currently in the register is going to be a Read-Modify-Write instruction. This includes ADDWF, SUBWF, BCF, BSF, INCF, XORWF, etc... Instructions that do not depend on
the current register value, like MOVWF, CLRF, and so on are not R-M-W instructions.
Tạm dịch: Thực tế, bất kỳ lệnh nào phụ thuộc vào một giá trị hiện hành trong một thanh ghi sẽ là một lệnh Read-Modify-Write (R-M-W). Điều này bao gồm các lệnh ADDWF, SUBWF, BCF, BSF, INCF, XORWF, v.v... Các lệnh không phụ thuộc vào giá trị hiện hành của thanh ghi, như MOVWF, CLRF, và tương tự thì không phải là các lệnh R-M-W.

Thân,

duylinh28 19-10-2006 01:05 PM

aho em hoi chut. bao gio co lop hoc pic moi day ? Neu ai biet thi nhan cho em qua dia chi sau khungbohanhtinh2000. thanks

tranhuyky 17-12-2006 11:29 PM

cho em hỏi có cách nào hay hơn không
 
Trích:

Nguyên văn bởi namqn (Post 4286)
À, anh xem lướt qua nên không phát hiện lỗi ở lần đầu.

Phần khai báo của bạn friends dịch không có lỗi, nhưng chạy chương trình sẽ bị sai (vì các địa chỉ biến được đặt không đúng). Toàn bộ 4 biến đó đều sẽ có địa chi 0x20. Bạn friends cần phải chỉnh lại như sau thì mới có chương trình đúng:
Code:

Org 0x20
W_SAVE res 1
STAT_SV res 1
PCH_SV res 1
FSR_SV res 1
ORG 0X0000

Giải thích thêm về phần này. Directive org chỉ làm thay đổi bộ đếm địa chỉ của trình hợp dịch. Với đoạn code như trên, chúng ta sẽ có W_SAVE là nhãn ở địa chỉ 0x20, STAT_SV là nhãn ở địa chỉ 0x21, và cứ thế. Từ khóa res và giá trị 1 sẽ làm bộ đếm địa chỉ tăng 1 đơn vị. Cách này không hay vì các địa chỉ biến thực chất là địa chỉ của các nhãn được hiểu là sẽ được dùng làm đích của các lệnh chuyển điều khiển (hay nói cách khác chúng là các địa chỉ của các từ lệnh), nếu dùng chúng trong các PIC18 chẳng hạn thì sẽ bị sai (vì các từ lệnh cách nhau 2 byte, và PIC18 dùng địa chỉ byte).

Thân,

Theo lời bác namqn nói cách dùng org không hay nếu chuyển sang PIC18 thì sai, em cũng thử rồi, làm như vậy phải sửa lại nhiều. Xin hỏi các bác có cách nào hay hơn không? cảm ơn các bác.

giaosucan 18-12-2006 10:29 PM

xin hỏi 1 tí ,tui có 1 con 18F45 có thể dùng mạch của 16F877 cho con này dc ko ,vì tui chưa tìm dc sơ đồ mạch của chon 18F45

namqn: theo tôi biết thì không có PIC18 nào có số hiệu là PIC18F45, do đó câu hỏi của bạn chưa rõ ràng.

binhdt04 28-05-2007 12:25 AM

minh khong dao duoctai lieu cacban goi cho monh duockhong minh cam on nhieu lam
binhdt04@yahoo.com

tranvanthuong 28-05-2007 08:46 AM

chương trình em viet đề điều khiển 4 led chớp tắt và dùng ngắt RB để kết hợp điều chỉnh tốc độ không biết tại sao chương trình không chạy rồi có khi chạy rút nguồn ra ghim lại thì chương trình không chay nhờ các anh chỉ giúp
chương trình em viet như sau:
Code:

include "E:\ccs c\chuong_trinh_ccsc\banh_kem_duc_thanh\chuong_trinh.h"
#int_RB
RB_isr()
{
int8 y;
  disable_interrupts(INT_RB);
  disable_interrupts(GLOBAL);
 
  if ( input(PIN_B6) )        //tang gia tri trong o nho
    {
      y = read_eeprom(0x00);
      y = y + 20;
      write_eeprom (0x00,y);
    }

 if ( input(PIN_B7) )          //giam gia tri trong o nho
    {

      y = read_eeprom(0x00);
      y = y - 20;
      write_eeprom (0x00,y);
      }
 
    delay_ms(1000);
   
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_RB);
   
}
//===========CAC CHUONG TRINH CON==============



void tao_tre(int16 x);




//============================================



void main()
{ int8 x=10,y;


  output_B(0x00);
  output_A(0x00);
  enable_interrupts(INT_RB);
  enable_interrupts(GLOBAL);




  while(1)
    {
      output_high(pin_B0);
      tao_tre(1);
      output_low(pin_B0);
      tao_tre(1);

      output_high(pin_B1);
      tao_tre(1);
      output_low(pin_B1);
      tao_tre(1);

      output_high(pin_B2);
      tao_tre(1);
      output_low(pin_B2);
      tao_tre(1);

      output_high(pin_B3);
      tao_tre(1);
      output_low(pin_B3);
      tao_tre(1);

      output_low(pin_B0);
      output_low(pin_B1);
      output_low(pin_B2);
      output_low(pin_B3);
      tao_tre(1);

      output_high(pin_B0);
      output_high(pin_B1);
      output_high(pin_B2);
      output_high(pin_B3);
      tao_tre(1);

      output_low(pin_B0);
      output_low(pin_B1);
      output_low(pin_B2);
      output_low(pin_B3);
      tao_tre(1);


    }
}
//============================================

void tao_tre(int16 x)
  {
        int16 z,i;

        z = x + read_eeprom (0x00);
          delay_ms(100);
        for(i=0;i<z;++i)
          delay_ms(2);

  }

//===========================================
và file.h
#include <16F84A.h>

#FUSES NOWDT,NOPUT,PROTECT                        //No Watch Dog Timer
#FUSES HS
#use delay(clock=10000000)


falleaf 28-05-2007 08:57 AM

Thử xem lại việc quản lý các cờ ngắt.

Chúc vui

tranvanthuong 28-05-2007 09:17 AM

HIC HIC, anh nào giup em di

tranvanthuong 28-05-2007 09:19 AM

a anh ơi~! em viết chạy ổn rồi ne!

Code:

#include "E:\ccs c\chuong_trinh_ccsc\banh_kem_duc_thanh\chuong_trinh.h"
#int_RB
RB_isr()
{
int8 y;
  disable_interrupts(INT_RB);
  disable_interrupts(GLOBAL);
 
 
  if ( input(PIN_B6) )        //tang gia tri trong o nho
    {
      y = read_eeprom(0x00);
      if(y<244)
        {
          y = y + 10;
          write_eeprom (0x00,y);
        }
    }
   

 if ( input(PIN_B7) )          //giam gia tri trong o nho
    {

      y = read_eeprom(0x00);
      if(y>10)
      {
        y = y - 10;
        write_eeprom (0x00,y);
      }
      }
     
 
    delay_ms(50);
   
   
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_RB);
   
}
//===========CAC CHUONG TRINH CON==============



void tao_tre(int8 x);




//============================================



void main()
{


  output_B(0x00);
  output_A(0x00);
  enable_interrupts(INT_RB);
  enable_interrupts(GLOBAL);




  while(1)
    {
      output_high(pin_B0);
      tao_tre(1);
      output_low(pin_B0);
      tao_tre(1);

      output_high(pin_B1);
      tao_tre(1);
      output_low(pin_B1);
      tao_tre(1);

      output_high(pin_B2);
      tao_tre(1);
      output_low(pin_B2);
      tao_tre(1);

      output_high(pin_B3);
      tao_tre(1);
      output_low(pin_B3);
      tao_tre(1);

      output_low(pin_B0);
      output_low(pin_B1);
      output_low(pin_B2);
      output_low(pin_B3);
      tao_tre(1);

      output_high(pin_B0);
      output_high(pin_B1);
      output_high(pin_B2);
      output_high(pin_B3);
      tao_tre(1);

      output_low(pin_B0);
      output_low(pin_B1);
      output_low(pin_B2);
      output_low(pin_B3);
      tao_tre(1);


    }
}
//============================================

void tao_tre(int8 x)
  {
        int8 z,i;

        z = x + read_eeprom (0x00);
        delay_ms(100);
        for(i=0;i<z;++i)
        delay_ms(2);

  }

//===========================================


Dolphin 15-07-2007 05:52 PM

+ Cho em hỏi về phần nút bấm với điện trở kéo lên. Khi bấm thì chân ở mức thấp (ok); khi ko bấm thì lam sao biết được trạng thái của chân? (do chân mắc với nguồn qua điện trở nên điện áp ở chân ko biết xác định thế nào, vẫn có thể là H hoặc L).
+ Đặt chân là input với điện áp là 0. Nếu nối chân đó với nguồn 5V thì nó sẽ chuyển từ 0-->5V và dòng điện sẽ chạy từ nguồn vào chân Pic? Còn nếu là output thì sao dòng điện sẽ chạy đi đâu?
Mấy cái này em vẫn chưa thông lắm...

namqn 15-07-2007 10:03 PM

Trích:

Nguyên văn bởi Dolphin (Post 10082)
+ Cho em hỏi về phần nút bấm với điện trở kéo lên. Khi bấm thì chân ở mức thấp (ok); khi ko bấm thì lam sao biết được trạng thái của chân? (do chân mắc với nguồn qua điện trở nên điện áp ở chân ko biết xác định thế nào, vẫn có thể là H hoặc L).
+ Đặt chân là input với điện áp là 0. Nếu nối chân đó với nguồn 5V thì nó sẽ chuyển từ 0-->5V và dòng điện sẽ chạy từ nguồn vào chân Pic? Còn nếu là output thì sao dòng điện sẽ chạy đi đâu?
Mấy cái này em vẫn chưa thông lắm...

1. Thông thường, người ta dùng điện trở vài k để kéo lên cho nút bấm, còn ngõ vào của PIC thì có tổng trở vào khá lớn (hàng megaohm). Do đó, nếu bấm nút thì điện áp đặt vào ngõ vào là 0V, còn không bấm nút thì điện áp đặt vào ngõ vào là điện áp ở điểm giữa của mạch phân áp, với 5V đi qua trở kéo lên, rồi đến điện trở vào hàng megaohm của PIC. Như vậy áp tại ngõ vào của PIC sẽ xấp xỉ 5V, tức là mức cao.

2. Câu này bạn hỏi không rõ ràng: 'Còn nếu là output thì sao dòng điện sẽ chạy đi đâu?'. Nếu bạn muốn biết khi bạn xuất mức cao hay thấp thì dòng điện sẽ chạy ra sao thì câu trả lời thế này: khi bạn xuất mức cao, MOSFET phía cao của cặp transistor ngõ ra sẽ dẫn, do đó ngõ ra là gần bằng 5V và PIC cấp dòng cho tải, nếu có tải thì tùy theo dòng tải mà điện áp ở ngõ ra sẽ bị giảm nhiều hay ít do áp rơi trên MOSFET phía cao. Khi bạn xuất mức thấp, MOSFET phía thấp của cặp transistor ngõ ra sẽ dẫn, do đó ngõ ra là gần bằng 0V và PIC rút dòng từ tải xuống Vss, nếu có tải thì tùy theo dòng tải mà điện áp ở ngõ ra sẽ cao hơn Vss nhiều hay ít do áp rơi trên MOSFET phía thấp. Bạn xem thêm mục I/O Ports trong các datasheet của chip sẽ thấy họ vẽ cấu trúc của ngõ ra.

Thân,


Múi giờ GMT. Hiện tại là 12:52 AM.

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