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)
-   -   Giúp đỡ về ngắt TMR1 pic 16F877A dùng CCS (http://www.picvietnam.com/forum/showthread.php?t=5018)

leduy 03-10-2009 01:23 AM

Giúp đỡ về ngắt TMR1 pic 16F877A dùng CCS
 
1 Attachment(s)
Mình đang viết bài điều khiển đèn giao thông, sử dụng Ngắt TMR1. Tức là khi đủ 1s thì T1 ngắt để phục vụ cho chương trình của mình. Mình đã viết xong, chạy tốt, khá đúng 1s thì LED7 đoạn giảm 1s như đèn giao thông bình thường.
Nhưng vấn đề ở chổ là làm mình tính toán được thời gian ngắt của T1 là 1s (trong chương trình là mình thế giá trị hoài dến khi dược thì thôi^^). Rắc rối của mình là BỘ CHIA PRESCALER của T1. Mình bó tay với nó luôn. Vì mình phải báo cáo nên cần biết vê lý thuyết tại sao lại là 1s.

Bác nào rành về cái này giúp mình với.
Đây là chương trình :
// CHUONG TRINH DEN GIAO THONG SU DUNG PIC16F877A
// PHAN KHAI BAO
#INCLUDE<16F877A.H>
#FUSES XT,NOWDT,NOPROTECT,NOLVP,PUT,HS // DAT CAU HINH CHO PIC
#USE DELAY(CLOCK=4000000) // XUNG CLOCK 4MHZ
#USE FAST_IO(A)
#USE FAST_IO(C)
#USE FAST_IO(D)
#BYTE PORTB =0X06
#BYTE PORTC =0X07
#BYTE PORTD =0X08

INT8 TIME=0;
INT16 COUNT=0;
UNSIGNED INT8 A,B,C,D;
UNSIGNED INT8 CHUC_X1,DVI_X1,CHUC_D2,DVI_D2,CHUC_X2,DVI_X2,CHUC_ D1,DVI_D1;
UNSIGNED INT8 CONST MALED[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x9 0} ;// MA LED 7 DOAN
UNSIGNED INT8 CONST QUETLED[]={0X01,0X02,0X04,0X08}; // MA QUET LED

//xxxxxxxxxxxxxxxx HAM NGAT TIMER1 xxxxxxxxxxxx
#INT_TIMER1
VOID NGAT_TIMER1()
{
SET_TIMER1(0); // cái này mình đoán và nạp vào thôi
COUNT ++; // TANG BIEN DEM

IF (COUNT==4) // cái này mình cũng đoán rồi cho no = 4 thoi
{
COUNT =0; //DU 1 GIAY THI CHO BIEN DEM VE 0
TIME ++; // VA CHO TIME CONG THEM 1
}
IF (TIME==50) // HET 1 CHU KY DEN THI CHO TMME =0
{
TIME =0;
}
}
// xxxxxxxx CAC CHUONG TRINH CON xxxxxxxxxx
VOID HIEN_THI(UNSIGNED CHAR ML , UNSIGNED CHAR L );
VOID GIAIMA();
//xxxxxxxxx CHUONG TRINH CHINH xxxxxxxx

VOID MAIN()
{
SET_TRIS_B(0X00); // PORT A OUT PUT
SET_TRIS_C(0X00); // PORT C OUT PUT
SET_TRIS_D(0X00);

ENABLE_INTERRUPTS(GLOBAL); // CHO PHEP NGAT TOAN CUC
ENABLE_INTERRUPTS(INT_TIMER1); // CHO PHEP NGAT TIMER 1
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1); // DINH THOI THEO DAO DONG NOI
SET_TIMER1(0);

PORTC= 0x00; // TAT CAC LED
TIME = 0;
WHILE(1)
{ LOOP:
GIAIMA();
IF(TIME<20)
{ PORTB = 0B00100001; // SANG DEN XANH 1,DO 2

HIEN_THI(CHUC_X1,0) ; // HANG CHUC CUA DEN XANH 1
HIEN_THI(DVI_X1,1); //HANG DON VI CHUA DEN XANH1
HIEN_THI(CHUC_D2,2); // HANG CHUC DEN DO2
HIEN_THI(DVI_D2,3); // HANG DON VI DEN DO2
GOTO LOOP ;
}

IF((TIME>=20)&(TIME<25))
{ PORTB = 0B00100010; //SANG DEN VANG 1, DO 2
HIEN_THI(CHUC_D2,0); //HANG CHUC CUA DEN VANG 1
HIEN_THI(DVI_D2,1); //HANG DON VI CUA DEN VANG 1
HIEN_THI(CHUC_D2,2); // HANG CHUC DEN DO
HIEN_THI(DVI_D2,3); // HANG DON VI DEN DO
GOTO LOOP ;
}


IF((TIME>=25)&(TIME<45))
{ PORTB = 0B00001100; //SANG DO 1, XANH 2
HIEN_THI(CHUC_D1,0); //HANG CHUC DEN DO1
HIEN_THI(DVI_D1,1); //HANG DON VI DEN D01
HIEN_THI(CHUC_X2,2); //HANG CHUC DEN XANH2
HIEN_THI(DVI_X2,3); //HANG DON VI XANH2
GOTO LOOP ;
}

IF (TIME>=45)
{ PORTB = 0B00010100;//SANG DO1, VANG 2
HIEN_THI(CHUC_D1,0); //HANG CHUC DEN DO1
HIEN_THI(DVI_D1,1); //HANG DON VI DEN D01
HIEN_THI(CHUC_D1,2); //HANG CHUC DEN VANG 2
HIEN_THI(DVI_D1,3); //HANG DON VI DEN VANG 2

}
}

} //xxxxxxxxx HET 1 CHU KY xxxxxxxxxxxxxxxxxxxx

VOID HIEN_THI(UNSIGNED CHAR ML, UNSIGNED CHAR L)
{
PORTD = MALED[ML]; // XUAT MA LED RA SO
PORTC = QUETLED[L]; // QUET LED
DELAY_US(40);
PORTC =0X00; // CHONG LEM
}
VOID GIAIMA()
{ A= (20-TIME);
CHUC_X1= A/10; // SO HANG CHUC DEN XANH1 20S
DVI_X1 = A%10;// // SO HANG DON VI XANH1
B= (25-TIME);
CHUC_D2= B/10; // SO HANG CHUC DEN DO2 25S
DVI_D2= B%10; // SO HANG DON VI DO2

C= (45-TIME);
CHUC_X2= C/10; //HANG CHUC CUA DE XANH 2
DVI_X2= C%10; //HANG DON VI CUA DEN XANH 2
D= (50-TIME);
CHUC_D1= D/10; //HANG CHUC CUA DEN DO1
DVI_D1= D%10; //HANG DON VI DEN DO1
}
Thanks các bác nhiều!

hoang1730 04-10-2009 04:23 PM

tính toán giá trị tràn cho timer cũng dễ thôi! Mình nói ngay là giá trị prescaler sẽ kéo dài chu kỳ ngắt timer ra. Cụ thể thời gian ngắt của timer1 có thể tính như sau:
1. Timer1 16bits sẽ tràn khi chuyển giá trị FFFF-->0000
2. Điều chỉnh thời gian ngắt bằng cách điều chỉnh giá trị nạp cho timer.
3. Time= (65535-value)*4*Prescaler*(1/Fosc).
trong đó: Fosc: tần số dao động thạch anh
4. Trong chương trình của bạn:
time=(65535-0)*4*1*(1/4)=65535 us
thêm vòng lặp count:
time=65535us*count=65535*4=262140 us
Goodluck!

ngocnguyen_pm05 12-10-2009 02:46 PM

Mình có đoạn code:

#include<16f877a.h>
#fuses hs,nolvp,nowdt,noprotect
#use delay(clock=400000)
#include"lcd_4bit.c"
int giatritocdoc,dem;
//#int_timer0
//void timer0()
//{
//set_timer0(155);
//dem=dem+1;
//output_d(dem);
//}
#int_timer1
void timer1()
{
set_timer1(15535);//dat tao thoi gian 0.1 s cho bo chia 2 tan so 4mhz
giatritocdoc=dem;
output_d(0xff);//de thu co chay hay khong
dem=0;
}
void main()
{
setup_timer_1(T1_INTERNAL/T1_DIV_BY_2);
//setup_timer_0(RTCC_DIV_2|RTCC_EXT_L_TO_H);
//set_timer0(155);
set_timer1(15535);dat gia tri dau
enable_interrupts(GLOBAL);
//enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
while(1)
}
sao nó không chạy được nhờ các sư huynh sửa giúp. Thanks

nhamdtk4 12-10-2009 03:40 PM

Sao nó ko chạy hả. Bạn nhìn vào những chỗ này trong code của bạn nhá:
Code:

setup_timer_1(T1_INTERNAL/T1_DIV_BY_2);
- Ko biết dấu / này nghĩa là j, | thế này mới đúng.
Code:

while(1)
- Tại sao lại như vậy mà ko viết như này "while(1){}"
Code:

set_timer1(15535);dat gia tri dau
- Chú giải thì nhớ thêm dấu // vào đằng trc.


Múi giờ GMT. Hiện tại là 07:22 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