37
 Dson 1 Thanh ghi (Register): Thanh ghi được đặt trong PIC, nó có th được ghi, đọc. Hãy t ưởng tượng các thanh ghi ging như các mu giy mà chúng ta có th đọc hay viết thông tin lên nó. Hình bên dưới mô t file thanh ghi (register file) được ánh x vào PIC16F84. PIC được chia làm 2 phn, Bank0 và Bank1. Bank1 dùng để điu khin các hot động ca PIC, ví d như nói cho nó biết nhng bit nào trên PortA là đi vào (Input) và nhng bit nào xut ra (Output). Bank0 dùng để thao tác trên d li u, ví d ta mun làm cho bit nào đó trên PortA lên mc cao, đầu tiên ta ta phi chuyn đến Bank1 để set 1 bit ca 1 chân c th nào đó trên PortA tr  thành Output, sau đó ta chuyn đến Bank0 và gi mc 1 ti chân đó. Nhng thanh ghi thông thường nht trên Bank1 mà chúng ta s s dng các thanh ghi STATUS, TRISA and TRISB.  Đầu tiên chúng ta hãy quay vào Bank1, thanh ghi TRISA cho phép ta chn chân nào đó trên PortA làm ngõ Output hay Input, thanh ghi TRISB cho phép ta chn chân nào đó trên PortB làm ngõ Output hay Input, thanh ghi STATUS cho phép chn s dng Bank0 hay Bank1. STATUS:  Để thay đổi t Bank0 sang Bank1 ta s dng thanh ghi tr ng thái STATUS, set bit5 ca thanh ghi tr ng thái lên1 để chn Bank1 hoc xoá bit5 v 0 để chn Bank0, thanh ghi STATUS có địa chỉ  03H. TRISA và TRISB: 2 thanh ghi TRISA and TRISB đặt ti địa chỉ  85H và 86H, để lp trình cho các chân trên 2 thanh ghi này thông thường người ta gi mc 0 hay 1 đến các bit t ương ng trên thanh ghi, có th làm điu này trong c 2 dng hoc là bng s binary (bin) hay hex. Dùng ki u binary thì rõ ràng hơn là kiu hex nhưng mà trông l ượm thượm hơn !. Trên PortA ta có 5 chân t ương ng 5 bit, nếu mun đặt 1 trong 5 chân này thành Output ta phi g i 1 đến bit tương ng vi nó, nhng bít này có tên bit đúng chính xác vi tên ca nó, nói cách khác bit0 là RA0, bit1 là RA1, bit2 là RA2…. Hãy xem ví d : Nếu ta mun set RA0, RA3 và RA4 thành Output RA1, RA2 thành Inputs, ta ph i gi 00110 (=06h), nên nh  bit thp nm bên phi, xem hình: Port A Pin RA4 RA3 RA2 RA1 RA0 Bit Number 4 3 2 1 0 Binary 0 0 1 1 0

Tai Lieu Dich ASM PIC Rat Hay

Embed Size (px)

Citation preview

Page 1: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 1/37

 

Dson 1

Thanh ghi (Register):Thanh ghi được đặt trong PIC, nó có thể được ghi, đọc. Hãy tưởng tượng các thanh ghigiống như các mẩu giấy mà chúng ta có thể đọc hay viết thông tin lên nó. Hình bên dướimô tả file thanh ghi (register file) được ánh xạ vào PIC16F84.PIC được chia làm 2 phần, Bank0 vàBank1.

Bank1 dùng để điều khiển các hoạt độngcủa PIC, ví dụ như nói cho nó biết nhữngbit nào trên PortA là đi vào (Input) vànhững bit nào xuất ra (Output).Bank0 dùng để thao tác trên dữ liệu, ví dụ ta muốn làm cho bit nào đó trên PortA lênmức cao, đầu tiên ta ta phải chuyển đếnBank1 để set 1 bit của 1 chân cụ thể nàođó trên PortA tr ở thành Output, sau đó tachuyển đến Bank0 và gởi mức 1 tới chânđó.Những thanh ghi thông thường nhất trên

Bank1 mà chúng ta sẽ sử dụng là cácthanh ghi STATUS, TRISA and TRISB. Đầu tiên chúng ta hãy quay vào Bank1,thanh ghi TRISA cho phép ta chọn chânnào đó trên PortA làm ngõ Output hayInput, thanh ghi TRISB cho phép ta chọnchân nào đó trên PortB làm ngõ Outputhay Input, thanh ghi STATUS cho phépchọn sử dụng Bank0 hay Bank1.

STATUS: Để thay

 

đổi từ Bank0 sang Bank1 ta sử dụng thanh ghi tr ạng thái STATUS, set bit5

của thanh ghi tr ạng thái lên1 để chọnBank1 hoặc xoá bit5 về 0 để chọn Bank0,thanh ghi STATUS có địa chỉ 03H.

TRISA và TRISB:2 thanh ghi TRISA and TRISB đặt tại địachỉ 85H và 86H, để lập trình cho các chântrên 2 thanh ghi này thông thường người tagởi mức 0 hay 1 đến các bit tương ứngtrên thanh ghi, có thể làm điều này trong cả 2 dạng hoặc là bằng số binary (bin) hayhex. Dùng kiểu binary thì rõ ràng hơn làkiểu hex nhưng mà trông lượm thượm hơn !.

Trên PortA ta có 5 chân tương ứng 5 bit, nếu muốn đặt 1 trong 5 chân này thành Outputta phải gởi 1 đến bit tương ứng với nó, những bít này có tên bit đúng chính xác với têncủa nó, nói cách khác bit0 là RA0, bit1 là RA1, bit2 là RA2…. Hãy xem ví dụ:Nếu ta muốn set RA0, RA3 và RA4 thành Output và RA1, RA2 thành Inputs, ta phảigởi 00110 (=06h), nên nhớ bit thấp nằm bên phải, xem hình:

Port A Pin RA4 RA3 RA2 RA1 RA0Bit Number 4 3 2 1 0Binary 0 0 1 1 0

Page 2: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 2/37

 

Dson 2

 Tương tự chúng ta cũng làm như vậy cho TRISB.

PORTA và PORTB: Để làm cho 1 trong những chân Output lên mức cao ta gởi 1 đến bit tương ứng trênthanh ghi PORTA hoặc PORTB, giống như cách làm trên thanh ghi TRISA và TRISB, cóthể kiểm tra lại trên từng chân của Port.

Thanh ghi W:Thanh ghi W là là thanh ghi mụch đích chung mà có thể đặt lên nó bất kỳ giá tr ị nào tamuốn, khi gán cho thanh ghi W một giá tr ị nào đó, ta có thể cộng nó với 1 giá tr ị kháchoặc có thể copy nó (Mov). Nếu bạn gán 1 giá tr ị nào đó lên thanh ghi W thì nội dungtr ước đó của nó sẽ bị ghi đè lên.Xem ví dụ sử dụng PortA: Đầu tiên chúng ta cần chọn Bank0 hoặc Bank1 bằng cách set trên thanh ghi STATUS,địa chỉ của STATUS là 03H và hãy set bit5 của nó lên 1 theo cách sau:

BSF 03h,5

BSF có ngh ĩ a là Bit Set F, từ F ngh ĩ a là chúng ta sẽ sử dụng một vị trí nào đó trong

memory hoặc trong thanh ghi, 2 con số “03H” sau câu lệnh BSF ngh ĩ a là địa chỉ  củathanh ghi STATUS, con số “5” tức là bit5 của nó, như vậy ý ngh ĩ a của câu lệnh trên làset bit5 của STATUS lên 1.Bây giờ chúng ta thao tác trong Bank1.

MOVLW b'00110'

Ta đã đặt giá tr ị binary 00110 vào trong thanh ghi mụch đích chung W, chữ b có ngh ĩ alà binary, d ĩ nhiên ta cũng có thể viết lại trong dạng số hex, nó như sau:

MOVLW 06h

MOVLW có ngh ĩ a là là ‘Move Literal Value Into W’ tạm dịch là di chuyển giá tr ị củaLiteral vào thanh ghi W, để rõ ràng hơn ta có thể nói là “ đặt giá tr ị tr ực tiếp sau đây(06H) vào trong thanh ghi W “Bây giờ ta tiếp tục đặt giá tr ị đó vào trong thanh ghi TRISA để thiết lập tr ạng thái choPort:

MOVWF 85h

Lệnh này có ngh ĩ a là “MOV nội dung của W vào (thanh ghi có) địa chỉ  85h”, trongtr ường hợp này con tr ỏ địa chỉ sẽ tr ỏ tới TRISA, thanh ghi TRISA bây giờ chứa giá tr ị 00110, xem lại mô tả các câu lệnh bằng hình sau:

Port A Pin RA4 RA3 RA2 RA1 RA0Binary 0 0 1 1 0Input/Output O O I I O

Bây giờ chúng ta sẽ thiết lập các chân trên PORTA, hãy quay về Bank0 để thao tác trêncác dữ liệu.

BCF 03h,5

Page 3: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 3/37

 

Dson 3

Lệnh BCF thì đối nghịch với BSF, nó có ngh ĩ a là “ Bit Clear F” tạm dịch là xoá bit nàođó trong vùng memory hay trong thanh ghi nào đó, trong tr ường hợp này là thanh ghiSTATUS (vì địa chỉ của nó là 03H) và lệnh này xoá bit5 của STATUS.Bên dưới là đoạn code:

BSF 03h,5 ; vào Bank 1

MOVLW 06h ; Đặt giá tr ị 00110 vào WMOVWF 85h ; Move 00110 vào trong TRISABCF 03h,5 ; Quay tr ở về Bank 0

Hãy đọc kỹ đoạn code trên cho đến khi nào bạn hiểu nó đang làm cái gì.

Ghi lên Port:Trong phần trên chúng ta đã nói đến làm thế nào để thiết lập các chân của Port tr ở thành Input hay Output, trong phần này ta sẽ nói tiếp làm sao có thể gởi data tới Port vàtrong phần kế tiếp chúng ta sẽ kết thúc với một đoạn code làm cho đèn Led chớp tắt vớicả sơ đồ mạch để có thể hiểu rõ con Pic làm việc chính xác đến mức độ nào, đừng cóthử compile và nạp đoạn code vào con Pic của bạn vì nó chỉ là ví dụ mà thôi. Đầu tiên hãy setup bit2 của Port A thành Output.

Bsf 03h,5 ; Vào Bank 1Movlw 00h ; Đặt giá tr ị 00000 vào trong WMovwf 85h ; Copy 00000 vào trong TRISA, tất

; cả các chân bây giờ sẽ tr ở ;thànhOutputbcf 03h,5 ; Quay tr ở về Bank0

 Đoạn code trên là những gì đã nói trong phần tr ước, chỉ khác là bây giờ ta set tất cả cácchân của PortA tr ở thành Output bằng cách gởi giá tr ị 0 đến thanh ghi w (thanh ghi W làloại thanh ghi có 3 tr ạng thái tri-state register).Bây giờ những gì mà ta muốn con Pic phải làm là bật tất cả Led lên, để làm điều này taphải gởi mức 1 đến các chân Led, hãy xem làm như thế nào đây:

movlw 02h ; Ghi 02h vào thanh ghi W. nó là 00010 nếu; viết theo dạng binary, như vậy nó đặt 0 vào; bit 2 (chân 18) trong khi giữ các chân khác ở ;;mức 0.

movwf 05h ;Bây giờ copy nội dung của W (02H) vào;PortA (địa chỉ là 05H).

Con Led bây giờ đã bật on, chúng ta thử tắt nó xem:

movlw 00h ; Ghi 00h vào thanh ghi W. nó là 00000 nếu; viết theo dạng binary, như vậy nó đặt 0 vào

; tất cả các chân.movwf 05h ; Bây giờ copy nội dung của W ( 02H) vào

; PortABây giờ Led đã bị tắt. Để làm cho led sáng, tắt liên tục chúng ta phải làm cho chương trình quay tr ở lại điểmbắt đầu bằng cách đặt nhãn cho chương trình và nói cho nó biết đó là điểm bắt đầu mànó phải quay lại thực hiện lần nữa. Rất đơn giản, hãy đặt 1 cái nhãn có tên là STARTngay tại điểm bắt đầu của đoạn code.

Page 4: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 4/37

 

Dson 4

Startmovlw 02h ; Write 02h to the W register. In binary

; this is 00010, which puts a ‘1’ on pin2; while keeping the other pins to ‘0’

movwf 05h ; Now move the contents of W (02h); onto the PortA, whose address is 05h

movlw 00h ; Write 00h to the W register. This puts a; 0’ on all pins.

movwf 05h ; Now move the contents of W (0h) onto; the Port A, whose address is 05h

goto Start ; Goto where we say Start

Bây giờ hãy xem lại đoạn code:

Bsf 03h,5Movlw 00hMovwf 85hbcf 03h,5

Start movlw 02hMovwf 05hMovlw 00hMovwf 05hGoto Start

Chúng ta chỉ nhìn thấy toàn những con số, bạn muốn hiểu được nó thì phải nhớ hết tấtcả những địa chỉ của các thanh ghi, các Port …. Nhưng ngay cả khi bạn nhớ được tấtcả thì một đoạn code ngắn nhất như trên cũng có thể làm bạn bối r ối, để giải quyết vấnđề này hãy gán cho các con số địa chỉ bằng 1 cái tên bằng lệnh EQU.EQU đơn giản là thay một cái gì đó bằng một cái gì đó !, nó không phải là câu lệnh củacon PIC mà nó là câu lệnh của assembler, với lệnh EQU bạn có thể gán bất kỳ địa chỉ  

thanh ghi nào bằng 1 cái tên gợi nhớ hoặc gán một cái tên cho một hằng số trong đoạnchương trình. Hãy thử gán vài hằng số bằng những cái tên bạn sẽ thấy nó dể đọc đếnnhư thế nào.

STATUS equ 03h ; this assigns the word STATUS to the value of 03h,; which is the address of the STATUS register.

TRISA equ 85h ; This assigns the word TRISA to the value of 85h,; which is the address of the Tri-State register for ; PortA

PORTA equ 05h ;This assigns the word PORTA to 05h which is the; address of Port A.

Bây giờ hãy thiếp lập các giá tr ị hằng số và đặt chúng vào chương trình, các giá tr ị hằngsố phải được định ngh ĩ a tr ước khi đặt vào chương trình và hãy nhớ phải luôn đặt chúngvào vị trí bắt đầu của chương trình.Bây giờ hãy xoá hết các ghi chú sau các câu lệnh, bạn thử nhìn xem có dể dàng hiểuđược đoạn code trên khi không có các dòng ghi chú:

STATUS equ 03hTRISA equ 85hPORTA equ 05h

Page 5: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 5/37

 

Dson 5

Bsf STATUS,5movlw 00hmovwf TRISAbcf STATUS,5

Start movlw 02hMovwf PORTA

movlw 00hmovwf PORTAgoto Start

Hy vọng r ằng bạn có thể hiểu được đoạn code trên ngay cả khi không có các ghi chúcho các câu lệnh.

Delay Loops.Có một chút r 

 

ắc r ối về đoạn code chớp tắt đèn led mà ta đã xem bên trên. Mỗi lệnh thựcthi mất 1 chu kỳ xung clock, nếu ta sử dụng thạch anh 4MHz thì mỗi lệnh mất 4/4MHzhay 1us, trong đoạn code trên, ta sử dụng 5 lệnh như vậy mất 5us để thực thi hoàntoàn, quá nhanh để mắt người có thể nhìn thấy đèn led chớp tắt trong khỏang thời gianngắn ngủi như vậy, cái mà ta cần là làm cho khoảng thời gian giữa sáng và tắt của led

kéo dài ra, nói cách khác là làm tr ễ (Delay). Cơ bản của 1 chương trình Delay là chođếm ngược lại giá tr ị đã đặt tr ước đó, và khi nó đến zero (0) thì ta cho dừng bộ đếm, giátr ị zero báo cho biết dừng chương trình delay và sẽ tiếp tục thực thi lại nếu ta muốn. Đầu tiên chúng ta phải định ngh ĩ a một hằng số dùng trong bộ đếm, tạm thời chúng tagọi là hằng số COUNT, kế đến chúng ta phải xác định bộ đếm sẽ thực hiện đếm baonhiêu, số lớn nhất mà ta có thể dùng cho bộ đếm là 255 hoặc số hex là FFh.Lệnh EQU gán 1 giá tr ị cho 1 thanh ghi, điều này có ngh ĩ a là bất kỳ con số nào mà tagán cho COUNT thì COUNT sẽ có giá tr ị bằng với nội dung của địa chỉ  đó. Nếu thử gángiá tr ị FFh cho COUNT ta sẽ nhận được thông báo lỗi khi compile chương trình bởi vìđịa chỉ FFH đã được dùng cho mụch đích khác và chúng ta không thể truy cập tới nó,như vậy chúng ta phải gán một con số như thế nào cho hợp lệ ?, bạn đừng lo lắng, sẽ có cách giải quyết.

Nếu chúng ta gán COUNT cho 1 địa chỉ nào đó, ví dụ 08h, nó sẽ tr ỏ tới vị trí thanh ghimụch đích chung, nhưng mà giá tr ị mặc nhiên sau khi mở nguồn của những vị trí khôngdùng đến là FFh vì vậy nếu COUNT tr ỏ tới 08h thì nó sẽ có giá tr ị FFh.Bây giờ tôi lại đang nghe bạn “khóc” r ằng làm sao mà gán COUNT bằng một số nào đócó giá tr ị trùng với 1 trong các địa chỉ của các thanh ghi đã sử dụng?, không sao, nếuvậy thì điều mà chúng ta phải làm là MOV giá tr ị của bạn tới vị trí này, giả sử nếu bạnmuốn COUNT có giá tr ị là 85h, chúng ta không thể làm:

COUNT EQU 85h

Bởi vì 85h là vị trí của thanh ghi xuất (out) 3 tr ạng thái (Tri-State register) của PORTA.Cái mà chúng ta phải làm là:

Movlw 85h ; Đầu tiên đặt giá tr ị 85h vào thanh ghi W.Movwf 08h ; Kế đến copy giá tr ị tới thanh ghi 08h.

Bây giờ, khi chúng ta nói:

COUNT equ 08h

Thì COUNT sẽ tương đương với giá tr ị 85h. Thật là quỷ quyệt, có phải không ?!

Page 6: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 6/37

 

Dson 6

Tiếp tục, đầu tiên ta định ngh ĩ a cho một hằng số 

COUNT equ 08h

kế đến giảm COUNT xuống 1 cho đến khi nó = 0, chỉ cần 1 lệnh đơn để làm việc này vớisự hỗ tr ợ của lệnh GOTO và một cái nhãn, lệnh đơn được dùng là:

DECFSZ COUNT,1

Lệnh DECFSZ sẽ giảm thanh ghi ( trong tr ường hợp này là COUNT) xuống một đơn vị được điền sau dấu phẩy (,), trong ví dụ này đơn vị là 1. Nếu nó giảm tới zero chươngtrình sẽ bỏ qua lệnh kế tiếp để nhảy đến thực thi lệnh thứ 2.Mất nhiều lời để giải thích cho 1 lệnh đơn có phải không?, hãy xem cái gì xảy ra khi tađặt nó vào chương trình.

COUNT equ 08hLABEL decfsz COUNT,1Goto LABEL

Carry on here.::: Điều mà chúng ta phải làm đầu tiên là gán hằng số COUNT = 255, kế đến đặt 1 cáinhãn ngay bên cạnh lệnh defsz.Lệnh decfsz COUNT,1 sẽ giảm giá tr ị của COUNT xuống 1 và lưu giá tr ị đã giảm tr ở vào trong COUNT, nó cũng sẽ kiểm tra xem COUNT = 0 chưa, nếu chưa nó sẽ chochương trình thực thi lệnh kế tiếp, trong ví dụ này nó sẽ thực thi lệnh GOTO để quay về lại điểm bắt đầu ( là LABEL), nếu COUNT = 0 thì nó sẽ cho chương trình bỏ qua lệnh kế tiếp và nhảy đến lệnh thứ 2, trong ví dụ này chương trình sẽ nhảy đến nơi có chữ ‘Carryon here’.

Như bạn đã thấy, chúng ta đã làm cho chương trình lưu lại một thời gian tr ước khi nótiếp tục làm việc gì đó tiếp theo, cái này gọi là vòng tr ễ (Delay loop), nếu chúng ta muốnthời gian tr ễ lớn hơn chúng ta phải làm một vòng tr ễ kiểu khác, nhưng mà cũng dể dàngđể hiểu ra r ằng có nhiều Loop hơn thì thời gian sẽ tr ễ lâu hơn, chúng ta cần ít nhất là 2Loop như trên nếu muốn nhìn thấy đèn Led chớp.Bây giờ hãy đặt chúng vào trong chương trình và kết thúc chương trình, nhớ thêm cácghi chú.

;*****Set up the Constants****

STATUS equ 03h ;Address of the STATUS register TRISA equ 85h ;Address of the tristate register for Port A

PORTA equ 05h ;Address of Port ACOUNT1 equ 08h ;First counter for our delay loopsCOUNT2 equ 09h ;Second counter for our delay loops

;****Set up the Port****

bsf STATUS,5 ;Switch to Bank 1movlw 00h ;Set the Port A pinsmovwf TRISA ;to Output.

Page 7: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 7/37

 

Dson 7

bcf STATUS,5 ;Switch back to Bank 0

;****Turn the LED on****

Start movlw 02h ;Turn the LED on by first puttingmovwf PORTA ;it into the w register and then

;on the Port;****Start of the delay loop 1****

Loop1 decfsz COUNT1,1 ;Subtract 1 from 255Goto Loop1 ;If COUNT is zero, carry on.Decfsz COUNT2,1 ;Subtract 1 from 255Goto Loop1 ;Go back to the start of our loop.

;This delay counts down from;255 to zero, 255 times

;****Delay finished, now turn the LED off****

movlw 00h ;Turn the LED off by first puttingmovwf PORTA ; it into the w register and then onthe Port

;****Add another delay****

Loop2 decfsz COUNT1,1 ;This second loop keeps theGoto Loop2 ;LED turned off long enough for decfsz COUNT2,1 ;us to see it turned off goto Loop2 ;

;****Now go back to the start of the program

goto Start ;go back to Start and turn LED;on again

;****End of the program****

end ;Needed by some compilers,;and also just in case we miss;the goto instruction.

Bạn có thể cpmpile chương trình này và nạp nó vào con PIC, d ĩ nhiên là bạn sẽ muốnthử cho nó hoạt động, ở đây có sẵn sơ đồ mạch cho bạn.Xin chúc mừng, bạn vừa mới viết xong 1 chương trình cho con PIC và đã làm cho nóhoạt động theo mong đợi. Cho đến bây giờ bạn đã học được 7 trong số 35 lệnh của con

PIC r ồi đấy, nhưng mà như vậy bạn vẫn chưa thể điều khiển được các Port I/O của nó.Tại sao bạn không thử thay đổi Delay Loop cho nó nhanh hơn để biết giá tr ị Delay Looptối thiểu mà mắt người có thể nhìn thấy đèn Led chớp tắt và thay đổi tốc độ chớp tắt củaLed, ví dụ mỗi lần là 1 giây. Trong tr ường hợp này bạn cần phải thử thay đổi các giá tr ị hằng số COUNT khác nhau của mỗi Delay Loop.Trong phần tiếp theo chúng ta sẽ bàn đến cái gì gọi là thủ tục con (subroutine) để giúpchúng ta tiếp tục viết các chương trình nhỏ và thông thường nhất.

Thủ tục con (subroutine):

Page 8: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 8/37

 

Dson 8

Một thủ tục con là một phần của một đoạn code hay một phần của một chương trình màbạn có thể gọi nó thực thi bất kỳ lúc nào cần thiết. Một thủ tục con được sử dụng khi màbạn muốn thực thi một chức năng nào đó nhiều hơn 1 lần, tức là làm đi làm lại chứcnăng đó, ví dụ như Delay Loop. Cái thuận tiện của một thủ tục con là bạn có thể thay đổigiá tr ị bên trong nó sau mỗi lần thực thi, ví dụ bạn có thể thay đổi 10 lần gía tr ị của nónếu cần thiết, nhưng quan tr ọng nhất của một thủ tục con là bạn có thể tiết kiệm bộ nhớ 

chương trình chiếm đóng trong con Pic.

Hãy xem một subroutine sau:

ROUTINECOUNT equ 255

LABEL decfsz COUNT,1Goto LABEL

RETURN

 Đầu tiên chúng ta phải đặt cho subroutine một cái tên, tôi chọn tên ROUTINE, sau đó

viết đoạn chương trình mà tôi muốn nó thực hiện, tôi viết lại chương trình Led chớp tắtnhư phần trên, cuối cùng tôi kết thúc subroutine bằng lệnh RETURN.Bạn có thể đặt subroutine này bất cứ nơi nào trong chương trình chính (MAIN) và khimuốn nó thực thi bạn chỉ  cần gọi nó bằng lệnh CALL theo sau là tên của subroutine.Subroutine sẽ thực thi đoạn code bên trong nó cho đến khi nó gặp lệnh RETURN thìdừng lại, chương trình sẽ tự động quay về chương trình chính đúng tại nơi mà nó gọisubroutine và thực thi lệnh kế tiếp sau lệnh CALL.Bạn có thể CALL nhiều lần để thực thi cùng một subroutine nếu bạn muốn, đó là lý dotại sao người ta sử dụng subroutine để giảm độ dài của chương trình.Tuy nhiên có hai thứ mà bạn phải ngh ĩ  đến, thứ nhất là bất kỳ hằng số nào cũng phảiđược khai báo tr ước khi bạn sử dụng nó nhưng mà trong tr ường hợp subroutine bạn cóthể khai báo ngay trong bản thân nó hoặc ngay tại đầu chương trình chính như thông

thường, tuy nhiên tôi lại khuyên bạn nên khai báo mọi thứ tại đầu chương trình chính vìnhư bạn đã biết, để mọi thứ ở cùng một nơi thì dể tìm kiến hơn, có phải không?. Vấn đề thứ hai r ất quan tr ọng là bạn phải bảo đảm đặt subroutine sau lệnh RETURN củachương trình chính tr ừ phi trong chương trình chính bạn dùng lệnh GOTO để nhảy quasubroutine, nếu không nó sẽ thực thi bất kỳ lệnh nào mà nó bắt gặp bất kể bạn có muốnhay không bởi vì con Pic không phân biệt được đâu là chương trình chính đâu làsubroutine.Hãy xem lại đoạn chương trình chớp Led nhưng mà lần này ta sử dụng subroutine choDelay Loop bạn sẽ thấy chương trình đơn giản đến mức nào và xem subroutine làmviệc ra sao.

;*****Set up the Constants****

STATUS equ 03h ;Address of the STATUS register TRISA equ 85h ;Address of the tristate register for Port APORTA equ 05h ;Address of Port ACOUNT1 equ 08h ;First counter for our delay loopsCOUNT2 equ 09h ;Second counter for our delay loops

;****Set up the Port****

Page 9: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 9/37

 

Dson 9

bsf STATUS,5 ;Switch to Bank 1movlw 00h ;Set the Port A pinsmovwf TRISA ;to Output.Bcf STATUS,5 ;Switch back to Bank 0

;****Turn the LED on****

Start movlw 02h ;Turn the LED on by first putting itmovwf PORTA ;into the w register and then on the Port

;****Add a delaycall Delay;****Delay finished, now turn the LED off****

movlw 00h ;Turn the LED off by first putting itmovwf PORTA ;into the w register and then on the Port

;****Add another delay****call Delay

;****Now go back to the start of the program

goto Start ;go back to Start and turn LED on again;****Here is our Subroutine

DelayLoop1

decfsz COUNT1,1 ;This second loop keeps the LEDGoto Loop1 ;turned off long enough for us toDecfsz COUNT2,1 ;see it turned off Goto Loop1 ;

Return

;****End of the program****end ;Needed by some compilers, and

;also;just in case we miss the goto instruction.

Rõ ràng kích thước chương trình đã giảm đi nhiều khi sử dụng subroutine cho DelayLoop, mỗi lần ta muốn thực hiện Delay để làm cho Led ON hoặc cho Led Off, ta chỉ cầngọi subroutine Delay. Tại điểm kết thúc subroutine chương trình sẽ quay tr ở về ngaysau dòng lệnh CALL.Nếu không sử dụng subroutine chương trình chớp Led trên có thể cần đến 120byte bộ 

nhớ chương trình, nhưng khi sử dụng subroutine nó chỉ còn cần 103byte, thật ra số bytechênh lệch như vậy cũng không phải là vấn đề quan tr ọng lắm, nhưng mà bạn chỉ  có1024byte để chứa chương trình trong con Pic thì việc tiết kiệm được số byte như vậyquả là không uổng công nặn óc để làm subroutine, có phải khôngTrong phần kế tiếp chúng ta sẽ tìm hiểu làm sao mà đọc được Port.

Đọc Port (Reading from the I/O Ports):Cho đến bây giờ bạn đã có th

 

ể ghi lên Port để làm cho Led chớp tắt, còn tiếp theochúng ta sẽ tìm cách đọc lại nội dung trên chân I/O của Port. Tr ước tiên cần kết nối cácchân Port tới mạch bên ngoài và theo dõi hoạt động tại đây.

Page 10: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 10/37

 

Dson 10

Nếu bạn còn nhớ những thứ đã nói đến trong các phần tr ước, để setup I/O Port chúngta phải chuyển từ Bank0 sang Bank1, hãy làm cái này tr ước:

STATUS equ 03h ;Address of the STATUS register TRISA equ 85h ;Address of the tristate register for Port APORTA equ 05h ;Address of Port A

Bsf STATUS,5 ;Switch to Bank 1

 Để gán cho Port tr ở thành Output, chúng gởi 0 vào thanh ghi TrisA và để nó tr ở thànhInput ta phải gởi 1 đến thanh ghi TrisA, quá đơn giản !.

Movlw 01h ;Set the Port A pinsMovwf TRISA ;to Input.Bcf STATUS,5 ;Switch back to Bank 0

Bây giờ chúng ta đặt bit0 của PortA tr ở thành Input, cái mà ta phải làm bây giờ là kiểmtra lại xem chân này đang ở mức cao hay thấp (mức1 hay mức 0), để làm được điềunày ta sử dụng lệnh BTFSC và lệnh BTFSS.

Lệnh BTFSC có ngh ĩ a là làm động tác thử xem 1 bit được chỉ  định trên thanh ghi có = 0hay không, nếu là 0 thì bỏ qua lệnh kế tiếp.Lệnh BTFSS thì ngược lại, nó có ngh ĩ a là làm động tác thử xem 1 bit được chỉ  định trênthanh ghi có = 1 hay không, nếu là 1 thì bỏ qua lệnh kế tiếp.Chúng ta sẽ sử dụng lệnh nào?, cái này còn tuỳ thuộc vào bạn mong đợi chương trìnhđọc được cái gì trên Port.Ví dụ: Nếu bạn đang mong đợi ngõ Input là 1 thì hãy dùng lệnh BTFSS, hãy xem cáinày:

Code here:BTFSS PortA,0

Goto startCarry on here::Chương trình sẽ chỉ nhảy đến dòng “Carry on here” nếu bit0 của PortA = 1.Bây giờ bạn hãy viết lại chương trình đèn Led chớp ở 1 tốc độ cố định, nhưng mà nếuđóng 1 cái Switch nào đó thì đèn Led sẽ chớp chậm hơn ½.. Bạn hoàn toàn có thể tự làm được mà, đừng có nhìn vào đoạn Code bên dưới xem sao.Chúng ta sử dụng cùng một mạch giống như phần trên nhưng mà thêm một cái Switchcó một đầu nối vào chân RA0 của con Pic còn đầu kia mắc lên nguồn.

;*****Set up the Constants****

STATUS equ 03h ;Address of the STATUS register TRISA equ 85h ;Address of the tristate register for Port APORTA equ 05h ;Address of Port ACOUNT1 equ 08h ;First counter for our delay loopsCOUNT2 equ 09h ;Second counter for our delay loops;****Set up the Port****bsf STATUS,5 ;Switch to Bank 1movlw 01h ;Set the Port A pins:movwf TRISA ;bit 1to Output, bit 0 to Input.

Page 11: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 11/37

 

Dson 11

Bcf STATUS,5 ;Switch back to Bank 0;****Turn the LED on****

Startmovlw 02h ;Turn the LED on by first putting itMovwf PORTA ;into the w register and then on the Port

;****Check if the switch is closedBTFSC PORTA,0 ;Get the value from PORT A

;BIT 0. If it is a zerocall Delay ;a zero, carry on as normal.If is is a 1,

;then add an extra delay routine;****Add a delaycall Delay;****Delay finished, now turn the LED off****movlw 00h ;Turn the LED off by first putting itmovwf PORTA ;into the w register and then on the Port;****Check if the switch is still closed

BTFSC PORTA,0 ;Get the value from PORT ABIT 0. If it is a zero,Call Delay ;carry on as normal.If is a 1, then add anextra delay

;routine;****Add another delay****call Delay;****Now go back to the start of the programgoto Start ;go back to Start and turn LED on again;****Here is our Subroutine DelayLoop1

Decfsz COUNT1,1 ;This second loop keeps the LEDGoto Loop1 ;turned off long enough for us todecfsz COUNT2,1 ;see it turned off 

goto Loop1 ;return

;****End of the program****end ;Needed by some compilers, and also

;just in case we miss the goto instruction.

 Đầu tiên chương trình bật Led on, kế đến kiểm tra xem cái Switch có đóng không, nếunó đóng chương trình sẽ gọi Delay subroutine, thời gian Delay giống y như tr ước nhưngmà gọi subroutine thực thi 2 lần, nó sẽ làm tương tự như vậy cho tr ường hợp Led Off.Bây giờ bạn hãy compile chương trình và cho con Pic chạy thử, nhưng mà tôi có một lờicảnh cáo bạn r ằng, toàn bộ những thứ mà bạn làm sẽ không gây ấn tượng cho bất kỳ aikhông thích thú với lập trình cho vi xử lý, vì vậy cũng đừng có thất vọng nếu mà bạn

đem khoe với những người thân trong gia đình r ồi chỉ cho họ làm sao cho con Led chớpchâm đi ….họ sẽ chỉ  giả vờ ngạc nhiên thích thú mà thôi !, đó là những kinh nghiệmxương máu của tôi !.Nếu bạn theo sát từ đầu đến giờ thì bạn đã biết tổng cộng 10 trong số 35 lệnh của conPic 16F84 r ồi đấy và tất cả những thứ mà bạn biết chỉ  đơn giản là làm cho con Ledchớp tắt !, thật phí phạm thời gian có phải không ?, còn tôi thì ngh ĩ  thật là phí phạm bộ nhớ của con Pic nếu phải viết chương trình dài như vậy chỉ  để chớp tắt, nhan chậm đènLed !, phải có cách gì đó làm cho hay hơn.

Page 12: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 12/37

 

Dson 12

Hãy xem ví dụ bên dưới, nó mới thật sự là một chương trình làm đèn Led chớp tắt,nhanh chậm.

movlw 02hmovwf PORTAmovlw 00h

movlw PORTA

 Đầu tiên ta nạp vào thanh ghiW giá tr ị 02h, sau đó copy nó sang thanh ghi PortA để bậtLed on.  Để tắt nó, ta Nạp gía tr ị 00h vào thanh ghi W sau đó copy nó tới thanh ghiPortA. Ở giữa chương trình ta phải gọi subroutine để cho đèn chớp tắt, chúng ta phảiviết 2 lệnh MOV cho Led Off và 2 lệnh MOV cho Led on, 2 lệnh MOV sẽ thực hiện lầnlượt ghi data vào thanh ghi W r ồi chuyển vào PORTA. Sau đó ta gọi 2 lần Delaysubroutine, 1 lần Delay cho Led on và 1 lần cho Led Off.Có cách nào khác đơn giản hơn không ?, có đấy, đó là sử dụng lệnh XORF.Lệnh XORF thực hiện hàm XOR cho data chứa trong thanh ghi, chắc là không cần phảigiải thích hàm XOR cho bạn phải không ?.Như vậy để bật Led On/Off chúng ta chỉ cần 2 dòng Lệnh.

MOVLW 02hXORWF PORTA,1

 Đầu tiên nạp vào W giá tr ị 02h sau đó thực hiện lệnh XORF cho data trên PortA với giátr ị 1, nếu hiện tại PortA có giá tr ị 1 thì nó sẽ thay đổi thành 0 còn nếu PortA đang là 0sau khi lệnh XORF thực hiện nó sẽ tr ở thành 1.Hãy xem mô tã lại những gì mà chúng ta đã nói:

PORTA00010xorwf 00000

xorwf 00010xorwf 00000xorwf 00010

Thật ra chúng ta không cần phải nạp mỗi lần cùng một giá tr ị vào trong thanh ghi W bởivì có thể làm điều này ngay lúc bắt đầu chương trình, chỉ cần quay tr ở về lệnh lật ngượcPortA lại mà thôi. Ngoài ra chúng ta cũng không cần phải gán một giá tr ị cho thanh ghiPortA, tại sao vậy?, bởi vì khi mới cấp nguồn cho con Pic thì PortA mặc nhiên đã = 1 r ồichúng ta chỉ cần lật qua lật lại cho PortA =0 r ồi =1 mà thôi, ngay cả khi ban đầu PortA =0 thì chúng ta cũng sẽ vẫn làm như vậy.Hãy xem 2 đoạn code mới, đoạn code thứ nhất viết theo kiểu như ban đầu, đoạn codethứ hai là viết lại nhưng dùng lệnh XORF.

;*****Set up the Constants****STATUS equ 03h ;Address of the STATUS register TRISA equ 85h ;Address of the tristate register for Port APORTA equ 05h ;Address of Port ACOUNT1 equ 08h ;First counter for our delay loopsCOUNT2 equ 09h ;Second counter for our delay loops;****Set up the Port****bsf STATUS,5 ;Switch to Bank 1

Page 13: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 13/37

 

Dson 13

movlw 00h ;Set the Port A pinsmovwf TRISA ;to Output.Bcf STATUS,5 ;Switch back to Bank 0movlw 02h ;Set up our w register with 02h;****Turn the LED on and off****Start

Xorwf PORTA,1 ;Toggle the LED

;****Add a delaycall Delay;****Now go back to the start of the programgoto Start ;go back to Start and turn LED on again;****Here is our SubroutineDelayLoop1

decfsz COUNT1,1 ;This second loop keeps the LEDGoto Loop1 ;turned off long enough for us todecfsz COUNT2,1 ;see it turned off 

goto Loop1 ;return

;****End of the program****end ;Needed by some compilers, and also

;just in case we miss the goto instruction.

;*******Flashing LED With Switch:;*******Set up the Constants****STATUS equ 03h ;Address of the STATUS register TRISA equ 85h ;Address of the tristate register for Port APORTA equ 05h ;Address of Port ACOUNT1 equ 08h ;First counter for our delay loops

COUNT2 equ 09h ;Second counter for our delay loops;****Set up the Port****bsf STATUS,5 ;Switch to Bank 1movlw 01h ;Set the Port A pins:movwf TRISA ;bit 1to Output, bit 0 to Input.Bcf STATUS,5 ;Switch back to Bank 0movlw 02h ; Set up our w register with 02h;****Turn the LED on and off****Start

xorwf PORTA,1 ;Toggle the LED;****Check if the switch is closedBTFSC PORTA,0 ;Get the value from PORT A BIT 0.If it is a

;zerocall Delay ;carry on as normal. If is a 1, then add an

;extra delay routine;****Add a delaycall Delay;****Check if the switch is still closed

BTFSC PORTA,0 ;Get the value from PORT A BIT 0. If it is a;zero,

call Delay ;carry on as normal. If is a 1, then add an

Page 14: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 14/37

 

Dson 14

;extra delay routine;****Add another delay****

call Delay

;****Now go back to the start of the program

goto Start ;go back to Start and turn LED on again;****Here is our SubroutineDelayLoop1

Decfsz COUNT1,1 ;This second loop keeps the LEDgoto Loop1 ;turned off long enough for us todecfsz COUNT2,1 ;see it turned off goto Loop1 ;return

;****End of the program****end ;Needed by some compilers, and also

;just in case we miss the goto instruction.

Chỉ  cần dùng các lệnh đơn giản chúng ta có thể giảm kích thước của chương trình.Thực sự ta đã giảm được bao nhiêu byte khi viết lại các chương trình bằng các lệnhđơn giản, hãy xem thống kê:

Program Change Size (Bytes)

Flashing LED Original 120Flashing LED Subroutine Added 103Flashing LED XOR Function Used 91LED With Switch Original 132LED With Switch XOR Function Used 124.

Chúng ta không chỉ  học vài lệnh mới mà còn học cách làm sao giảm kích thước củachương trình.

Toán hạng Logic và Số học:Trong phần trên chúng ta được giới thiệu lệnh XORF và cách sử dụng nó, trong phầnnày sẽ nói tiếp các toán hạng và lệnh Logic mà con Pic có hỗ tr ợ.Bây giờ ta sẽ nói làm sao thao tác trên các bit riêng r ẽ, thực hiện vài thuật toán thôngthường trên dữ liệu. Sẽ không có ví dụ nữa nhưng mà sẽ giải thích cặn kẽ làm thế nàodùng các toán hạng trong các đoạn code nhỏ.

Lệnh ANDLW và ANDWF:Con Pic cho ta 2 món được ch

 

ế biến từ hàm AND, đó là lệnh ANDLW và ANDWF.Lệnh ANDLW cho phép ta AND nội dung trong thanh ghi W với một con số xác định, cúpháp là:

ANDLW <number><number> là cái mà ta sẽ AND với nội dung trong thanh ghi W, kết quả AND sẽ lưutrong thanh ghi W.Lệnh ANDWF cho phép ta AND thanh ghi W với một thanh ghi khác, ví dụ như vớiPortA, cú pháp là:

ANDWF <register>,d

Page 15: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 15/37

 

Dson 15

<register> là thanh ghi mà ta chỉ  định, ví dụ PortA, d nói cho Pic biết nơi lưu kết quả.Nếu d=0 thì kết quả lưu vào thanh ghi W và d=1 thì kết quả lưu vào thanh ghi đứngtr ước d.Hai đoạn code bên dưới sẽ mô tã 1 ví dụ cho mỗi hàm AND. Đầu tiên kiểm tra tr ạng tháiPortA là nơi mà ta cần biết ngõ vào có = 1100 hay không và đặt kết quả vào trong thanhghi W.

Movlw 1100ANDWF 05h,0

Ví dụ thứ hai sẽ kiểm tra nội dung trong W.

ANDLW 1100

Lệnh IOR:Lệnh IOR đơn giản như là một hàm OR, khi một trong hai bit =1 hoặc cả hai đều = 1 màOR với nhau sẽ cho kết quả = 1, ngược lại sẽ =0.

Lệnh ADDLW và ADDWF:ADD là một hàm cộng 2 s

 

ố với nhau, nếu kết quả lớn hơn 8bit thì cờ CARRY sẽ được

set lên 1 ngược lại nó =0. Cờ CARRY có địa chỉ byte 03h và nằm tại bit0.Một lần nữa con Pic cho ta 2 món chế biến từ hàm ADD, đó là ADDLW và ADDWF, bạncũng có thể đoán r ằng nó cũng tương tự như các hàm ở trên.Lệnh ADDLW cộng nội dung của thanh ghi W với một số xác định, cú pháp là:ADDLW <number>Lệnh ADDWF cộng nội dung của thanh ghi W với một thanh ghi bất kỳ, kết quả lưutrong W, cú pháp là: ADDWF <register>,d

<register> là thanh ghi mà chúng ta chỉ  định và d nói cho con Pic biết nơi lưu kết quả.Nếu d=0 kết quả lưu trong thnh ghi W, d=1 kết quả lưu trong thanh ghi ta chỉ  định (tức là<register>).

Lệnh SUBLW and SUBWF:

Hàm SUB, tôi dám đánh cược bạn không thể đoán được hàm này làm cái gì ?!, thôiđược r ồi, xem như bạn đã đoán ra, hàm SUB này tr ừ 1bit với 1bit khác.Một lần nữa con Pic lại cho ta 2 món được chế biến từ hàm SUB, đó là SUBLW andSUBWF, cú pháp thì giống y như là những món của hàm ADD nhưng mà thay vì cộngthì nó tr ừ.

Lệnh INCF và INCFSZ:Nếu chúng ta muốn cộng 1 với một số trong Pic, đơn giản ta sử dụng hàm ADD và số 1,cái bất tiện là đầu tiên ta phải bỏ con số 1 vào trong thanh ghi W, sau đó dùng lệnhADDLW 1 để tăng nó lên 1. Nếu ta chỉ muốn cộng số 1 vào một thanh ghi bất kỳ thì còn tồi tệ hơn, đầu tiên phải đặt số 1 vào thanh ghi W, sau đó dùng lệnh

ADDWF <register>,1.Ví dụ ta muốn cộng số 1 với nội dung của địa chỉ 0Ch, ta phải viết đoạn code sau:

Movlw 01addwf 0c,1

Có một cách tốt hơn cách này đó là dùng lệnh INCF trong con Pic, cú pháp là:INCF <register>,d

Page 16: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 16/37

 

Dson 16

Với <register> là thanh ghi, hoặc địa chỉ mà ta chỉ  định, còn d thì nói cho con Pic biết nơiđặt kết quả. Nếu d=0 thì kết quả lưu trong thanh ghi W, nếu d=1 kết quả sẽ được lưutrong thanh ghi chỉ  định nằm tr ước nó (tức là <register>)Bằng cách này ta có thể tiết kiệm ½ bộ nhớ của Pic. Nếu ta muốn kết quả lưu trong Wthì sử dụng ví dụ trên sau đó thêm một lệnh khác để MOV nội dung trong địa chỉ 0Ch tr ở vào trong thanh ghi W sau đó đặt vào thanh ghi 0Ch bất cứ cái gì.

Có một lệnh increment khác, đó là INCFSZ, lệnh này sẽ tăng thanh ghi mà ta chỉ  địnhlên 1, nhưng nếu thanh ghi này =0 sau khi thực thi lệnh ( xảy ra khi cộng 1 vào FFh) thìcon Pic sẽ bỏ qua lệnh kế tiếp, đoạn code bên dưới sẽ mô tả lệnh này:

LoopIncfsz 0CGoto Loop

::Rest of program.

Trong đoạn code trên, địa chỉ 0Ch sẽ tăng lên 1 sau đó chương trình nói cho con Pic

quay về nhãn Loop và gia tăng 0Ch lên lần nữa, nó làm tiếp tục như vậy cho tới khi 0Ch=127 (FFh). Lần này khi tăng lên 1, nội dung của 0Ch sẽ =0.Lệnh INCFSZ sẽ nói cho con Pic bíêt hãy bỏ qua lệnh kế tiếp, trong tr ường hợp ví dụ trên nó bỏ qua lệnh GOTO Loop để thực thi tiếp đoạn code còn lại.

Lệnh DECFSZ:Lệnh DECFSZ đã bàn trong các ví dụ tr ước, bây giờ ta sẽ không nhắc lại nữa.

Lệnh COMF:Lệnh cu

 

ối cùng trong nhóm này là lệnh COMF, nó đảo ngược (Compliment) tất cả cácbit trong thanh ghi được chỉ  định, cú pháp là:

COMF <register>,d.Với <register> là thanh ghi mà ta muốn đảo và d nói cho con Pic bíêt nơi lưu kết quả.Nếu d=0 kết quả lưu trong thanh ghi W, nếu d=1 thì kết quả lưu trong thanh ghi chỉ  định

nằm tr ước d ( tức là <register>). Xem mô tả sau đây:

0C = 11001100COMF 0C,10C = 00110011

Cái này r ất tiện lợi khi mà bạn muốn nhanh chóng bật các chân của Port từ Output tr ở thành Input hoặc ngược lại.

Toán hạng trên Bit:

Các toán hạng dùng cho Bit cho phép chúng ta thao tác trên các bit đơn lẽ trong byte,nó cho phép MOV, SET và CLEAR bit trong thanh ghi hoặc những địa chỉ  được chỉ  định,phần cuối của tutorial này ta sẽ trình bày một chương trình làm cho con Led sáng chạytheo nhiều cách khác nhau.

Lệnh BCF:Trong các ph

 

ần tr ước chúng ta đã xem một số lệnh thực thi trên bit, trong phần này tasẽ xem một số lệnh còn lại tác động lên bit như thế nào.BCF là lệnh xoá 1 bit được chỉ  định trong thanh ghi, cú pháp là:

Page 17: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 17/37

 

Dson 17

BCF <register>,<bit>

Chúng ta đã sử dụng lệnh này trong phần tr ước để thay đổi từ Bank1 sang Bank0 bằngcách xoá bit trong thanh ghi STATUS, chúng ta cũng có thể Clear 1 bit về 0 tại bất kỳ bitnào trong bất kỳ thanh ghi nào, ví dụ, nếu bạn muốn Clear bit thứ 3 trong thanh ghi 0Chcó nội dung = 11001101, bạn có thể làm như sau:

BCF 0C,03 Lệnh BSF:

Lệnh BSF ngược lại, nó có thể Set 1 bit lên 1 tại bất kỳ bit nào trong bất kỳ thanh ghinào, ta đã dùng cái này trong phần tr ước để nhảy từ Bank0 sang Bank1, cú pháp là:BSF <register>,<bit>Cách dùng BSF giống y như cách dùng BCF.

Lệnh BTFSC:Chúng ta đã có th

 

ể Set bit và Clear bit trong thanh ghi, nhưng mà nếu bạn chỉ muốn thử xem bit nào đó trong thanh ghi là = 1 hay = 0 thì sao, r ất đơn giản, hảy dùng lệnhBTFSC, nó được gọi là “Bit Test Register F and Skip If It Is Clear”, tạm dịch là “lệnh thử kiểm tra bit trong thanh ghi và bỏ qua lệnh kế nếu bit = 0”, quá rõ ràng r ồi, không cầnphải giải thích gì thêm nữa phải không ?!, ta sẽ dùng lệnh này để kiểm tra một cái cờ 

(flag) nào đó ví dụ như cờ Carry, nó tránh cho ta khỏi phải đọc thanh ghi STATUS để tìm xem tr ạng thái của từng bit như thế nào. Ví dụ, nếu bạn muốn thử bit cờ Carry =1chưa sau khi bạn cộng 2 byte với nhau, bạn hãy thử làm cái này:

BTFSC 03h,0

Nếu cờ Carry=1 thì chương trình thực thi tiếp lệnh đứng kế tiếp, nếu Carry=0 nó sẽ bỏ qua lệnh kế tiếp, xem đoạn code sau:

Loop :::BTFSC 03,0

Goto Loop

Trong đoạn code trên, con Pic sẽ đi ra khỏi Loop nếu bit0 trong thanh ghi STATUS ( haycờ Carry) bị xoá về 0, nói cách khác nếu cờ Carry=0 lệnh GOTO sẽ được thực hiện.

Lệnh BTFSS:Lệnh này có ngh ĩ a là “Bit Test Register F, And Skip If Set” tạm dịch là kiểm tra bit trongthanh ghi F và bỏ qua lệnh kế nếu=1. Nó giống như là lệnh BTFSC nhưng mà chỉ kháclà con Pic sẽ bỏ qua lệnh kế tiếp nếu bit=1. Lệnh CLRF:

Lệnh này sẽ Clear nội dung trong thanh ghi hiện hành về 0, cú pháp là:CLRF <register>

Chúng ta đã dùng lệnh này tr ước đây để Clear ngõ ra Output của Port về 0 bằng cách

dùng câu lệnh:CLRF 05h

lệnh CLRW:

Lệnh này giống y như lệnh CLRF nhưng mà chỉ  khác là nó chỉ Clear thanh ghi W, cúpháp thì hoàn toàn đơn giản:

CLRW

Page 18: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 18/37

 

Dson 18

Lệnh RLF và RRF:Lệnh này sẽ dịch bit trong thanh ghi sang vị trí bên trái (RLF) hoặc bên phải (RRF) củathanh ghi đó, ví dụ bạn có 00000001 và bạn dùng lệnh RLF thì bạn sẽ nhận được00000010.Bây giờ hãy xem cái gì sẽ xảy ra nếu bạn có 10000000 và tiếp tục thực thi lệnh RLF?,đừng có hốt hoảng, bit 1 của bạn sẽ đi sang cờ Carry, nếu bạn lại tiếp tục RLF thì bit 1

sẽ quay tr ở về vị trí 0 trong byte. Mọi thứ sẽ diễn ra đúng như vậy đối với lệnh RRFnhưng mà bit sẽ di chuyển theo chiều bên phải. Ví dụ bên dưới biểu diễn lệnh RLF, bạncó nhình thấy chữ C là ký hiệu của cờ Carry, các con số 7654321 là thứ tự từ cao xuốngthấp của 8bit trong thanh ghi.

C 76543210

0 00000001RLF 0 00000010RLF 0 00000100RLF 0 00001000RLF 0 00010000

RLF 0 00100000RLF 0 01000000RLF 0 10000000RLF 1 00000000RLF 0 00000001

Chương trình Test:

Bây giờ bạn sẽ xem một ví dụ, nếu muốn bạn có thể compile và cho nó chạy thử.Chương trình này làm cho đèn chạy bắt đầu từ bit0 của PortA sang tới bit8 của PortB r ồiquay về thực thi lại từ đầu. Bạn hãy kết nối các con Led vào chân Port r ồi cho chạychương trình, bạn sẽ nhìn thấy các bit hoạt động như những gì mà ta đã nói từ tr ước

đến giờ.

TIME EQU 9FH ; Variable for the delay loop.PORTB EQU 06H ; Port B address.TRISB EQU 86H ; Port B Tristate address.PORTA EQU 05H ; Port A address.TRISA EQU 85H ; Port A Tristate address.

STATUS EQU 03H ; Page select register.COUNT1 EQU 0CH ; Loop register.COUNT2 EQU 0DH ; Loop register.

BSF STATUS,5 ; Go to page 1MOVLW 00H ; and set upMOVWF TRISB ; both Ports A and BMOVLW 00H ; to Output,MOVWF TRISA ; then return to

Page 19: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 19/37

 

Dson 19

BCF STATUS,5 ; page 0.MOVLW 00H ; Clear Port A.MOVWF PORTA ;; Start of main programRUNMOVLW 01H ; Set the first bit

MOVWF PORTB ; on Port B.CALL DELAY ; Wait a whileCALL DELAY ;

; Move the bit on Port B left, then pause.

RLF PORTB,1CALL DELAYCALL DELAYRLF PORTB,1CALL DELAYCALL DELAY

RLF PORTB,1CALL DELAYCALL DELAYRLF PORTB,1CALL DELAYCALL DELAYRLF PORTB,1CALL DELAYCALL DELAYRLF PORTB,1CALL DELAYCALL DELAY

RLF PORTB,1CALL DELAYCALL DELAYRLF PORTB,1 ; This moves the bit into the carry flag; Now move onto Port A, and move the bit left.RLF PORTA,1 ; This moves the bit from the zero flag into PortACALL DELAYCALL DELAYRLF PORTA,1CALL DELAYCALL DELAYRLF PORTA,1

CALL DELAYCALL DELAYRLF PORTA,1CALL DELAYCALL DELAY

; Move the bit back on Port ARRF PORTA,1CALL DELAYCALL DELAY

Page 20: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 20/37

 

Dson 20

RRF PORTA,1CALL DELAYCALL DELAYRRF PORTA,1CALL DELAYCALL DELAY

RRF PORTA,1 ; This moves the bit into the zero flag; Now move the bit back on Port B

RRF PORTB,1CALL DELAYCALL DELAYRRF PORTB,1CALL DELAYCALL DELAYRRF PORTB,1CALL DELAYCALL DELAYRRF PORTB,1

CALL DELAYCALL DELAYRRF PORTB,1CALL DELAYCALL DELAYRRF PORTB,1CALL DELAYCALL DELAYRRF PORTB,1CALL DELAYCALL DELAY ; Now we are back where we started,;

GOTO RUN ; let's go again.; Subroutine to give a delay between bit movements.DELAY

MOVLW TIME ; Get the delay time,MOVWF COUNT1 ; and put it into a variable.

LOOP1;DECFSZ COUNT1 ; Decrement 1 from the delay time until itGOTO LOOP1 ; reaches zero.MOVWF COUNT1 ; Get the delay time again,

LOOP2 ; and repeat the count down.DECFSZ COUNT1 ;GOTO LOOP2 ;

RETURN ; End of subroutine.END ;

Page 21: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 21/37

 

Dson 21

 

Bảng dữ liệu ( Data Table):Có một điểm r ất đặc biệt trong tập lệnh mà nó cho phép bạn truy xuất dữ liệu theo kiểu

tra bảng (data table). Một bảng dữ liệu thông thường là một danh sách liệt kê các giá tr ị của dữ liệu, mỗi giá tr ị được đọc phụ thuộc vào việc phải thoả mãn vài tiêu thức nào đó.Ví dụ, bạn có một con Pic và bạn muốn đếm số lần ngõ vào Input được nâng lên mứccao trong thời gian 1giây là bao nhiêu sau đó hiễn thị lên Led 7 đoạn. Mỗi lần thời gianbắt đầu tính, con Pic sẽ đếm số lần ngõ Input vào được nâng lên mức cao trong thờigian 1 giây, sau 1 giây nó hiễn thị con số nó đếm được tương ứng với số lần ngõ vàoInput được nâng lên mức cao. Cái này r ất tiện dụng bởi vì chúng ta không biết đượchiện tại con số đếm đã là bao nhiêu cho đến khi con Pic dừng lại, bằng cách sử dụngbảng tra dữ liệu chúng ta có thể cho phép con Pic quýêt định con số nào nó cần hiễn thị.Bây giờ tr ước khi giải thích bảng tra dữ liệu làm việc ra sao ta sẽ bàn xem con Pic bám

theo chổ nào trong chương trình trong lúc chương trình đang chạy. Nếu bạn đã từng lậptrình trong BASIC thì đở mệt nhọc hơn, còn nếu không bạn cũng đừng lo lắng, bạn sẽ vẫn tìm thấy các khái niệm ở đây.Hãy tưỡng tượng chúng ta có một chương trình BASIC như chương trình bên dưới:

10 LET K=011 K=K+112 IF K>10 THEN GOTO 20 ELSE GOTO 1120 PRINT K21 END

Chương trình bắt đầu tại dòng số 10, mỗi lần K =0 nó tiến tới dòng 11, sau khi cộng

thêm 1 cho K nó di chuyển đến dòng 12. Ở đây chúng ta hỏi K có lớn hơn 10 không ?,nếu đúng nó tiếp tục đi tới dòng 20, nếu sai nó quay tr ở lại dòng 11, dòng 20 sẽ xuất giátr ị của K và dòng 21 sẽ kết thúc chương trình.BASIC sử dụng con số thứ tự dòng để giúp cho lập trình viên bám theo chương trìnhmột khi những cái nhãn nhận dạng không cho phép sử dụng trong BASIC.Con Pic có sử dụng những cái nhãn để nhảy qua lại các vị trí hay không?, chúng tadùng những cái nhãn nhận dạng vì vậy chúng ta biết những thứ gì, ở đâu và nói chocon Pic biết con đường nó phải đi. Cái mà thực sự con Pic đã dùng đó là bộ đếm dònglệnh bên trong còn gọi là bộ đếm chương trình Program Counter. Program Counter viết

Page 22: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 22/37

 

Dson 22

tắt là PC dò tìm các vị trí trong bộ nhớ  để tìm kiếm vị trí hiện tại của câu lệnh màchương trình đang thực thi. Khi chúng ta nói cho con Pic bíêt phải đi đến cái nhãn nàođó, nó bíêt vị trí của cái nhãn này trong bộ nhớ và nó gia tăng PC lên cho tới khi nó đọcđược vị trí đó.  Điều này giống y như cái cách mà chúng ta đọc chương trình trongBASICBên dưới là đoạn code và các vị trí bộ nhớ hay nói cách khác chính là nội dung trong

PC, kế bên là các dòng lệnh.

PC Instruction

0000 movlw 030001 movwf 0C0002 Loop decfsc 0C0003 goto Loop04 end

Trong ví dụ trên, ta set PC tới 0000. tại vị trí này ta có lệnh movlw 03. Khi con Pic thựcthi lệnh này nó tăng PC lên và vì vậy nó đọc tiếp lệnh kế, ở đây con Pic lại thấy lệnh

movwf 0C, nó lại tăng PC lên một lần nữa, lần này nó thấy lệnh decfsc 03, nếu nội dungtrong địa chỉ 0C không = 0 con Pic sẽ tăng PC lên 1 và đọc lệnh kế tiếp, lệnh Goto loopnói con Pic hãy quay lại vị trí 0002. Nếu nội dung trong 0C là 0 thì con Pic nói PC phảităng lên 2 hay nói cách khác là bỏ qua lệnh kế tiếp nó, như vậy nó sẽ đến vị trí 0004, tạiđây là điểm kết thúc của chương trình. Các vị trí được thiết lập bởi assembler, và chúngta không cần lo lắng con Pic đang làm cái gì cho tới khi chúng ta cần kiểm soát nó như trong tr ường hợp của bảng tra dữ liệu. Cách tốt nhất để giải thích bảng dữ liệu làm việcra sao là hãy chấm dứt ngay cái ví dụ này và xem cái bên dưới đây !.

PC equ 02Movlw 03Call table

:table addwf PCretlw 01retlw 02retlw 03retlw 04retlw 05retlw 06retlw 07return

Lệnh đầu tiên gán cái nhãn PC có địa chỉ của Program Counter (02h), sau đó chúng ta

đặt giá tr ị của thanh ghi 03h vào trong thanh ghi W. Bây giờ ta làm một lệnh gọi bảng tradữ liệu. Dòng đầu tiên trong subroutine bảng dữ liệu sẽ công nội dung của thanh ghi W(03h) với PC, điều này làm cho PC tăng lên 3, tương đương với việc PC sẽ đi xuống 3dòng. Khi PC xuống dòng thứ 3 con Pic trông thấy lệnh reltw, lệnh này chuyển giá tr ị đứng sau nó vào thanh ghi W r ồi quay tr ở về lại subroutine. Lệnh RETLW có ngh ĩ a làquay về và tr ả giá tr ị phía sau nó về thanh ghi W. Lưu ý là có 2 động tác được thực hiệntrong lệnh RETLW.Khi ta đang đứng trong một subroutine ta cần có một lệnh quay về để thoát ra khỏisubroutine đó là lệnh RET.

Page 23: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 23/37

 

Dson 23

Phía sau lệnh RETLW là một con số, con số này là thứ mà ta sẽ đặt vào trong thanh ghiW, trong tr ường hợp này nó là số 03.Chúng ta có thể gán cho thanh ghi W bất kỳ giá tr ị nào nhưng phải chắc chắn r ằng consố này sau khi cộng với PC trong subroutine bảng tra dữ liệu sẽ tìm ra được một lệnhRETLW, trong ví dụ trên, điều này có ngh ĩ a là ta có thể có bất kỳ con số nào từ 1 đến 7,nếu ta đi lọt ra ngoài subroutine thì có thể sẽ làm cho con Pic không thể thực hiện bất kỳ 

phần nào của chương trình nữa. Chính vì điều này mà người ta hay đặt bảng tra dữ liệuở cuối của chương trình, như vậy nếu bị lọt ra khỏi subroutine thì sẽ đến điểm kết thúcchương trình (End).

Ngắt (Interrupt):Chủ đề nói v

 

ề các Ngắt (Interrupts) hầu như là dài nhất và khó hiểu nhất, không phải dể để giải thích về ngắt cho người nào đó hiểu, nhưng mà hy vọng sau khi kết thúc phầnnày chúng ta có thể áp dụng ngắt vào trong chương trình của chúng ta. Chúng ta sẽ chia phần này thành 2 phần nhỏ, mụch đích là để cho bạn nghỉ giải lao !. Đầu tiên, Ngắt (interrupt) là cái gì vậy ?, nó thật sự có ý ngh ĩ a giống như tên gọi của nóvậy, một Interrupt là một tác vụ xử lý hay là một tín hiệu xử lý mà nó có thể bắt con Picdừng lại những gì đang làm để làm một công việc khác. Một ví dụ dể hiểu, hãy lấy sinhhoạt hàng ngày của bạn, giả sử bạn đang ngồi ở nhà, r ồi bạn đang tán gẫu với ai đó,

thình lình chuông điện thoại reo, bạn ngưng cuộc nói chuyện lại, nhặt điện thoại lên vànói chuyện với người gọi đến. Khi bạn kết thúc cuộc nói chuyện bằng điện thoại bạn lạiquay tr ở về và tiếp tục tán gẩu với người đã nói chuyện với bạn tr ước khi điện thoại reo.Bây giờ bạn hãy tưởng tượng, chương trình chính là quá trình tán gẫu của bạn vớingười bạn ngồi ở nhà, điện thoại reo tạo ra một Interrupt và thủ tục (routine) Interrups làcuộc nói chuyện với người ở đầu dây bên kia, khi kết thúc cuộc nói chuyện bằng điệnthoại bạn quay về “chương trình chính” để tiếp tục tán gẫu, Ví dụ này giải thích chínhxác một Interrups tạo ra một tiến trình xử lý như thế nào. Một chương trình chính đangchạy, thực hiện một vài chức năng nào đó trên mạch điện, nhưng khi Interrupt xảy rachương trình chính sẽ tạm ngưng và ngay lúc đó một thủ tục khác được thực hiện, khithủ tục này kết thúc con Pic sẽ lại quay về chương trình chính.Con Pic có 4 Interrupt, nó có thể được chia thành 2 nhóm, 2 Interrupts phục vụ cho các

thiết bị kết nối ngoại vi và 2 Interrupts cho bên trong nó. Tr ước tiên ta hãy nói về 2Interrupts bên ngoài, 2 Interrups bên trong Pic sẽ nói đến trong phần Timers và lưu tr ữ Data.

Nếu bạn quan sát trên sơ đồ chân của Pic bạn sẽ thấy chân số 6 có ghi là RB0/INT,RB0 là bit0 của PortB, ký hiệu INT là ký hiệu chức năng Interrupt ngoài. Ngoài ra cácchân từ 10 đến 13 ( bit 4 tới 7 của PortB) cũng có thể sử dụng cho Interrupt. Tr ước khisử dụng Interrupt hay dùng nó như là Port in out thông thường chúng ta cần phải làm 2việc. Đầu tiên ta cần nói cho con Pic biết r ằng ta sẽ sử dụng Interrupt, kế đến ta cần xácđịnh chân nào của PortB sẽ dùng như Interrupt.Trong con Pic có 1 thanh ghi gọi là INTCON, địa chỉ  là 0Bh, trong thanh ghi này có 8bitcó thể thiết lập chế độ cho phép hay không cho phép. Bit7 của INTCON được gọi là GIE

có ngh ĩ a là Global Interrngupt Enable tạm dịch là chân cho phép sử dụng toàn bộ Interrup. Nếu set bit này lên 1 con Pic sẽ cho phép sử dụng Interrupt. Bit4 của INTCONgọi là INTE có ngh ĩ a là INTerrupt Enable tạm dịch là cho phép Interrupt, set bit này lên1 sẽ cho phép chân RB0 tr ở thành chân Interrupt. Bit3 còn gọi là bit RBIE nếu đượcset=1 sẽ báo cho con Pic biết ta sẽ sử dụng từ bit4 cho đến bit7 của PortB. Bây giờ thìcon Pic đã biết và theo dõi khi nào chân này lên cao hay xuống thấp, nó biết cần phảidừng chương trình chính lại khi nào để quay ra phục vụ thủ tục của Interrupt.Bây giờ chúng ta cần nói cho con Pic biết sẽ khởi động Interrupt bằng cạnh lên (từ 0Vlên 5V) hay cạnh xuống ( từ 5V xuống 0V) của tín hiệu vào chân Interrupt. Nói cách

Page 24: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 24/37

 

Dson 24

khác, ta muốn con Pic phục vụ Interrupt khi tín hiệu vào thay đổi từ thấp lên cao hay từ cao xuống thấp. Mặc nhiên sau khi bật nguồn con Pic sẽ thiết lập chế độ Interrupt cạnhlên, có ngh ĩ a là interrup xảy ra khi tín hiệu vào thay đổi từ thấp lên cao (cạnh lên)Thanh ghi OPTION ở địa chỉ 81h chính là thanh ghi thiết lập chế độ cho Interrupt tíchcực ở cạnh lên hay cạnh xuống của tín hiệu vào, bit6 của thanh ghi OPTION được gọi làINTEDG, nếu setbit6=1 sẽ thiết lập interrupt tích cực ở cạnh lên của tín hiệu vào (tr ạng

thái default) , nếu Clear bit6=0 sẽ thiết lập interrupt tích cực ở cạnh xuống của tín hiệuvào.Nếu bạn muốn con Pic thiết lập interrupt xảy ra ở cạnh lên của tín hiệu thì bạn khôngcần phải làm gì trên bit6 của thanh ghi OPTION.Thật không may mắn, thanh ghi OPTION lại nằm trên Bank1, vì vậy bạn phải làm độngtác di chuyển từ Bank0 sang Bank1 sau đó Set bit6 trên thanh ghi OPTION r ồi lại quaytr ở về Bank0. Có một mánh lới để làm tất cả chuyện này trên Bank1 như là thiết lập cácchân Port, quay tr ở vào Bank0 !.  Được r ồi, cho đến giờ chúng ta đã biết chân nào củacon PIC sẽ tr ở thành Interrupt và tích cực cạnh nào của tín hiệu, cái gì sẽ xảy ra trongchương trình và Interrupt xảy ra khi nào.Có 2 thứ xảy ra, thứ nhất là có 1 cờ ‘flag’ được set để nói cho con Pic biết r ằng có 1Interrupt đã xảy ra, thứ hai bộ đếm chương trình (program counter) tr ỏ đến một địa chỉ  

đặc biệt trong con Pic, hãy xem từng vấn đề như thế nào. Cờ Ngắt (Interrupt Flag):

Trong thanh ghi INTCON bit1 chính là cờ báo Interrupt gọi là INTF, khi có Interrupt xảyra, cờ này sẽ được set lên 1, tr ước khi có Interrupt xảy ra nó =0. Trong khi cờ Interruptđược set lên 1 thì con Pic sẽ không thể và không bao giờ đáp ứng bất kỳ một Interruptnào nữa. Cái cờ  được set lên 1 và con Pic sẽ thực thi chương trình (routine) củaInterrupt, nếu cái cờ vì lý do gì đó không thể set lên 1 và con Pic đang thực thi chươngtrình Interrupt thì tín hiệu đổ vào liên tục tại chân Interrupt sẽ liên tục gây ra Interrupttrên con Pic làm cho nó phải liên tục quay tr ở về  điểm bắt đầu của chương trình(routine) Interrupt và sẽ không bao giờ nó có thể kết thúc được chương trình Interruptnày.Bây giờ quay lại ví dụ về chuyện tán gẫu và cuộc nói chuyện điện thoại của bạn, nó

giống như là bạn vừa nhặt điện thoại lên định nói chuyện thì chuông lại reo lần nữa vì cóai đó cũng đang muốn nói chuyện với bạn!. Tại sao không phải là sau khi kết thúc cuộcchuyện trò với người thứ nhất bạn lại nhặt điện thoại lên một lần nữa để nói chuyện vớingưòi thứ hai, có phải tốt hơn không!, tôi đoán đó là lý do tại sao mà điện thoại khôngthể reo trong khi bạn đã nhấc ống nghe.

Có một tr ở ngại nhỏ trên cái cờ này, mặc dù con Pic tự động set cờ này lên 1 nhưng nólại từ chối trách nhiệm Clear cái cờ này về 0 ! vì vậy mà trách nhiệm cao cả này đượctrao cho người lập trình viên !, nếu không thì sẽ không bao giờ có interrupt xảy ra nữa.Cái này thì dể dàng thôi và tôi chắn chắn r ằng bạn sẽ làm được.

Địa chỉ bộ nhớ:Memory Location

Lần đầu tiên mở nguồn hoặc khi reset con Pic, Bộ đếm chương trình (Program Counter)tr ỏ đến địa chỉ 000h, đó chính là điểm bắt đầu của bộ nhớ chương trình. Tuy nhiên hkicó Interrupt xảy ra thì PC sẽ tr ỏ đến địa chỉ 0004h, vì vậy khi viết chương trình mà cós73 dụng Interrupt thì đầu tiên chúng ta phải nói cho con Pic nhảy (jump) đến địa chỉ  0004h và tách riêng chương trình Interrupt ( bắt đầu tại 0004h) với các chương trìnhkhác, điều này thì r ất dễ làm có phải không ?.(dầu tiên chúng ta khởi động chương trình bằng lệnh ORG, lệnh này ngh ĩ a là Origin, or start tạm dịch là điểm khởi đầu hay điểm khởi động, theo sau ORG là một địa chỉ xácđịnh. Bởi vì con Pic khởi động tại 0000h nên chúng ta viết:

Page 25: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 25/37

 

Dson 25

ORG 000hKế đến chúng ta cần nhảy qua khỏi địa chỉ  0004h, bạn hãy dùng lệnh GOTO để làmđiều này và theo sau GOTO là 1 cái nhãn mà nó sẽ tr ỏ tới điểm bắt đầu của đoạn codecủa chương trình chính. Sau đó ta đặt tiếp một ORG khác, vì ta đang nói đến Interruptnên bạn phải đặt ORG 0004hTheo sau lệnh ORG 0004h chúng ta sẽ viết chương trình Interrupt hoặc có thể đặt 1

lệnh GOTO để nhảy đến chương trình Interrupt đặt ở đâu đó.Viết chương trình Interrupt theo sau ORG 0004h Hay dùng lệnh GOTO để nhảy đến 1 chương trình Interrupt đặt ở đâu đó thật sự là vấn đề để chọn lựa. Để chấm dứt 1 chương trình Interrupt ta cần đặt lệnh RTFIE tại cuối chương trìnhInterrupt đó, RTFIE có ngh ĩ a là return from the interrupt routine tạm dịch quay tr ở về từ chương trình Interrupt, khi con Pic nhìn thấy lệnh RTFIE nó báo cho Program Counter biết để dời tới vị trí lần cuối cùng nó đứng trong chương trình chính tr ước khi Interruptxảy ra, hãy xem một đoạn code ngắn bên dưới đây:

ORG 0000h ;PIC starts here on power up and resetGOTO start ;Goto our main program

ORG 0004h ;The PIC will come here on an interrupt: ;This is our interrupt routine that we: ;want the PIC to do when it receives: ;an interruptRETFIE ;End of the interrupt routinestart ;This is the start of our main program.

Có 2 điều quan tr ọng mà bạn cần chú ý khi sử dụng Interrupt:Thứ nhất, nếu bạn sử dụng cùng một thanh ghi cho chương trình chính và cho Interruptthì r ất có thể nội dung của thanh ghi này bị thay đổi khi Interrupt xảy ra, ví dụ: bạn sử dụng thanh ghi W để gởi Data tới PortA trong chương trình chính và cũng dùng thanhghi W trong Interrupt để di chuyển nội dung từ nơi này đến nơi khác, nếu bạn không cẩn

thận thì thanh ghi W sẽ chứa giá tr ị cuối cùng trong chương trình Interrupt (khi interruptxảy ra), và r ồi, khi bạn quay về chương trình chính bạn lại gởi nội dung này vào PortAthay vì một nội dung khác tr ước khi Interrupt xảy ra. Cách đơn giản để tránh thảm hoạ này là bạn hãy lưu thanh ghi W vào vị trí tạm nào đấy và dùng nó lại sau khi chươngtrình Interrupt kết thúc.Thứ hai, đó là thời gian nghỉ bắt buộc giữa 2 lần interrupt xảy ra liên tiếp, như bạn biết,con Pic có một bộ dao động bên trong hoạt động bằng cách mắc với bên ngoài hoặcdùng thạch anh hoặc dùng mạch RC, tần số dao động này được chia 4 bên trong để tạora xung Clock làm nhịp cho 1 chu kỳ lệnh, Ví dụ: nếu thạch anh là 4MHz kết nối với conPic thì 1 chu kỳ lệnh là: 4MHz/4 = 1MHzBây giờ hãy xem hướng dẫn sử dụng cho con Pic của nhà sản xuất, phải có ít nhất là 3đến 4 chu kỳ lệnh giữa 2 interrupt, tôi chọn và khuyên bạn cũng nên chọn 4 chu kỳ lệnh

giữa 2 interrupt cho chắc ăn !.Lý do mà con Pic cần thời gian ngh ĩ giữa 2 lần Interrupt là nó phải làm đủ thứ chuyệnnhư là nhảy đến địa chỉ Interrupt, set cờ interrupt, thoát ra khỏi chương trình interrupt.Như vậy, dựa trên những gì đã bàn trong phần trên, bạn phải lưu ý khi sử dụng mạchkết nối với các thiết bị ngoại vi kích hoạt interrupt của con Pic.Bây giờ lại có một thứ cần phải nhớ, đó là khi bạn sử dụng từ bit4 đến bit7 của PortBnhư Interrupt thì bạn không thể chọn riêng từng chân trên PortB để nó làm việc như Interrupt, nếu bạn cho phép (enable) những chân này thì bạn đã cho phép tất cả Trong phần tiếp theo chúng ta sẽ viết chương trình cho Interrupt

Page 26: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 26/37

 

Dson 26

Interrupts – Chương trình Interrupt:Chương trình mà ta sẽ vi

 

ết là đếm số lần 1 cái Switch bật on r ồi hiễn thị con số đó.CHương trình sẽ đếm từ 0 đến 9, hiễn thị lên 4 Led dưới dạng Binary, ngõ vào interruptlà RB0.  Đầu tiên ta cần phải báo cho con Pic nhảy đến địa chỉ mà bộ đếm chương trìnhsẽ tr ỏ đến khi Interrupt xảy ra, hãy lưu ý chúng ta sẽ sử dụng 1 cách khác để biểu diễnsố Hex. Tr ước đây chúng ta hay viết F9h với h có ngh ĩ a là hexadecimal, bây giờ chúng

ta viết lại là 0xF9, và cái này chính là dạng mà chúng ta sẽ viết từ giờ tr ở đi.

Org 0x00 ;This is where the PC points to on power up and resetGoto main ;Goto our main programOrg 0x04 ;This is where our interrupt routine will startRetfie ;This tells the PIC that the interrupt routine has

;finished and the PC will point back to the main programmain ;This is the start of our main program

Bây giờ chúng ta cần nói cho con Pic biết r ằng chúng ta sẽ sử dụng Interrupt và sử dụng RB0 (chân 6) như là chân Interrupt.

bsf INTCON,7 ;GIE – Global interrupt enable (1=enable)bsf INTCON,4 ;INTE - RB0 interrupt enable (1=enable)

Kế đến chúng ta xoá cờ Interrupt, mặc dù chúng ta đã nói khi mở nguồn lần đầu tiên thìcờ Interrupt mặc nhiên bị xoá về 0, nhưng mà tôi chưa bao giờ tin vào bất kỳ điều gì !.

bcf INTCON,1 ;INTF - Clear flag bit just in case

Và bây giờ setup 2 Port, nhớ r ằng khi chúng ta sử dụng RB0 như một Interrupt thì taphải setup nó như một ngõ vào Input.

Bsf STATUS,5 ;Switch to Bank 1

Movw 0x01 ;Movwf TRISB ;Set RB0 as InputMovlw 0x10 ;Movwf TRISA ;Set the first 4 pins on PortA as OutputBcf STATUS,5 ;Come back to Bank 0

Chúng ta sẽ sử dụng biến COUNT để lưu số lần Switch On, bạn có thể hỏi tại saochúng ta không làm đơn giản là tăng giá tr ị của PortA r ồi đọc lại giá tr ị này, nhưng bạnsẽ biết lý do tại sao mà tôi sử dụng biến COUNT khi viết chương trình Interrupt.

loopmovf COUNT,0 ;Move the contents of COUNT into W

movwf PORTA ;Now move it to Port Agoto loop ;Keep on doing thisend ;End of our program

Chương trình chính đã có, bây giờ ta nói cho con Pic biết cái gì sẽ làm khi Interrutp xảyra, trong tr ường hơp này Interrupt của chúng ta sẽ là cái Switch.Chúng ta muốn con Pic cộng thêm 1 vào biến COUNT mỗi lần cái Switch đóng lại.Nhưng mà PortA có 5 bit, nếu chúng ta chỉ  đơn giản tăng Port lên 1 thì chúng ta sẽ cósố đếm tối đa là 31.

Page 27: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 27/37

 

Dson 27

Có 2 lý do mà tôi chọn không tăng lên đến 31. Thứ nhất chúng ta dùng Led 7 đoạn, màthông thường nó chỉ biểu diễn được từ 0 đến 15 ( từ 0 đến Fh). Thứ hai, tôi cũng muốnbiểu diễn vài thuật toán thông thường để bạn hiểu những thứ sẽ trình bày trong phầncuối của cuốn sách này.Cái đầu tiên chúng ta cần làm là lưu nội dung của thanh ghi W vào chỗ tạm thời vìchúng ta sẽ dùng W để tải nội dung của COUNT vào PortA, nếu không làm vậy có thể ta

sẽ tải nội dung khác lên PortA chứ không phải COUNT.

Movwf TEMP ;Store w register in a temporary location

Kế tiếp ta muốn công 1 vào biến COUNT:

Incf COUNT,1 ;Increment COUNT by 1, and put the result back into;COUNT

Kế  đến chúng ta muốn kiểm tra xem COUNT đã lớn hơn 9 chưa bằng cách là lấyCOUNT tr ừ cho 10.

Movlw 0x0A ;Move the value 10 into w

Subwf COUNT,0 ;Subtract w from COUNT, and put the result in w

Trong các phần tr ước bạn đã biết, nếu ta lấy một số nhỏ tr ừ cho số lớn hơn thì cờ Carrysẽ set lên 1, ngoài ra cờ Carry cũng sẽ được set lên 1 khi chúng ta tr ừ 2 số bằng nhau.

Btfss STATUS,0 ;Check the Carry flag. It will be set if ;COUNT is equal to, or is greater than w,;and will be set as a result of the subwf instruction

Chúng ta muốn, nếu COUNT lớn hơn 9 thì đặt lại giá tr ị 0 cho nó, ngược lại sẽ quay về chương trình chính để xuất giá tr ị COUNT ra PortALệnh BTFSS như bạn biết là nó sẽ bỏ qua lệnh kế nếu cờ Carry =1.

Trong truờng hợp này nếu COUNT=10:

goto carry_on ;If COUNT is <10, then we can carry ongoto clear ;If COUNT is >9, then we need to clear it

carry_onbcf INTCON,0x01 ;We need to clear this flag to enable

;more interruptsmovfw TEMP ;Restore w to the value before the interruptretfie ;Come out of the interrupt routine

clear clrf COUNT ;Set COUNT back to 0

bcf INTCON,1 ;We need to clear this flag to enable;more interrupts

retfie ;Come out of the interrupt routine

Bây giờ hãy ráp lại tất cả các đoạn code lại với nhau.Bên dưới là 1 chương trình hoàn chỉ nh, mạch điện trình bày sau chương trình này, mỗilần bạn cho Switch On đèn Led sẽ  đếm theo số Binary từ 0000 đến 1010 r ồi quay tr ở về 0000.

Page 28: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 28/37

 

Dson 28

org 0x00 ;This is where we come on power up and reset;*******************SETUP CONSTANTS*******************INTCON EQU 0x0B ;Interrupt Control Register PORTB EQU 0x06 ;Port B register addressPORTA EQU 0x05 ;Port A register addressTRISA EQU 0x85 ;TrisA register address

TRISB EQU 0x86 ;TrisB register addressSTATUS EQU 0X03 ;Status register addressCOUNT EQU 0x0c ;This will be our counting variableTEMP EQU 0x0d ;Temporary store for w register Goto main ;Jump over the interrupt address;***************INTERRUPT ROUTINE***************org 0x04 ;This is where PC points on an interruptmovwf TEMP ;Store the value of w temporarilyincf COUNT,1 ;Increment COUNT by 1, and put the result

;back into COUNTmovlw 0x0A ;Move the value 10 into wsubwf COUNT,0 ;Subtract w from COUNT, and put the result in w

btfss STATUS,0 ;Check the Carry flag. It will be set if ;COUNT is equal to, or is greater than w, and will be set;as a result of the subwf instruction

goto carry_on ;If COUNT is <10, then we can carry ongoto clear ;If COUNT is >9, then we need to clear itcarry_onbcf INTCON,0x01 ;We need to clear this flag to enable more interruptsmovfw TEMP ;Restore w to the value before the interruptretfie ;Come out of the interrupt routineclear clrf COUNT ;Set COUNT back to 0bcf INTCON,1 ;We need to clear this flag to enable more interrupts

retfie ;Come out of the interrupt routine

;*******************Main Program*********************main;*******************Set Up The Interrupt Registers****bsf INTCON,7 ;GIE – Global interrupt enable (1=enable)bsf INTCON,4 ;INTE - RB0 Interrupt Enable (1=enable)bcf INTCON,1 ;INTF - Clear FLag Bit Just In Case;*******************Set Up The Ports******************bsf STATUS,5 ;Switch to Bank 1movlw 0x01movwf TRISB ;Set RB0 as Input

movlw 0x10movwf TRISA ;Set R 0 to RA3 on PortA as Outputbcf STATUS,5 ;Come back to Bank 0;*******************Now Send The Value Of COUNT To Port Aloopmovf COUNT,0 ;Move the contents of Count into Wmovwf PORTA ;Now move it to Port Agoto loop ;Keep on doing thisend ;End Of Program

Page 29: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 29/37

 

Dson 29

Sơ đồ mạch:Bên dưới là sơ đồ mạch mà nó sẽ làm việc với đoạn code bên trên, có 2 thứ mà sơ  đồ mạch đã “ném” ra cho bạn, thứ nhất là mạch này không có tụ điện trong mạch daođộng, cái này là một chút mẹo vặt, bởi vì chúng ta sử dụng các điện dung tản mạn giữachân dao động của con Pic và mass trên mạch điện để thay thế các tụ điện mắc trongmạch dao động, như vậy điện tr ở và điện dung tản mạn trên mạch tạo thành khung dao

động RC, nó có thể sẽ bị thay đổi tuỳ theo cấu hình của mạch điện.Thứ hai có một mạch chống rung cho các cái Switch, cái này thật sự cần thiết, vì khi bạnấn Switch nó sẽ bị rung, lúc đóng lúc hở và con Pic có thể hiểu nhầm r ằng bạn đã ấnSwitch r ất nhiều lần. Với mạch chống rung này, khi bạn ấn Switch tụ điện sẽ nạp khi bạnnhả Switch ra tụ điện sẽ xả từ từ, thời gian xả của tụ điện sẽ bỏ qua các lần rung củaSwitch.

Watchdog Timer:Bây giờ chúng ta bàn v

 

ề một bộ định thời bên trong Pic gọi là Watchdog Timer, vậyWatchdog Timer là cái gì?Giả sử bạn viết một chương trình, bạn mong đợi chương trình này sẽ chạy nếu khôngcó gì tr ục tr ặc xảy ra thì nó sẽ không bao giờ dừng lại, như vậy bạn phải làm một vònglặp để khi chương trình chạy đến điểm cuối thì nó lại quay tr ở về điểm bắt đầu. Nhưngmà hãy xem một tr ường hợp:Giả sử chương trình kiểm tra một chân input, nếu nó lên mức cao thì con Pic sẽ tiếp tụckiểm tra một chân input thứ hai có lên mức cao hay không, nếu chân input thứ haikhông lên mức cao, con Pic sẽ ngồi đó chờ và nó sẽ chỉ  thoát ra khỏi chỗ ngồi của nónếu chân input thứ hai lên mức cao.Bây giờ hãy xem một tr ường hợp khác, giả sử như bạn viết một chương trình, bạn

compiled nó thành công, và ngay cả bạn đã cho chạy mô phỏng từng bước, từng bướcmột trên máy tính, bằng MPLAB chẳng hạn, có vẽ như mọi chuyện đều tốt, bạn đemnạp vào con Pic. Sau một thời gian chạy thử, con Pic thình lình bị kẹt vào nơi nào đótrong chương trình mà không thể thoát ra được tr ạng thái hiện tại. Điều gì là cần thiết để giải quyết hai tr ường hợp trên, reset lại hay vẫn để cho nó bị kẹtkhông thoát ra được ?, đó là mụch đích của mạch watchdog.Mạch watchdog thì không phải là mới mẽ gì, có r ất nhiều microprocessors vàmicrocontrollers đã có mạch watchdog, nhưng mà nó làm việc ra sao?.

Page 30: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 30/37

 

Dson 30

Bên trong con Pic có một mạch RC, mạch này cung cấp 1 xung Clock độc lập với bất kỳ xung Clock nào cung cấp cho Pic. Khi Watchdog Timer (viết tắt là WDT) được cho phép(enabled), nó sẽ đếm bắt đầu từ 00 và tăng lên 1 cho đến FFh, khi nó tăng từ FFh đến00 ( FFh+1) thì con Pic sẽ bị Reset bất kể đang làm gì, chỉ có 1 cách là ngăn không choWDT đếm tới 00.Khi con Pic bị kẹt không thể thoát ra khỏi tình tr ạng hiện tại thì WDT vẫn tiếp tục đếm

mà không bị bất kỳ điều gì ngăn cấm nó đếm tới FF và đến FF+1, vì vậy nó sẽ reset conPic làm cho chương trình phải khởi động lại từ đầu. Để sử dụng WDT chúng ta cần làm 3 việc.Thứ nhất, cần thời gian bao lâu để reset WDT?.Thứ hai, làm sao xoá WDT?.Cuối cùng, chúng ta phải nói cho con Pic biết chương trình cho phép WDT hoạt động.Bây giờ bạn hãy xem từng cái một:Trong Datasheet của con Pic có nói r ằng, WDT có thời gian từ lúc Start cho đến khi kếtthúc là 18ms, tuy nhiên nó cũng phụ thuộc vào vài yếu tố, nguồn cung cấp, nhiệt độ củacon Pic bởi vì mạch dao động của WDT là RC. Tuy nhiên chúng ta cũng có thể làm chothời gian dài hơn. Bên trong con Pic có một cái gọi là Prescaler tạm dịch là đặt tỷ lệ,chúng ta có thể lập trình để chia xung Clock của mạch RC, chúng ta chia RC Clock càng

nhiều thì thời gian WDT reset càng dài.Prescaler nằm trên thanh ghi OPTION có địa chỉ 81h từ bit0 đến bit2, bên dưới là bảngchia tỷ lệ thời gian WDT.

Bit 2 1 0 Rate WDT Time

0 0 0 1:1 18mS0 0 1 1:2 36mS0 1 0 1:4 72mS0 1 1 1:8 144mS1 0 0 1:16 288mS1 0 1 1:32 576mS

1 1 0 1:64 1.1Seconds1 1 1 1:128 2.3Seconds

Hãy nhớ r ằng các khoảng thời gian này không phụ thuộc vào tần số xung Clock bênngoài, nó xác định bằng thời gian thực chứ không phải đếm chu kỳ xung clock.Hãy xem ví dụ WDT sẽ reset con Pic trong khoảng ½ giây khi con Pic bị kẹt.Giá tr ị gần nhất mà ta có theo bảng trên là 576mS hoặc 0.576 seconds. Đầu tiên chúng ta gởi giá tr ị b’101’ tới thanh ghi OPTION, như sau:

movlw b’101’ ;This is 0x05 in Hexmovwf 81h ;This is the Option Register 

Quá đơn giản !, bây giờ, có một mẹo nhỏ.Mặc nhiên prescaler được gán cho một bộ định thời khác, vì vậy ta phải thay đổi toàn bộ WDT. Tr ước tiên phải reset một bộ đếm khác tới giá tr ị 0, sau đó chuyển sang Bank1 để gán prescaler cho WDT và thiết lập thời gian r ồi sau đó lại quay về Bank0, đoạn codebên dưới với xx là giá tr ị ta sẽ chọn cho prescaler.

Bcf STATUS,0 ;make sure we are in Bank 0Clrf 01h ;address of the other timer – TMR0

Page 31: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 31/37

 

Dson 31

Bsf STATUS,0 ;switch to Bank 1Clrwdt ;reset the WDT and prescaler movlw b’1xxx’ ;Select the new prescaler value and assignmovwf OPTION ;it to WDTbcf STATUS,0 ;come back to Bank 0

Lệnh CLRWDT là để xoá WDT, chúng ta phải làm điều này tr ước khi nó reset con Pic,chúng ta cần tính toán nơi nào trong chương trình mà bộ đếm của WDT sẽ tràn để đặtlệnh CLRWDT tr ước thời điểm này để bảo đảm con Pic không reset. Nếu chương trìnhcủa bạn dài, có thể phải đặt hơn 1 lệnh CLRWDT trong chương trình. Ví dụ bạn sử dụng giá tr ị default mặc nhiên là 18ms thì phải bảo đảm r ằng chương trình sẽ nhìn thấylệnh CLRWDT sau mỗi 18ms.Bây giờ chúng ta phải tìm cho ra đoạn code của chúng thực thi trong thời gian thực làbao lâu, nguyên lý thì r ất đơn giản nhưng mà có thể làm cho bạn dựng cả tóc lên đấy !.

Thời gian thực thi Lệnh (Instruction Timing):

Như bạn đã biết, xung nhịp bên trong của Pic được gọi là chu kỳ lệnh, nếu dùng thạchanh 4MHz thì 1 chu kỳ lệnh là 1/(4MHz/4) = 1uS, một số lệnh chỉ  thực thi mất 1 chu kỳ 

trong khi một số lệnh khác mất 2 chu kỳ để thực thi hoàn toàn, bạn hãy xem trong tậplệnh của Pic để biết thêm chi tiết. Cách để nhớ thì hoàn toàn đơn giản, giả sử tất cả cáclệnh đều mất 1 chu kỳ, nhưng mà nếu lệnh đó làm cho chương trình nhảy tới nơi nào đóthì sẽ mất 2 chu kỳ, ví dụ: lệnh MOVWF mất 1 chu kỳ bởi vì lệnh này chỉ mang data từ nơi này sang nơi khác, lệnh GOTO mất 2 chu kỳ bởi vì nó làm cho Program Counter nhảy tới nơi nào đó trong chương trình, Lệnh RETURN cũng mất 2 chu kỳ bởi vì nó làmcho PC quay tr ở về đầu chương trình. Tuy nhiên có 4 lệnh mà nó có thể mất 1 hoặc 2chu kỳ, đó là DECFSZ, INCFSZ, BTFSC và BTFSS, những lệnh này có một điểm chungđó là nó sẽ bỏ qua lệnh kế tiếp nếu nó thoả một điều kiện nào đó, ví dụ: Lệnh DECFSZsẽ giảm giá tr ị trong thanh ghi F xuống 1, nếu kết quả khác 0 thì lệnh kế tiếp được thựcthi, vì vậy nó mất 1 chu kỳ, nhưng nếu kết quả là 0 thì lệnh kế tiếp bị bỏ qua để thực thilệnh đứng sau kế, trong tr ường hợp này lệnh thực thi mất 2 chu kỳ lý do là nó thay đổi

giá tr ị của PC, nó cần 1 chu kỳ để thực hiện hàm và 1 chu kỳ nữa để thay đổi PC đến vị trí thoả điều kiện của hàm. Để rõ ràng hơn, hãy xem ví dụ bên dưới

Movlw 02movwf COUNT

loop decfsz COUNTgoto loopend

Lệnh đầu tiên mov giá tr ị 02 vào thanh ghi W, nó mất 1 chu kỳ, lệnh thứ hai cũng tươngtự, 1 chu kỳ. Lệnh thứ 3, đầu tiên nó giảm COUNT xuống 1, cái này mất 1 chu kỳ, sau

đó nó thử xem COUNT =0 chưa, trong tr ường hợp đầu tiên thì chưa xảy ra COUNT =0 ,vì vậy nó đi tiếp tới lệnh kế, lệnh thứ 4 nhảy đến một cái nhãn, vì vậy nó mất 2 chu kỳ.Chúng ta quay tr ở lại lệnh thứ 3

decfsz COUNTlần này sau khi giảm COUNT xuống 1 thì COUNT =0, lệnh kế tiếp sẽ bị bỏ qua và nónhảy đến End chấm dứt chương trình, hành động bỏ qua lệnh kế tiếp được thực hiệntrong 1 chu kỳ khác, vì vậy khi ta đặt 02 vào COUNT thì chương trình này mất 7 chu kỳ,nếu thạch anh là 4MHZ thì:

Page 32: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 32/37

 

Dson 32

1/(4MHz/4) = 1uS / chu kỳ  7 chu kỳ mất 7 x 1uS = 7uS

Như vậy khi viết chương trình liên quan đến thời gian thực thi, bạn phải tính toán cẩnthận khi dùng các lệnh DECFSZ, INCFSZ, BTFSC và BTFSS.Bên trong con Pic có một thứ gọi là ‘Fuses’ tạm dịch là cầu chì, nó không giống như cầuchì fuses bảo vệ của ổ điện nhà mà nó giống như một cái Switch điện tử được đóng hay

mở bởi lập trình viên. Làm sao mà những cái Fuses này được đóng hay mở để choWDT hoạt động, có 2 cách để làm.Cách thứ nhất là viết 2 dòng lệnh tại phần đầu chương trình để nói cho Pic biếtenable hay disable cái fuses nào đó.Cách thứ hai là nói cho con Pic biết cái fuses nào được enable.

. We will look at getting your program to instruct the programming software in a later tutorial, when we look at including other files and macros. To tell the programmingsoftware manually, varies from program to program. The documentation that came withthe programmer should tell you how to do this. As I am using the PICALLW software,which is linked on my main page, I will explain how to do change fuses within thisprogram. The fuses are configured by pressing the F3 key, or clicking on the ‘Config’

button. Then you can select the fuse you want enabled, in this case the WDT, byclicking on the box next to it.

Sample ProgramLet us write a program, where we will turn on the WDT, and let the PIC perform afunction. We will first of all periodically clear the WDT, to show that the program works,and then remove the CLRWDT command to show that the PIC will indeed reset.The program I have chosen is the one used in tutorial 9 where we cause a row of LEDsto light up one at a time from left to right, then right to left. The circuit is shown below,and with the RC values shown will give us a clock frequency of 8KHz. This clock speedwill allow us to actually see the LEDs moving one by one. I chose this program becauseit is slow enough for us to play with the WDT, and you can easily see when the PIC is

reset. I have removed the original comments, and I have replaced them with adescription of the WDT lines, a running total of the time from the start (assuming a 8KHzclock), and the number of clock cycles at each line.

TIME equ 9FH ; Variable for the delay loop.PORTB equ 06H ; Port B address.TRISB equ 86H ; Port B Tristate address.PORTA equ 05H ; Port A address.TRISA equ 85H ; Port A Tristate address.STATUS equ 03H ; Page select register.

COUNT1 equ 0CH ; Loop register.COUNT2 equ 0DH ; Loop register.bsf STATUS,5 ; 1 cycle, 0.5mSmovlw 00H ; 1 cycle, 1.0mSmovwf TRISB ; 1 cycle, 1.5mSmovlw 00H ; 1 cycle, 2.0mSmovwf TRISA ; 1 cycle, 2.5mSbcf STATUS,5 ; 1 cycle, 3.0mSmovlw 00H ; 1 cycle, 3.5mS

Page 33: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 33/37

 

Dson 33

movwf PORTA ; 1 cycle, 4.0mS; Start of main programRUNmovlw 01H ; 1 cycle, 4.5mSmovwf PORTB ; 1 cycle, 5.0mScall DELAY ; 2 cycles, 486mS

call DELAY ; 2 cycles, 967mS; Move the bit on Port B left, then pause.rlf PORTB,1 ; 1 cycle, 967.5mScall DELAY ; 2 cycles, 1.45Scall DELAY ; 2 cycles, 1.93Srlf PORTB,1 ; 1 cycle, 1.93Scall DELAY ; 2 cycles, 2.41Scall DELAY ; 2 cycles, 2.89Srlf PORTB,1 ; 1 cycle, 2.89Scall DELAY ; 2 cycles, 3.37Scall DELAY ; 2 cycles, 3.85Srlf PORTB,1 ; 1 cycle, 3.85S

call DELAY ; 2 cycles, 4.34Scall DELAY ; 2 cycles, 4.82Srlf PORTB,1 ; 1 cycle, 4.82Scall DELAY ; 2 cycles, 5.30Scall DELAY ; 2 cycles, 5.78Srlf PORTB,1 ; 1 cycle, 5.78Scall DELAY ; 2 cycles, 6.26Scall DELAY ; 2 cycles, 6.74Srlf PORTB,1 ; 1 cycle, 6.74Scall DELAY ; 2 cycles, 7.22Scall DELAY ; 2 cycles, 7.70Srlf PORTB,1 ; 1 cycle, 7.70S

; Now move onto Port A, and move the bit left.rlf PORTA,1 ; 1 cycle, 7.70Scall DELAY ; 2 cycles, 8.19Scall DELAY ; 2 cycles, 8.67Srlf PORTA,1 ; 1 cycle, 8.67Scall DELAY ; 2 cycles, 9.15Scall DELAY ; 2 cycles, 9.63Srlf PORTA,1 ; 1 cycle, 9.63Scall DELAY ; 2 cycles, 10.11Scall DELAY ; 2 cycles, 10.59Srlf PORTA,1 ; 1 cycle, 10.59Scall DELAY ; 2 cycles, 11.07S

call DELAY ; 2 cycles, 11.55S; Move the bit back on Port Arrf PORTA,1 ; 1 cycle, 11.55Scall DELAY ; 2 cycles, 12.04Scall DELAY ; 2 cycles, 12.52Srrf PORTA,1 ; 1 cycle, 12.52Scall DELAY ; 2 cycles, 12.99Scall DELAY ; 2 cycles, 13.48Srrf PORTA,1 ; 1 cycle, 13.48S

Page 34: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 34/37

 

Dson 34

call DELAY ; 2 cycles, 13.96Scall DELAY ; 2 cycles, 14.44Srrf PORTA,1 ; 1 cycle, 14.44S; Now move the bit back on Port Brrf PORTB,1 ; 1 cycle, 14.44Scall DELAY ; 2 cycles, 14.92S

call DELAY ; 2 cycles, 15.40Srrf PORTB,1 ; 1 cycle, 15.40Scall DELAY ; 2 cycles, 15.89Scall DELAY ; 2 cycles, 16.37Srrf PORTB,1 ; 1 cycle, 16.37Scall DELAY ; 2 cycles, 16.84Scall DELAY ; 2 cycles, 17.33Srrf PORTB,1 ; 1 cycle, 17.33Scall DELAY ; 2 cycles, 17.81Scall DELAY ; 2 cycles, 18.29Srrf PORTB,1 ; 1 cycle, 18.29Scall DELAY ; 2 cycles, 18.77S

call DELAY ; 2 cycles, 19.25Srrf PORTB,1 ; 1 cycle, 19.25Scall DELAY ; 2 cycles, 19.73Scall DELAY ; 2 cycles, 20.22Srrf PORTB,1 ; 1 cycle, 20.22Scall DELAY ; 2 cycles, 20.70Scall DELAY ; 2 cycles, 21.18S

goto RUN ; 2 cycles, 21.18S; Subroutine to give a delay between bit movements.;Total of 957 cycles, 480mSDELAY

movlw TIME ; 1 cyclemovwf COUNT1 ; 1 cycle

LOOP1 ;decfsz COUNT1 ; 9F x 1 cycle + 1 cycle = 160 cyclesgoto LOOP1 ; 9E x 2 cycles = 316 cyclesmovwf COUNT1 ; 1 cycle

LOOP2 ;decfsz COUNT1 ; 9F x 1 cycle + 1 cycle = 256 cyclesgoto LOOP2 ; 9E x 2 cycles = 316 cycles

return ; 2 cyclesEND ;

With an 8KHz clock, it takes just under 1 second for the next LED illuminates, and ittakes a total of about 21 seconds to run from one end to the other and back again i.e. togo through the routine once only. The delay routine takes 480mS, and we are calling ittwice before moving the bit on the Ports. Now, we need to periodically reset the WDT.The largest time we can set the WDT is 2.3 seconds, and the next one down form this is1.1 seconds. We have two options here. We could make a call to a subroutine to clear 

Page 35: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 35/37

 

Dson 35

the WDT after the two delays have finished, or we could incorporate the CLRWDT withinthe delay itself. I have decided, for no real reason at all, to incorporate the CLRWDTwithin the delay loop.

TIME equ 9FH ; Variable for the delay loop.PORTB equ 06H ; Port B address.

TRISB equ 86H ; Port B Tristate address.PORTA equ 05H ; Port A address.TRISA equ 85H ; Port A Tristate address.STATUS equ 03H ; Page select register.COUNT1 equ 0CH ; Loop register.COUNT2 equ 0DH ; Loop register.OPT equ 81h ; Option Register to control the WDT

;*************Set up the Ports, WDT and prescaler******************clrf 01h ;Clear TMR0bsf STATUS,5 ;Switch to Bank 1clrwdt ;reset the WDT and prescaler 

movlw b’1101’ ;Select the new prescaler value and assignmovwf OPT ;it to WDT

movlw 00H ; Now set up the Portsmovwf TRISB ;movlw 00H ;movwf TRISA ;bcf STATUS,5 ;Come back to Bank 0movlw 00H ;movwf PORTA ;

;*************Start of main program*****************************

RUNmovlw 01H ;movwf PORTB ;call DELAY ;call DELAY ;; *************Move the bit on Port B left, then pause.**************rlf PORTB,1 ;call DELAY ;call DELAY ;rlf PORTB,1 ;call DELAY ;call DELAY ;

rlf PORTB,1 ;call DELAY ;call DELAY ;rlf PORTB,1 ;call DELAY ;call DELAY ;rlf PORTB,1 ;call DELAY ;call DELAY ;

Page 36: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 36/37

 

Dson 36

rlf PORTB,1 ;call DELAY ;call DELAY ;rlf PORTB,1 ;call DELAY ;call DELAY ;

rlf PORTB,1 ;; *************Now move onto Port A, and move the bit left.***********rlf PORTA,1 ;call DELAY ;call DELAY ;rlf PORTA,1 ;call DELAY ;call DELAY ;rlf PORTA,1 ;call DELAY ;call DELAY ;rlf PORTA,1 ;

call DELAY ;call DELAY ;;************** Move the bit back on Port A************************rrf PORTA,1 ;call DELAY ;call DELAY ;rrf PORTA,1 ;call DELAY ;call DELAY ;rrf PORTA,1 ;call DELAY ;call DELAY ;

rrf PORTA,1 ;;****************** Now move the bit back on Port B******************rrf PORTB,1 ;call DELAY ;call DELAY ;rrf PORTB,1 ;call DELAY ;call DELAY ;rrf PORTB,1 ;call DELAY ;call DELAY ;rrf PORTB,1 ;

call DELAY ;call DELAY ;rrf PORTB,1 ;call DELAY ;call DELAY ;rrf PORTB,1 ;call DELAY ;call DELAY ;rrf PORTB,1 ;

Page 37: Tai Lieu Dich ASM PIC Rat Hay

5/8/2018 Tai Lieu Dich ASM PIC Rat Hay - slidepdf.com

http://slidepdf.com/reader/full/tai-lieu-dich-asm-pic-rat-hay 37/37

 

Dson 37

call DELAY ;call DELAY ;

goto RUN ;

; ******************Subroutine to give a delay between bit movements.******

DELAYmovlw TIME ;movwf COUNT1 ;

LOOP1 ;decfsz COUNT1 ;goto LOOP1 ;movwf COUNT1 ;LOOP2 ;decfsz COUNT1 ;goto LOOP2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; This part resets the WDT ;;;;Comment out or remove this command to see the WDT ;;;; in action. It should reset the PIC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;clrwdt ;This simply resets the WDT.

;***************Return from our original DELAY routine***************return ;END ;

If you comment out, or remove the CLRWDT command, you will find that the PIC will not

go past lighting the second LED. This is because the WDT is resetting the PIC. Withthe CLRWDT in place, the program works as it should.