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)

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.
}

totite 27-02-2006 02:14 PM

Các bác vui lòng chỉ giúp em cách nào truy xuất vào vùng data trong bộ nhớ chương trình sau khi được định nghĩa bằng chỉ dẫn DB của Assembly. Em cần lập một bảng tra các giá trị cho led 7 đoạn giống như trong hợp ngữ của MCS51.

hpecom 27-02-2006 02:33 PM

Trích:

Nguyên văn bởi ngkdong
void main()
{ printf("\r\n\Hello! \r\n");
do
{ delay_ms(2000);
printf("\r\n\Running...\r\n");
} while (TRUE);
}

Chương trình của bạn, nếu chạy đúng thì nó sẽ
xuất ra dòng Hello,
và tiếp theo cứ mỗi 2s nó lại xuất ra dòng Running...
dòng Running... trước sẽ cách dòng Running... sau nó hai dòng trắng.:D
và vòng lặp là vô tận.

LEO-XBS 01-03-2006 07:23 PM

bác ntc co thể chỉ giúp em cách sử dụng cổng analog duoc ko
làm thế nào để sử dụng cổng đó trong việc thu tín hiệu từ led thu-phat va chuyển thành tín hiệu số (không dùng khuếch đại thuật toán) cộng với cách xư lý tín hiệu đó

ntc 05-03-2006 01:19 PM

Bảng tra giá trị cho vi điều khiển PIC sử dụng kĩ thuật bảng. Mình đã viết tutorial về kĩ thuật này rồi. Một hai bữa nữa sẽ post lên diễn đàn.
:D

ntc 05-03-2006 01:22 PM

Dùng bộ ADC đi. Trong PIC16F877A có tích hợp sẵn bộ ADC đó. Bạn nên tham khảo cái datasheet để biết được cấu trúc ADC trong PIC và cách sử dụng nó.:)


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

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