PDA

View Full Version : Nhật ký học PIC (Quên mang kính - Upd. 01/2006)


qmk
30-12-2005, 08:34 PM
Giờ có một cái đề tài làm Remote bằng Pic16.
Mua được từ bbd mấy cón Pic16f88 bắt đầu ngồi mò mẫm.
Tiện thể xin bác fall một góc diễn đàn để post lên quá trình làm việc.
Nhiều việc khác xen vào nên không nhanh.

Đầu tiên là tập hợp một ít tài liệu trên diễn đàn này bao gồm có học pic 1 ngày..., rồi cái tutorial gì đó. Đồng thời tìm thêm một vài cuốn sách trên mạng. Vài tài liệu xem lướt nữa cuối cùng kết luận bắt đầu từ bài của bác fall. Phần cứng đã chuẩn bị trước coi như không lo.

qmk
30-12-2005, 09:09 PM
- Tìm datasheet của 16f87/88 đọc lướt qua.
- In cái danh sách SFR
- Híc tìm mãi kô có cái tóm tắt tập lệnh nào ngắn ngắn chỉ trong một trang. Tìm một lúc thì thấy nó nằm trong datsheet. In ra luôn.
- Đọc qua cái tutorial pdf thấy tập lệnh của chuối, khái niệm chuyển bank hơi rối rắm. Như vậy không tối ưu phải chuyển bank rất nhiều.
Cảm nhận ban đầu.
* Thanh ghi W giống thanh ghi A của msc51 nhưng bị tận dụng một cách quá đáng ???
* Tập lệnh hơi bị ít lệnh. Có vẻ thiếu thiếu. Mỗi 2 lệnh mov. Vậy con này kô có bộ nhớ ngoài ??? Mov bit thế nào đây ???
* Cái lệnh retlw hay hay. Lệnh sleep, clrwdt tại sao là lệnh mà kô là một thao tác nào đó trên thanh ghi ??? Dành chỗ cho mấy lệnh khác. Có vẻ vừa thiếu vừa thừa. Chắc có ý đồ.
* Không hiểu so sánh thế nào ??? Có lệnh testbit, với incfsz/decfsz chắc là dùng nó. Chưa rõ cách dùng lắm.
* Không thấy lệnh push, pop ???

Giờ đọc kỹ tài liệu của fall xem sao với bản pdf xem sao.

qmk
31-12-2005, 01:24 PM
Ngâm cứu cái taplenh.pdf với các tiêu chuẩn mà bác fall đưa ra.
Tại cũng có tiêu chuẩn khác rồi. Bổ sung mấy ý của bác fall.

Chương trình đầu tay.

;;================================================ |=================================================
;; Tên chương trình : Hướng đẫn học Pic
;; Mã số kiểm tra :
;; Người thực hiện : qmk
;; Ngày cập nhật : 31/12/2005
;; Phiên bản : Writing
;; Mô tả phần cứng :
;; - Pic16F88
;; - Tần số Xtal : 4MHz
;; - Xem tài liệu thiết kế phần cứng đi kèm
;;------------------------------------------------|-------------------------------------------------
;; Mô tả chương trình:
;; - Các thông tin về cập nhật chương trình xem ở cuối chương trình
;;
;;------------------------------------------------|-------------------------------------------------
;; Thỏa thuận bản quyền:
;; - Bản quyền phần mềm này thuộc về người viết chương trình...
;;================================================ |=================================================
;Region CẤU HÌNH BỘ BIÊN DỊCH - COMPILER CONFIGURATION
TITLE "Hướng dẫn học Pic"
PROCESSOR PIC16F88
;; __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF &_HS_OSC

include <P16F88.inc>
;/Region
;;================================================ |=================================================
ORG 0x0000
GOTO MAIN

ORG 0x0005
;;================================================ |=================================================
;Region CHƯƠNG TRÌNH CHÍNH - MAIN PROGRAM
MAIN
banksel TRISB ;; Bank select (Một iMacro của trình biên dịch?)
clrf TRISB ;; TRISB = 0 Out, =1 In (Tri State)

banksel PORTB
bsf PORTB,0 ;; rb0 = 1

goto $ ;; Vòng lặp vô tận
;/Region
END ;; Trình biên dịch tự động dừng khi gặp lệnh này



Chương trình này có mấy warning có vẻ bất thường:
Warning[215] D:\TESTF88\MAIN.ASM 21 : Processor superseded by command line. Verify processor symbol.
Message[302] D:\TESTF88\MAIN.ASM 35 : Register in operand not in bank 0. Ensure that bank bits are correct.
Warning[205] D:\TESTF88\MAIN.ASM 43 : Found directive in column 1. (END)

Dòng 35 là:
clrf TRISB ;; TRISB = 0 Out, =1 In (Tri State)

Ngoài ra khi để dòng này nó sẽ báo lỗi:
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF &_HS_OSC

Error[126] D:\TESTF88\MAIN.ASM 24 : Argument out of range (not a valid config register address)

Không hiểu lệnh này mâu thuẫn với cấu hình Device trong MPlab thế nào.

qmk
31-12-2005, 02:11 PM
Có vẻ như trong bài tutorial của bác fall chứ END. là không đúng. Chỉ là END thôi.

Híc mấy cái waning củ chuối, nó bắt phải viết lệnh after collum1. Còn lable thì phải ngay collum1. Không biết sao turn off cái này đây.

Gặp một lỗi ngớ ngẩn. Nhấn vào version control mplab treo luôn. Tôi dùng MPLAB7.1 Mới down 7.3 về. Khi mở lại thì project conrrupt. Bó tay

qmk
31-12-2005, 04:57 PM
Chương trình thứ 2:


;Region CẤU HÌNH BỘ BIÊN DỊCH - COMPILER CONFIGURATION
TITLE "Hướng dẫn học Pic"
PROCESSOR PIC16F88
;; __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF &_HS_OSC

include <P16F88.inc>
;/Region
;;================================================ |=================================================
;Region KHAI BÁO BIẾN, HẰNG... - VARIABLE, CONSTANT,ETC DEFINITION

ORG 0x20
bTemp1 RES 1
bTemp2 RES 1
;;================================================ |=================================================
ORG 0x0000
GOTO MAIN

ORG 0x0005
;;================================================ |=================================================
;Region CHƯƠNG TRÌNH CHÍNH - MAIN PROGRAM
MAIN
banksel TRISB ;; Bank select (Một iMacro của trình biên dịch?)
clrf TRISB ;; TRISB = 0 Out, =1 In (Tri State)
Loop_Main:
banksel PORTB
bsf PORTB,0 ;; RB0 = 1
call Delay100ms
bcf PORTB,0 ;; RB0 = 1
call Delay100ms
goto Loop_Main ;; Trở về chương trình chính
;/Region
;;================================================ |=================================================
;Function Delay10ms - Hàm tam ngưng Nx10ms
;Sumary
;;
;; Input:
;; Output:
;; Effect:
;/Sumary
Delay100ms
movlw 250 ;; Nap vao gia tri y
movwf bTemp2
movlw 199 ;; Nap vao gia tri x
movwf bTemp1 ;; y lan
Loop_DHM
decfsz bTemp1,f
goto Loop_DHM ;; x-1 lan
movwf bTemp1 ;; y lan
decfsz bTemp2,f
goto Loop_DHM
return ;; 8+3+y*(x-1)*2+y*4 = 7 + y(x+1)*2 = (100.008)
;/Function
;;------------------------------------------------|-------------------------------------------------
END ;; Trình biên dịch tự động dừng khi gặp lệnh này


Bản cập nhật bổ sung thêm file myp16def.inc nội dung như sau:
RB0 EQU 0
RB1 EQU 1
RB2 EQU 2
RB3 EQU 3
RB4 EQU 4
RB5 EQU 5
RB6 EQU 6
RB7 EQU 7
Sửa một số chữ chú thích sai


;;================================================ |=================================================
;; Tên chương trình : Hướng đẫn học Pic
;; Mã số kiểm tra :
;; Người thực hiện : qmk
;; Ngày cập nhật : 31/12/2005
;; Phiên bản : Writing
;; Mô tả phần cứng :
;; - Pic16F88
;; - Tần số Xtal : 4MHz
;; - Xem tài liệu thiết kế phần cứng đi kèm
;;------------------------------------------------|-------------------------------------------------
;; Mô tả chương trình:
;; - Các thông tin về cập nhật chương trình xem ở cuối chương trình
;;
;;------------------------------------------------|-------------------------------------------------
;; Thỏa thuận bản quyền:
;; - Bản quyền phần mềm này thuộc về người viết chương trình...
;;================================================ |=================================================
;Region CẤU HÌNH BỘ BIÊN DỊCH - COMPILER CONFIGURATION
TITLE "Hướng dẫn học Pic"
PROCESSOR PIC16F88
;; __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF &_HS_OSC

include <P16F88.inc>
include <myp16def.inc> ;; Bổ sung thêm một vài định nghĩa
;/Region
;;================================================ |=================================================
;Region KHAI BÁO BIẾN, HẰNG... - VARIABLE, CONSTANT,ETC DEFINITION

ORG 0x20
bTemp1 RES 1
bTemp2 RES 1
;;================================================ |=================================================
ORG 0x0000
GOTO MAIN

ORG 0x0005
;;================================================ |=================================================
;Region CHƯƠNG TRÌNH CHÍNH - MAIN PROGRAM
MAIN
banksel TRISB ;; Bank select (Một iMacro của trình biên dịch?)
clrf TRISB ;; TRISB = 0 Out, =1 In (Tri State)
Loop_Main:
banksel PORTB
bsf PORTB,RB0 ;; RB0 = 1
call Delay100ms
bcf PORTB,RB0 ;; RB0 = 0
call Delay100ms
goto Loop_Main ;; Trở về chương trình chính
;/Region
;;================================================ |=================================================
;Function Delay10ms - Hàm tam ngưng Nx10ms
;Sumary
;;
;; Input:
;; Output:
;; Effect:
;/Sumary
Delay100ms
movlw 250 ;; Nap vao gia tri y
movwf bTemp2
movlw 199 ;; Nap vao gia tri x
movwf bTemp1 ;; y lan
Loop_DHM
decfsz bTemp1,f
goto Loop_DHM ;; x-1 lan
movwf bTemp1 ;; y lan
decfsz bTemp2,f
goto Loop_DHM
return ;; 8+3+y*(x-1)*2+y*4 = 7 + y(x+1)*2 = (100.008)
;/Function
;;------------------------------------------------|-------------------------------------------------
END ;; Trình biên dịch tự động dừng khi gặp lệnh này

qmk
31-12-2005, 07:43 PM
Phiên bản khác dùng timer để delay


;Region CẤU HÌNH BỘ BIÊN DỊCH - COMPILER CONFIGURATION
TITLE "Hướng dẫn học Pic"
PROCESSOR PIC16F88
CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF &_HS_OSC

include <P16F88.inc>
include <myp16def.inc> ;; Bo sung mot so khai bao
;/Region
;;================================================ |=================================================
;Region KHAI BÁO BIẾN, HẰNG... - VARIABLE, CONSTANT,ETC DEFINITION

ORG 0x20
bTemp1 RES 1
bTemp2 RES 1
;;================================================ |=================================================
ORG 0x0000
GOTO MAIN

ORG 0x0005
;;================================================ |=================================================
;Region CHƯƠNG TRÌNH CHÍNH - MAIN PROGRAM
MAIN
banksel TRISB ;; Bank select (Một iMacro của trình biên dịch?)
clrf TRISB ;; TRISB = 0 Out, =1 In (Tri State)
Loop_Main:
banksel PORTB
bsf PORTB,RB0 ;; RB0 = 1
call Delay100ms
banksel PORTB
bcf PORTB,RB0 ;; RB0 = 1
call Delay100ms
goto Loop_Main ;; Trở về chương trình chính
;/Region
;;================================================ |=================================================
;Function Delay100ms - Hàm tạm ngưng 100ms
;Sumary
;; S
;; Input:
;; Output:
;; Effect: Timer 1
;/Sumary
TIMER1_RELOAD EQU -(50000+8)
Delay100ms
banksel PIE1
clrf PIE1
clrf INTCON ;; Không sử dụng ngắt
clrf PIR1
banksel T1CON
clrf T1CON
movlw 0x10 ;; Đặt chế độ prescaler 1:2
movwf T1CON
movlw HIGH TIMER1_RELOAD ;; Nạp giá trị byte cao
movwf TMR1H
movlw LOW TIMER1_RELOAD ;; Nạp giá trị byte thấp
movwf TMR1L
bsf T1CON,TMR1ON ;; Khởi động Timer
banksel PIR1
WAIT_DHM
btfss PIR1, TMR1IF
goto WAIT_DHM
bcf PIR1, TMR1IF
return
;/Function
;;------------------------------------------------|-------------------------------------------------
END

qmk
01-01-2006, 12:24 PM
Vài kinh nghiệm
- Với những người đã quen Asm51 vào trong build option chọn số mạch định là Decimal như vậy tất cả các số mặc định sẽ là dạng số ai cập thường ví dụ 500 chứ kô cần viết d'500'
- Cái warning: Register in operand not in bank 0. Ensure that bank bits are correct. không phải sợ chỉ cần check xem đúng bank chưa.

Có ý kiến về đoạn mã sau của bác fall:

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 )
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!

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


Đoạn mã trên lưu lại các giá trị STATUS, W, FSR, PCH (PCLATCH).
Lệnh BSF cuối cùng không cần thiết vì khi retfie lệnh này đã set GIE lên rồi.

Trong trường hợp trong ngắt không sử dụng Indirect thì có thể không cần lưu FSR.
Trong trường hợp chương trình chỉ nằm trong 2K có thể không cần lưu PCLATCH.

Với các ứng dụng đơn giản và các dòng PIC như 16F88, 16F877 có common RAM chỉ thế này là đủ:


;;------------------------------------------------|-------------------------------------------------
;Template PushSFR - Lưu lại các thanh ghi trước khi vào ngắt
;Sumary
;; Vì Pic không hỗ trợ lệnh Push, Pop nên cần phải viết mã lưu lại các thanh ghi trước khi
;; vào ngắt. Các thanh ghi cần lưu lại là STATUS, W còn PCLATCH được tự động lưu vào Stack
;;
;/Sumary
PushSFR MACRO
movwf bSaveW ;; Lưu W vào thanh ghi tạm
swapf STATUS,W ;; Đổi chỗ STATUS nible và đặt nó vào W
movwf bSaveStatus ;; Lưu giá trị Status trong W và thanh ghi tạm
ENDM
;/Template
;;------------------------------------------------|-------------------------------------------------
;Template PopSFR - Phục hồi các thanh ghi trước khi vào ngắt
;Sumary
;; Vì Pic không hỗ trợ lệnh Push, Pop nên cần phải viết mã lưu lại các thanh ghi trước khi
;; vào ngắt. Các thanh ghi cần lưu lại là STATUS, W.
;; Nếu viết chương trình dùng nhiều hơn 1 bank cần lưu lại PCLATCH.
;; Nếu trong ngắt có sử dụng indirect access cần lưu FSR
;/Sumary
PopSFR MACRO
swapf bSaveStatus,W ;; Đổi chỗ nible trong bSaveStatus và lưu vào W
movwf STATUS ;; Ghi lại giá trị từ W vào STATUS
swapf bSaveW,F
swapf bSaveW,W ;; Ta đùng SWAP vì nó không ảnh hưởng đến Status.Z
ENDM
;/Template
;;------------------------------------------------|-------------------------------------------------
;Template IntService - Phục vụ ngắt (Code: ISR)
;Sumary
;; Pic chỉ có một Vectơ ngắt duy nhất ở địa chỉ 0x0004. Tất cả các ngắt đều nhảy đến đây.
;; Khi xảy ra ngắt thời gian đến khi nhảy địa chỉ 0x0004 (Interrupt Latency) là 3-4 chu kỳ máy
;; (3 với các ngắt trong (sinh từ nội bộ chip), 3.75 với các ngắt từ ngoài)
;; Vì chung một nguồn ngắt nên khi vào chương trình phải kiểm tra tất cả các cờ ngắt xem nguyên
;; nhân gây ra ngắt là từ đâu. Nếu do các nguyền nhân không mong muốn thì triệu gọi Macro
;; UnexpectedISR để xử lý.
;; Để dễ dàng đọc các phục vụ từng ngắt sẽ được viết dưới dạng các Macro để dễ dàng sửa chữa.
;; Phục vụ ngắt này sẽ được chèn vào vecto ngắt bắt đầu từ địa chỉ 0x0004
;/Sumary
IntService MACRO
PushSFR ;; Gọi Macro lưu lại các thông số hệ thống
clrf STATUS ;; Chọn Bank0
btfsc PIR1,TMR1IF ;; Nguồn ngắt là Timer1?
goto T1_ISR ;; Ok! Triệu gọi phục vụ ngắt Timer1
goto Unexpected_ISR ;; No! Ngắt là do nguồn khác (không mong muốn)
T1_ISR ;; Routine when the Timer1 overflows
Timer1ISR ;; Gọi Macro xử lý ngắt Timer1
goto End_ISR
Unexpected_ISR
;; UnexpectedISR ;; Gọi Macro xử lý ngắt từ nguồn khác
End_ISR
PopSFR ;; Gọi Macro phục hồi các thông số hệ thống
retfie ;; Trở về và cho phép Interrup tiếp theo
ENDM
;/Template
;/Template

lkhanh
16-10-2008, 02:30 AM
Mình mới học, và mình sẽ học theo cách của bạn,rất thú vi! Thank!

nampham
20-12-2008, 03:39 PM
Bác cho em hỏi, phần các bác viết về ngắt ý, sao các bác lại dùng lệnh SWAP , theo em nghĩ thì chỉ cần lưu giữ giá trị các thanh ghi trước khi vào ngắt thôi, sao lại cần đổi vị trí các bít thấp cho bít cao làm gì

namqn
20-12-2008, 04:53 PM
Bác cho em hỏi, phần các bác viết về ngắt ý, sao các bác lại dùng lệnh SWAP , theo em nghĩ thì chỉ cần lưu giữ giá trị các thanh ghi trước khi vào ngắt thôi, sao lại cần đổi vị trí các bít thấp cho bít cao làm gì
Trước khi lưu lại và sau khi phục hồi thanh ghi STATUS, bạn cần dùng các lệnh không gây ảnh hưởng đến các bit trạng thái trong STATUS để di chuyển dữ liệu. Lệnh MOVF làm thay đổi cờ Z, còn các lệnh MOVWF và SWAPF không làm thay đổi cờ nào hết. Đây là lý do của cách viết đoạn code lưu và phục hồi các thanh ghi như trên khi xử lý ngắt, như vẫn thấy trong các datasheet của các PIC tầm trung.

Thân,

quangvanvo
01-01-2011, 09:18 PM
các anh chị ơi có tài liệu nào chỉ rõ đặc điểm các thanh ghi đồng thời cho các ví dụ đàng hoàn không za? mình tự nhận mình là cpu mình chỉ học được qua các ví dụ không àh!!!!!!!! giúp em với các anh chị ơi giừi qua nich em giùm nha các anh chị "phieudu_cunggio951@yahoo.com.vn"