PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Pic16f877a TỪ DỄ TỚi KhÓ (http://www.picvietnam.com/forum/showthread.php?t=238)

ntc 04-12-2005 01:28 PM

Pic16f877a TỪ DỄ TỚi KhÓ
 
Chào cả làng!


Luồng thứ hai là luồng “PIC16F877A! Nào ta cùng chat!”. Rút kinh nghiệm cái luồng “Học PIC trong vòng một ngày” của bác Falleaf, tui tạo ra them một luồng nữa để cho các bạn thảo luận, thắc mắc và … nói nhảm. Như vậy các bạn sẽ dễ dàng theo dõi các bài viết trong luồng “PIC16F877A TỪ DỄ TỚI KHÓ”, đồng thờI giảm bớt sự luộm thuộm, lung tung cho các luồng trong trang web của chúng ta.

Rất mong các bạn tuân thủ đúng qui định trên để đảm bảo mục đích chung của các luồng.

Qyuết định như vậy đi. Hehe. trị thấy tui làm vậy có được không vậy? Nhớ cho biết ý kiến nghe.

Chào thân ái! Chúc cả làng PICVietnam một ngày chủ nhật vui vẻ! ;)

falleaf 04-12-2005 08:13 PM

Tuần tới, anh sẽ cung cấp mạch phát triển của PIC16F877A cho nhóm PIC ở HCM làm, sau khi có các kết quả thực hành, anh sẽ cung cấp các bài viết chi tiết về mạch phát triển cho PIC16F877A.

Tuy nhiên, trong giai đoạn này, em nên đưa ra một số mạch ứng dụng cụ thể, theo từng bài học cụ thể, các source code và các mạch cần phải cung cấp theo từng bài liên tục, không viết tràn lan, và tránh đi sai mục tiêu.

Trước tiên, em nên chỉ rõ hướng em sẽ đi, để người đọc dễ theo dõi, khi luồng này phát triển và có nhiều người quan tâm, em dán nó lên để cho mọi người dễ thấy.

Chúc vui.

ntc 04-12-2005 10:45 PM

OK! Phản hồi như vậy là được rồi. Tui sẽ làm tới nới tới chốn cái dzụ này.

Nói thiệt là tui cũng chẳng phải là tiền bối gì, chỉ có biết tới đâu thì viết tới đó thôi.

Ghi nhận ý kiến của bác falleaf. Em sẽ tổ chức lại cái tài liệu em gửi cho bác thành từng bài nhỏ có liên quan cụ thể với nhau, chuyển qua pdf và post lên. Việc này cứ để em làm, bác chỉ cần viếng thăm đều đều để có ý kiến ý cò là được rồi.

Mục đích của luồng này trước hết là giúp các bạn làm quen từ từ với PIC16F877A. Trong thời gian đầu, tui sẽ cố gắng viết bài càng chi tiết càng tốt (từ mạch test cho tới chương trình cụ thể) để các bạn có thể làm quen với con PIC này một cách dễ dàng. Sau bước đầu làm quen, các bài viết sẽ mang tính chất đặt vấn đề để tất cả cùng giải quyết, chúng ta sẽ đi theo hướng làm việc dựa trên quá trình tìm hiểu các datasheet của cái mà mình muốn điều khiển, rồi sau đó mới đưa ra phương pháp điều khiển cụ thể cho nó.

Các bài viết sẽ đi theo trình tự từ dễ tới khó, và để tiện cho việc thảo luận, các bài viết sẽ được đánh số rõ ràng, như vậy bên cái luồng "PIC! Nào ta cùng chat!", muốn thảo luận về bài nào ta chỉ cần nói số thứ tự của cái bài đó ra là mọi người sẽ biết. Mỗi bài sẽ chỉ đi sâu vào một ứng dụng cụ thể, các thông tin cung cấp trong mỗi bài sẽ có tính tập trung cao để các bạn dễ theo dõi.

ntc 05-12-2005 09:14 PM

Bài tui viết xong rồi, nhưng dang chờ mấy tiền bối xét duyệt và điều chỉnh. Trong khi chờ đợi, tui sẽ đưa ra cái mục lục của các bài sắp được post lên. Trong quá trình viết bài có thể sẽ có vài điều chỉnh nhỏ, nhưng định hướng các bài viết sẽ là như vậy. Bài nào có điều chỉnh khác với mục lục tui sẽ đề cập cụ thể:

Bài 1 Điều khiển các port I/O
Bài 2 Chương trình delay
Bài 3 Một số ứng dụng xuất/nhập qua các port của vi điều khiển (bài này
khá dài nên có khả năng sẽ được chia ra thành nhiều bài nhỏ).
Bài 4 Điều khiển IC ghi dịch 74HC595
Bài 5 PIC16F877A và LED 7 đoạn (bài này cũng khó khả năng được chia ra)
Bài 6 Ngắt và cấu trúc của một chương trình ngắt dành cho vi điều khiển
PIC16F877A
Bài 7 Các Timer của vi điều khiển PIC16F877A
Bài 8 Timer và hoạt động định thời
Bài 9 Ứng dụng tổng hợp (coi như là một bài tập để ôn lại tất cả các bài
trước, tui cho rằng bài này sẽ khá thú vị, hehe)
Bài 10 Điều khiển LCD

Tạm thời là như vậy cái đã. Các bạn thấy cái mục lục như vậy đã đủ hấp dẫn chưa?? Hay phải thêm bớt cái gì nữa??

tuanva 08-12-2005 01:07 PM

Theo tôi nên bổ xung thêm phần Serial Communication

Quygia 09-12-2005 04:16 AM

Và thêm phần AD converter, giáo trình PIC tiếng Anh và những thứ liên quan, kể cả một cuốn note book cho 16F877 tui có nhiều, có điều không hiểu giữa A và không A, có khác nhau gì không hả bác ntc

ntc 09-12-2005 06:00 PM

Cai A hay khong A thi bac Falleaf da tra loi roi. Co A thi bo nho chuong trinh cua no la bo nho Flash, con khong co A thi bo nho chuong trinh cua no la bo nho EEPROM.

Hehe, bai dau tien chinh sua hoi nhieu (vi chua the lam hai long cac vi tien boi) nen cac ban chiu kho doi mot hai bua nua di.

Con viec nay nua, lam on chuyen qua cai luong "PIC16F877A!Nao ta cung chat". Hehe, tui bat dau thay cai luong nay hoi lon xon roi do.

falleaf 09-12-2005 08:18 PM

Em dang làm mod của box này mà, em có quyền sử dụng các chức năng điều khiển trong box của em, để di chuyển bài viết, cắt dán bài viết....

Các bạn cố gắng chuyển luồng để post bài, để tránh mod phải làm việc nhiều.

Chúc vui.

ntc 10-12-2005 12:55 PM

1 Attachment(s)
NÓ ĐÂY! Hehe. Bài đầu tiên.

Hy vọng sau khi đọc xong bài này, các bạn sẽ nhận ra rằng đây không phải là tài liệu dịch hay copy từ đâu đó.

Các bạn đọc xong nhớ cho biết ý kiến nghe, cách viết của tui như vậy đọc có thấy dễ hiểu không.

Bài này là bài cơ bản và khá đơn giản và được viết khá kĩ, hy vọng các bạn có thể hiểu được một cách dễ dàng và thực hiện thành công ứng dụng trong bài.

Còn nữa, tui nhắc lại lần cuối cùng, qua cái luồng "PIC16F877A!NÀO TA CÙNG CHAT" rồi mình cùng thảo luận, hehe, nếu không thì tui bắt buộc phải dùng tới ... vũ lực à nghe.

tinhthanthep 25-12-2005 11:50 PM

Bài 1 của bác hay lắm, đọc dễ hiểu. Bác có thể viết tiếp về ngắt, timer, counter, comparator, PWM... Đây mới là những phần đáng để ngâm cứu.

minhtienbk 06-01-2006 12:31 AM

sao trong doan code ko có phần khai báo hả anh ,ví dụ trisb equ 03h chẳng hạn ,em vẫn ko hiểu ,anh chỉ giùm !

acom 09-01-2006 04:14 PM

Cam on ban ntc ve bai viet do. Rat co ban va chi tiet. Dieu nay se giup cho nguoi moi tim hieu ve PIC co cai nhin don gian ve PIC hon. Mong bac co nhieu bai viet moi de giup anh em trong dien dan tiep can voi PIC nhanh hon.

tinhthanthep 09-01-2006 08:29 PM

Trích:

Nguyên văn bởi minhtienbk
sao trong doan code ko có phần khai báo hả anh ,ví dụ trisb equ 03h chẳng hạn ,em vẫn ko hiểu ,anh chỉ giùm !

----------------------

cần gì phải khai báo. vì trong chương trình có tác động trực tiếp lên trisb rồi.
movfw b'00000000'
movwf trisb
mplap sẽ tự hiểu trisb nằm ở địa chỉ 03h

falleaf 10-01-2006 03:12 PM

Chính đang phải đi mổ chân, cho nên không thể viết bài tiếp được, hôm nọ anh quên mất vì quá nhiều việc.

Mọi người thông cảm. Khi nào Chính hồi phục sẽ viết bài tiếp cho các bạn học.

Chúc vui.

ntc 04-02-2006 04:57 PM

Chào năm mới. Chúc mọi người một năm mới vui vẻ, hạnh phúc, và thành đat.
Đây là bài viết thứ hai, mời mọi người cùng xem.

http://www.picvietnam.com/download/T...TCR.300106.pdf

nily 05-02-2006 10:01 AM

cảm ơn nhiều ,chúc mau bình phục và chúc mừng năm mới luôn .

hungkhanh 05-02-2006 10:55 PM

Trong bài 2, có một đoạn code mình không hiểu cho lắm?

Code:

Đoạn chương trình 2:
MOVLW d’255’
MOVWF delay‐reg1 ; đưa giá trị 255 vào thanh ghi “delay‐reg1”
loop
DECFSZ delay‐reg1,0 ; giảm giá trị thanh ghi “delay‐reg1”và so sánh với 0
GOTO loop1 ; nếu chưa bằng 0 nhảy tới label “loop1”
GOTO next ; nếu đã băng 0 chương trình delay hoàn tất
loop1
MOVLW d’255’
MOVWF delay‐reg2 ; đưa vào thanh ghi “delay‐reg2” giá trị 255
DECFSZ delay‐reg2,0 ; giảm giá trị thanh ghi “delay‐reg2” và so sánh với 0
MOVWF loop1 ; nếu chưa bằng 0 thì nhảy đến label “loop1”
GOTO loop ; nếu bằng 0 thì nhảy đến label “loop”
next

Thử phân tích một chút. Bây giờ ta sẽ xem xét đoạn code sau chạy từ đầu như thế nào

Code:

MOVLW d’255’
MOVWF delay‐reg1 ; đưa giá trị 255 vào thanh ghi “delay‐reg1”
loop
DECFSZ delay‐reg1,0 ; giảm giá trị thanh ghi “delay‐reg1”và so sánh với 0; GIÁ TRỊ ĐƯỢC GHI TRONG DELAY-REG1 GIẢM 1 THÀNH 244, SAU ĐÓ GIÁ TRỊ 244 ĐƯỢC GHI VÀO W-REGISTER, CÒN GIÁ TRỊ ĐƯỢC GHI TRONG DELAY-RED1 VẪN GIỮ NGUYÊN LÀ 255
GOTO loop1 ; nếu chưa bằng 0 nhảy tới label “loop1”
GOTO next ; nếu đã băng 0 chương trình delay hoàn tất
loop1
MOVLW d’255’
MOVWF delay‐reg2 ; đưa vào thanh ghi “delay‐reg2” giá trị 255
DECFSZ delay‐reg2,0 ; giảm giá trị thanh ghi “delay‐reg2” và so sánh với 0. TƯƠNG TỰ NHƯ TRÊN, GIÁ TRỊ ĐƯỢC DÁN CHO DELAY-REG2 SAU KHI THỰC HIỆN LỆNH NÀY VẪN LÀ 255
MOVWF loop1 ; nếu chưa bằng 0 thì nhảy đến label “loop1”
GOTO loop ; nếu bằng 0 thì nhảy đến label “loop”
next

Dó đó, đoạn code sau sẽ delay với khoảng thời gian là infinity.

Đoạn code sau sẽ đúng ghi ta thay đổi 0 thành 1 để sau khi thực hiện kệnh, giá trị sẽ được ghi vào file register. Ngoài ra, còn một chỗ không ổn ở chỗ loop1. Thử phân tích:

- Đầu tiên gán giá trị 255 vào dalay-reg2.
- giảm giá trị của delay-reg2 và so sánh với 0, nếu khác 0 thì thực hiện lệnh tiếp theo. (do ban đầu giá trị là 255 nên giảm 1 còn 254, khác 0 nên sẽ thực hiệ lênh tiếp theo, tức goto loop1)
- lại set giá trị của delay-reg2 là 255.
- giảm gias trị đi 1 và so sánh với 0.
....
như vậy, riêng loop1 cũng thực với với thời gian là infinity dù ở lệnh DECFSZ có để giá trị tham số là 1 hay 0.

vì vậy, ngoài sửa lại giá trị tham số của lệnh DECFSZ từ 0 thành 1, cần đưa phần gán giá trị 255 cho delay-reg2 ra ngoài vòng lặp, đặt nó ở cùng vị trí với chỗ gán giá trị 255 cho delay-reg1.

chắc là NTC đau chân quas nên không chú ý chỗ này ;D


Btw, cho mình hỏi một câu rất dở hơi, thạch anh tên tiếng Anh là gì vậy? có bạn nào giải thích cho mình biết thạch anh là gì không, mình hiểu nó là dùng để tạo xung, nhưng cụ thể hơn thì không biết. Mong được giúp đỡ.

falleaf 06-02-2006 09:40 AM

Xin lỗi các bạn, đoạn chương trình trên đã có sự nhầm lẫn, F đã được báo về vẫn đề lỗi chương trình ngay từ hôm đầu NTC post lên, nhưng vẫn không có thời gian sửa chữa chương trình. Có lẽ các bạn vào đây thường xuyên thì cũng biết F đang làm việc gì. Vì vậy, thành thật xin lỗi các bạn vì sự lầm lẫn trên.

Nếu bạn nào có thời gian, xin sửa chữa giúp đoạn code trên để bạn đọc không bị vướng vào lỗi sai này nữa.

Chúc vui.

falleaf 06-02-2006 10:07 AM

Code:

MOVLW d’255’
MOVWF delay‐reg1 ; đưa giá trị 255 vào thanh ghi “delay‐reg1”
loop
DECFSZ delay‐reg1,0 ; giảm giá trị thanh ghi “delay‐reg1”và so sánh với 0
GOTO loop1 ; nếu chưa bằng 0 nhảy tới label “loop1”
GOTO next ; nếu đã băng 0 chương trình delay hoàn tất
loop1
MOVLW d’255’
MOVWF delay‐reg2 ; đưa vào thanh ghi “delay‐reg2” giá trị 255
DECFSZ delay‐reg2,0 ; giảm giá trị thanh ghi “delay‐reg2” và so sánh với 0
MOVWF loop1 ; nếu chưa bằng 0 thì nhảy đến label “loop1”
GOTO loop ; nếu bằng 0 thì nhảy đến label “loop”
next

Xin lỗi các bạn vì hiện nay diễn đàn đang được sửa chữa, vì vậy không thể trình bày tốt được.

F sửa luôn đoạn code trên để tránh các bạn mắc lỗi sai. Bản sửa sẽ được NTC cập nhật lại sau:

Code:

MOVLW d’255’
MOVWF delay_reg1 ; đưa giá trị 255 vào thanh ghi “delay_reg1”
loop
DECFSZ delay_reg1, F ; giảm giá trị thanh ghi “delay_reg1”và so sánh với 0 và ghi lại vào delay-reg1
GOTO loop1 ; nếu chưa bằng 0 nhảy tới label “loop1”
GOTO next ; nếu đã băng 0 chương trình delay hoàn tất
loop1
MOVLW d’255’
MOVWF delay_reg2 ; đưa vào thanh ghi “delay_reg2” giá trị 255

DECFSZ delay_reg2, F ; giảm giá trị thanh ghi “delay_reg2” và so sánh với 0 và ghi lại vào delay_reg2
GOTO $-1 ; nếu chưa bằng 0 thì nhảy lên trên để tiếp tục giảm delay_reg2
; vòng lặp này nhằm giảm delay_reg2 về đến 0
; thời gian giảm delay_reg2 chính là thời gian delay_trong vòng lặp con.
GOTO loop ; nếu bằng 0 thì nhảy đến label “loop”
next

Cách viết hai:

À thôi, H hiểu vì sao NTC viết sai rồi... oki,

để F nói NTC sửa lại sau ... sorry cả nhà...

Chúc vui...

falleaf 06-02-2006 10:18 AM

Trong cách viết trên, F cũng đồng thời chỉ ra hai cách viết cho lệnh GOTO.

Code:

LOOP  GOTO    LOOP


Code:

GOTO  $
Hai cách viết này tương đương nhau. Trong đó, $ thay cho vị trí con trỏ tại vị trí lệnh đang thực hiện.

Chính vì vậy, trong đoạn code trên, thay vì viết

Code:

loop
DECFSZ delay_reg1, F ; giảm giá trị thanh ghi “delay_reg1”và so sánh với 0 và ghi lại vào delay-reg1
GOTO loop1 ; nếu chưa bằng 0 nhảy tới label “loop1”
GOTO next ; nếu đã băng 0 chương trình delay hoàn tất
loop1
...

Chúng ta co thể thay thành:

Code:

loop
DECFSZ delay_reg1, F ; giảm giá trị thanh ghi “delay_reg1”và so sánh với 0 và ghi lại vào delay-reg1
GOTO $+2 ; nếu chưa bằng 0 nhảy tới label “loop1”
GOTO next ; nếu đã băng 0 chương trình delay hoàn tất
...

Và đoạn code phía dưới:

Code:

loop1
MOVLW d’255’
MOVWF delay_reg2 ; đưa vào thanh ghi “delay_reg2” giá trị 255

DECFSZ delay_reg2, F ; giảm giá trị thanh ghi “delay_reg2” và so sánh với 0 và ghi lại vào delay_reg2
GOTO $-1 ;
...

chúng ta co thể thay lại thành:

Code:

loop1
MOVLW d’255’
MOVWF delay_reg2 ; đưa vào thanh ghi “delay_reg2” giá trị 255
loop2
DECFSZ delay_reg2, F ; giảm giá trị thanh ghi “delay_reg2” và so sánh với 0 và ghi lại vào delay_reg2
GOTO loop2;
...

Chúc vui.

ntc 06-02-2006 01:53 PM

Cảm ơn bạn hungkhanh đã phát hiện ra các lỗi sai của bài 2. Xin lỗi cả làng nghe, mình sẽ chỉnh sửa lại gấp.

ntc 10-02-2006 10:37 AM

1 Attachment(s)
Đây là bản đã được chỉnh sửa. Phần chỉnh sửa là phần tô màu đỏ trong tài liệu. Mọi người dowwnload lại rồi xem luôn nhé.

nhh 12-02-2006 01:19 PM

Bác ntc post tiếp các phần tiếp theo cho anh em tham khảo!Đợi bác mãi sốt ruột quá!

nhh 14-02-2006 08:08 AM

BẬT TẮT LED 1s

Code:

;========================================
;Auhor:                NHH
;Date:                10/02/06
;Hardware:        PIC16F877A
                ;XTAL 10MHz, PORTB noi voi 8 LED qua 8 dien tro 220Ohm
;========================================
        TITLE                "ON-OFF LED 1 SECOND"
        PROCESSOR        PIC16f877A
        INCLUDE<P16f877A.inc>
        __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _CPD_OFF &_LVP_OFF
;=============================================================================       
        COUNT1 EQU 0x20
        COUNT2 EQU 0x21
        COUNT3 EQU 0x22
;=========================CHUONG TRINH CHINH=========================
        ORG 0x000
        GOTO        MAIN

MAIN
        BCF STATUS,RP1
        BSF STATUS,RP0                ; select BANK 1
        CLRF TRISB                ; PORTB output
        BCF STATUS,RP0                ;  select BANK 0

        MOVLW        d'255'
        MOVWF        COUNT1                ;<-COUNT1=255       
        MOVWF        COUNT2                ;<-COUNT2=255
NEXT       
        MOVLW        d'14'
        MOVWF        COUNT3                ;<-COUNT3=13
        MOVLW        b'11111111'        ;LED ON
        MOVWF        PORTB
        CALL        LOOP

        MOVLW        d'14'
        MOVWF        COUNT3                ;<-COUNT3=13
        MOVLW        b'00000000'        ;LED OFF
        MOVWF        PORTB       
        CALL        LOOP
       
        GOTO        NEXT               
;========================CHUONG TRINH CON====================
LOOP
        DECFSZ        COUNT1,1
        GOTO        LOOP
        DECFSZ        COUNT2,1
        GOTO        LOOP
        DECFSZ        COUNT3,1
        GOTO        LOOP               
        RETURN
               
        END


nhh 14-02-2006 08:10 AM

;hex File
;====================
:020000040000fa
:1000000001280313831686018312ff30a000a1008c
:100010000d30a200ff30860013200d30a20000300a
:10002000860013200828a00b1328a10b1328a20b6d
:040030001328080089
:02400e00323f3f
:00000001ff

falleaf 14-02-2006 10:01 AM

Ai phân tích đoạn chương trình này nào?

Lưu ý là có đoạn goto LOOP về chung, và lưu ý rằng khi 0 - 1 = 255 <> 0, nên sẽ không bị nhảy về LOOP trở lại nhé

Công thức tính thời gian delay ở đây được tính như thế nào? Mời các bạn tham gia tính toán con số chính xác.

Chúc vui.

ntc 15-02-2006 01:19 PM

Ặc ăc !! Viết chương trình delay như vậy thì tính thời gian delay cũng chua lắm đó. Bà con thử phân tích coi. Đây cũng là một đề bài thú vị. Chú ý là mhh sử dụng thạch anh 10 MHz.
nhh đã nạp vào PIC và chạy thử chưa. Nhìn sơ qua có cái gì đó không ổn.

falleaf 15-02-2006 02:49 PM

Cách tính khá đơn giản, không phải quá khó đâu em, anh đã viết gợi ý rồi, nhưng xoá đi để mọi người cùng thảo luận.

Anh cũng chưa tính ra con số cụ thể, nhưng nếu biết cách tính khéo léo thì rất là hay. Đoạn code này là một thủ thuật viết hàm delay khá thú vị.

Bây giờ giả sử loop 3 vòng như thế này, các giá trị count1, count2, count3 là a, b, và c. Vậy công thức tổng quát của còng lặp này là bao nhiêu chu kỳ máy?

Đây là câu hỏi!

Chúc vui.

falleaf 15-02-2006 02:52 PM

Tất nhiên, phải chỉ ra điều kiện ràng buộc của a, b và c. Nếu như mình làm 1 vòng, 2 vòng, 3 vòng lặp thì giá trị a, b, c phải là bao nhiêu?

Chúc vui.

nhh 17-02-2006 09:06 AM

Trích:

Nguyên văn bởi ntc
Ặc ăc !! Viết chương trình delay như vậy thì tính thời gian delay cũng chua lắm đó. Bà con thử phân tích coi. Đây cũng là một đề bài thú vị. Chú ý là mhh sử dụng thạch anh 10 MHz.
nhh đã nạp vào PIC và chạy thử chưa. Nhìn sơ qua có cái gì đó không ổn.

nhh đã chạy thử rồi mới dám post lên chứ!Bác ntc thử chạy xem sao?

nhh 17-02-2006 09:59 AM

Nếu sử dụng vòng lặp như thế này với giá trị nạp vào của count1,count2,count3 là a,b,c:
------------------------------
LOOP
DECFSZ COUNT1,1
GOTO LOOP
DECFSZ COUNT2,1
GOTO LOOP
DECFSZ COUNT3,1
GOTO LOOP
RETURN
------------------------------
Khi count1 giảm đến 0,sau đó giảm count2 xuống 1 và quay về LOOP
count1 giảm thêm 1 nên sẽ là 255.Do vậy giá trị a không có ý nghĩa.
Tương tự giá trị b cũng vậy.

THỜI GIAN CHO VÒNG LẶP LOOP NÀY:

Khi con trỏ đang ở dòng DECFSZ COUNT2,1 thì count1 có giá trị 0
Khi con trỏ đang ở dòng DECFSZ COUNT3,1 thì count1,count2 đều có giá trị 0

1) DECFSZ COUNT1,1 mất 1 chu kỳ máy
GOTO LOOP mất 2 chu kỳ máy
Để count1 giảm từ 0 về 1 mất 255*3 chu kỳ máy,giảm từ 1 về 0 mất thêm 1 chu kỳ máy nữa.Bây giờ con trỏ đang ở dòng DECFSZ COUNT2,1
Vậy thời gian đã thực thi là :
(255*3 + 1)*t (t là thời gian thực thi 1 chu kỳ máy)

2) Mỗi lần count2 giảm 1 thì lại quay lại giảm count1
Thời gian giảm count2 cũng tính tương tự
Vậy khi con trỏ ở DECFSZ COUNT3,1 thì thời gian đã thực thi là:
((255*3 + 1)*t)*255 + (255*3 + 1)*t

3) Tương tự tính cho giảm count3 từ c về 0.
Vậy thời gian cho vòng lặp LOOP sẽ là:
{[(255*3 + 1)*t]*255 + (255*3 + 1)*t}*(c-1) + [(c-1)*3 + 1]*t
= {{[(255*3 + 1)]*255 + (255*3 + 1)}*(c-1) + (c-1)*3 + 1}*t
= [(766*255 + 766)*(c-1) + (c-1)*3 + 1]*t
= [196096*(c-1) + (c-1)*3 + 1]*t
= (196099*c - 196098)*t

Với c = 14 ,t = 0,4us thời gian này là (196099*14 - 196098)*0.4us = 1.02s

Chắc không khó khăn gì để tính thời gian lặp kiểu này với n biến count!

nhh 17-02-2006 10:18 AM

Bác NTC hay bác F có thể post bài hướng dẫn tiếp về ngắt,timer,PWM,....cho anh em tham khảo được không ?
Đợi bài của các bác!

ntc 17-02-2006 11:23 AM

Thú vị thiêt. Tuy là cách tính có vẻ rắc rối, nhưng công thức cuối cùng lại rất đơn giản. Tính để một hai bữa nữa cho bà con ngâm cứu rồi trả lời mà nhh đã tự bật mí rồi.

falleaf 17-02-2006 11:27 AM

Một điểm chú ý là, giữa các vòng lặp sau, thì điểm khởi đầu của count1 và count2 luôn luôn là 0. Vì vậy, để đảm bảo lần thứ nhất chạy đúng, thì giá trị khởi tạo phải là 0. Như vậy, a = b = 0.

Nếu như có N vòng lồng nhau, thì giá trị các vòng trước đó là count1,2...n-1 = 0.

Nếu không đặt như vậy, thì lần đầu tiên chạy sẽ bị sai. Khi đem ứng dụng vào những bài toán khác, không phải là nhấp nháy led, thì việc không cẩn thận này rất nguy hiểm.

Khi có độ lệch về thời gian trong các vòng lặp, phải chọn mức thấp hơn.

Vd: không chọn c = 14 để vòng lặp là 1.02s mà phải chọn c =13, sau đó dùng một đoạn code khác để bù vào vòng lặp này.

Như vậy, chúng ta sẽ có chính xác thời gian thực.

Một thủ thuật nhỏ của việc viết vòng lặp này đó là cài đặt lại giá trị ở vòng lặp thứ n-1, trong trường hợp này là cài đặt lại giá trị của count2 mỗi khi count3 giảm đi 1 đơn vị. Có nghĩa là chỉ cần thực hiện một lệnh DECF cho count2 trước khi giảm count3.

Khi đó count2 luôn giảm từ 254 xuống. Mất 1 lệnh, hệ số trước count2 lại nhân 3. Như vậy, mình giảm được 2 lệnh. Tính lên vòng lặp trên, lại giảm được 255*3 ..

Vậy chỉ cần thêm một lệnh giảm, thì sẽ giảm ít hơn là giảm count3 1 đơn vị. Cái này là do độ phân giải mình muốn.

Bạn thử dùng lại cách này, và tính chính xác lại thời gian, sau đó bù lại sao cho nó đáp ứng đúng 1s thử xem?

Chúc vui

tinhthanthep 20-02-2006 01:29 PM

Tiến tới Timer, ngắt và PMW đi thôi các bác.

ngkdong 21-02-2006 07:24 AM

Ban NTC giup minh ti,
Minh thu viet giao dien P6F876A voi PC trong CSS, sau khi PIC khoi dong no se goi len PC 1 dong: Hello!
Tuy nhien khi noi may tinh, PIC goi lien tuc nhieu dong: Hello! va co nhieu dong ky tu bi loi, ma khong chay tiep phan sau.
Xin nho ban huong dan dum.

ntc 23-02-2006 12:05 PM

Bạn phải mô tả kĩ hơn ứng dụng của mình mới được. Kết nối phần cứng như thế nào, chương trình viết trên PIC và trên PC ra sao thì mới biết đường mà giúp chứ. CSS mình chưa xài, nhưng nếu mô tả kĩ hơn thì rất nhiều thành viên có thể giúp cho bạn.

LEO-XBS 24-02-2006 02:57 PM

bác nào có thể giải thích cho em đoạn khai báo này với:
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _CPD_OFF &_LVP_OFF

ntc 25-02-2006 04:14 PM

Đây là đoạn code dùng để khai báo các "Configuration bits" của vi điều khiển PIC. Nó bao gồm:
Khai báo chế độ bảo vệ code CP (code Protection). ON: bật chế độ. OFF: tắt chế độ.
Khai báo cho phép sử dụng Watchdog Timer WDT.
Khai báo các chế độ reset BODEN, PWRTE: đại khái là trước khi vi điều khiển đi vào hoạt động một cách ổn định, nó phải trải qua một khoảng thời gian quá độ để ổn định nguồn, ổn định xung clock,... có thể tạm gọi là các giai đoạn reset. Các giai đoạn này cho phép ta điều khiển bằng các bit trên.
Khai báo loại nguồn xung clock OSC : HS, XT hay RC. Tùy theo loại nguồn xung clock mà khai báo thích hợp.
Khai báo chế độ nạp chương trình LVP (Low Voltage Programming):chế độ nạp này sử dụng chân RB4/PGM đối với PIC16F877A. Các PIC khác cũng được hỗ trợ chế độ nạp này. Vấn đề này đã được đề cập trong cái TUT01. Bạn xem lại nhé.
Chức năng cụ thể của các khai báo này bạn xem lại cái datasheet ( phần "CONFIGURATION BITS") để biết thêm. Mình không nhớ hết được.
Mỗi PIC sẽ được hỗ trợ một số chế độ chứ không phải chế độ nào cũng được hỗ trợ, tùy theo con PIC bạn sử dụng mà khai báo cho thích hợp. Ví dụ, bạn sẽ thấy là khai báo cho con PIC16F84A sẽ ít hơn khai báo cho con PIC16F877A.
Mọi thông tin cho phần khai báo này đều có trong datasheet. Chỉ cần đọc và hiểu được thì mình sẽ sử dụng được.
Chúc vui! (mượn đỡ câu này của anh Hiệp một tí nghe)

ngkdong 25-02-2006 04:39 PM

Cac ban giai thich dum, minh cung moi hoc PIC thoi, minh viet mot doan de thu giao dien PIC16F876A nhu sau:
#include <16F876A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=24000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
void main() {

printf("\r\n\Hello! \r\n");

do {
delay_ms(2000);
printf("\r\n\Running...\r\n");
} while (TRUE);
Chi vay thoi de thu giao dien voi PC, nhung khi minh nap PIC roi, dung tool Serial Port Monitor trong CCS C de giam sat thu, thi thay PIC luon goi ve rat nhieu dong Hello!, ma khong thay co dong Running...
Dung ra thi no chi goi lan luot 2 dong tren thoi va khong lam gi ca, nhung o day no cu goi lien tuc dong Hello!, doi khi bi loi ky tu nua chu.
Mong cac ban chi giao giup nhe.
}


Múi giờ GMT. Hiện tại là 01:16 PM.

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