PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT PIC,...)

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Ðề tài đã khoá
 
Ðiều Chỉnh Xếp Bài
Old 20-04-2006, 05:10 PM   #1
ncv
Đệ tử 1 túi
 
Tham gia ngày: Apr 2006
Bài gửi: 16
:
Một cách viết khác để tham khảo với hy vọng viết C sao cho dễ hiểu :-)

#include <16F877A.h>
#fuses NOWDT, PUT, XT, NOPROTECT
#use delay(clock=4000000)

#define INITIAL_VALUE 6

byte count;
byte led;

void change_led(void);

#int_timer0
void interrupt_timer0() {
set_timer0(INITIAL_VALUE);
count++;
if (count == 2000) {
count = 0;
change_led();
}
}

void main() {
set_tris_b(0);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2); // set mod
set_timer0(INITIAL_VALUE); // set initial value

count = 0;
led = 1;
while (true)
output_b(led);
}

void change_led() {
led = led << 1;
if (led == 0)
led = 1;
}

Trích:
Nguyên văn bởi nhh
Đây là chương trình dùng ngắt Timer0 định thì 1s.
Đầu tiên led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi.
Code:
//****************************************************
// Author  : nhh
// Date    : 02/04/06
// Hardware: PIC16F877A
//****************************************************
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#byte portb=0x06
#define led pin_B0
int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
set_timer0(6);
++count;
if(count==2000)
   {
count=0;
a=a<<1;  // dich trai a 1bit
   }
if(a==256)
   {
a=1;
count=0;
   }
}
//Chuong trinh chinh
main()
{
set_tris_b(0);
enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(6);
count=0;
a=1;
while(true)
   {
portb=a;
   }
}
ncv vẫn chưa có mặt trong diễn đàn  
Old 06-08-2006, 04:09 PM   #2
boys3509_2006
Đệ tử 2 túi
 
Tham gia ngày: Feb 2006
Bài gửi: 32
:
Cho hỏi tí

Em mới vô thôi, huynh giải thích mấy dòng code sau cho em được ko ?
" set_timer0(6) " ; " ++count; " ; "if (count==2000) "

Nó nằm trong ct nháy led dùng interrup và timer0. biến count và a có tác dụng gì ? tại sao phải lùi a "a=a<<1" ?
boys3509_2006 vẫn chưa có mặt trong diễn đàn  
Old 09-10-2006, 09:47 PM   #3
phamvanthang
Nhập môn đệ tử
 
Tham gia ngày: Sep 2006
Bài gửi: 7
:
Ban lam on cho biet cho tim may thu vien cua CCS C, vi du nhu lcd_lib_4bit.h hay def_877a.h. Cam on!
phamvanthang vẫn chưa có mặt trong diễn đàn  
Old 22-05-2007, 05:36 PM   #4
suongrong17
Nhập môn đệ tử
 
suongrong17's Avatar
 
Tham gia ngày: May 2007
Nơi Cư Ngụ: Ho Chi Minh City
Bài gửi: 4
:
Send a message via Yahoo to suongrong17
#include<18F4450.h>
#fuses NOWDT,PUT,HS,NOPROTECT
#use delay(clock=20000000)
#use fast_io(b)
#byte portb=0x6
#define led pin_B0
int8 a;
void ngat()
{
delay_ms(1000);
a=a<<1; // dich trai a 1bit
if(a==256)
a=1;
}
main()
{
a=1;
set_tris_b(0);
while(true)
{
ngat();
output_b(a);
}
}
Cách này thì PIC18F4550 cũng dịch leds vô tư. Nhưng mà muốn dùng TIMER0 như của bác nhh . Khi mình làm không hiểu tại sao lại không thể chạy. Nhờ bác chỉ giáo giùm nhé!
#include <18F4550.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=20000000) . Mình đã sửa lại code của nhh như vậy để phù hợp với PIC18F4550, nhưng không hiểu sao vẫn không chạy đơợc. Bạn có thể hướng dẫn kỹ hơn về Interrup và Timer không, cảm on bạn nhiều.
__________________
Già vẫn học. Chọc thì cười.
suongrong17 vẫn chưa có mặt trong diễn đàn  
Old 22-05-2007, 08:52 PM   #5
thaithienanh
Đệ tử 7 túi
 
thaithienanh's Avatar
 
Tham gia ngày: Jul 2006
Bài gửi: 189
:
Send a message via Yahoo to thaithienanh
Úi code của bạn sai rồi nếu muốn sử dụng được ngắt thì trong hàm main bạn phải thực hiện cho phép ngắt timer_0 và ngắt toàn cục (global) hoạt động, định xung nhịp cho timer, và hàm ngắt() phải được đặt ngay bên dưới chỉ thị #int_timer0 để trình dịch có thể hiểu được đây là hàm phục vụ ngắt, hàm ngắt() này bạn không thể gọi đến giống như một hàm thông thường đuợc mà nó chỉ được máy gọi đến khi có xuất hiện cờ tràn timer_0, mà khi đã sử dụng ngắt timer (tức ngắt định thời) thì bạn không nên dùng delay trong nó (rất dở),vì ngắt timer được tạo ra để thay thế hoàn hảo cho delay, code của bạn mình sửa như sau :
#include<18F4450.h>
#fuses NOWDT,PUT,HS,NOPROTECT
#use delay(clock=4000000)
int16 count=0;
int8 a=1;

#int_timer0
void ngat(){
++count;
if(count==2000) {count=0;a=a<<1;} // dich trai a 1bit
if(a==256) {a=1;count=0; }}

void main(){
enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); //xung timer = xung máy/2
while(true) {
output_b(a);
}}

như vậy ở hàm trên ta sẽ thấy sau mỗi lần tràn ngắt timer_0 (sau hai xung máy) biến đếm count sẽ tăng lên 1 đơn vị và cứ thế cho đến khi đạt giá trị 2000 (đây là giá trị mà bạn cần phải tính để chọn đúng thời gian cần làm làm trễ) khi đó biến a sẽ đuợc dịch bit sang trái,....rồi tiếp tục... chắc khúc này bạn hiểu rồi há.
__________________
_____________________________Tri nhân tri tự bất tri tâm_____________________________
_ _ _ _ _ _ _ _ Yêu mến tất cả anh em Picvietnam.com _ _ _ _ _ _ _ _
. . . . . . . . . . . . . . . . Để post đuợc một câu hỏi rõ ràng xin tham khảo link sau : . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . http://www.picvietnam.com/forum/showthread.php?t=1263. . . . . . . . . . . . . . . .
thaithienanh vẫn chưa có mặt trong diễn đàn  
Old 23-05-2007, 04:38 PM   #6
suongrong17
Nhập môn đệ tử
 
suongrong17's Avatar
 
Tham gia ngày: May 2007
Nơi Cư Ngụ: Ho Chi Minh City
Bài gửi: 4
:
Send a message via Yahoo to suongrong17
Pic18f4450

Trích:
Nguyên văn bởi thaithienanh View Post
Úi code của bạn sai rồi nếu muốn sử dụng được ngắt thì trong hàm main bạn phải thực hiện cho phép ngắt timer_0 và ngắt toàn cục (global) hoạt động, định xung nhịp cho timer, và hàm ngắt() phải được đặt ngay bên dưới chỉ thị #int_timer0 để trình dịch có thể hiểu được đây là hàm phục vụ ngắt, hàm ngắt() này bạn không thể gọi đến giống như một hàm thông thường đuợc mà nó chỉ được máy gọi đến khi có xuất hiện cờ tràn timer_0, mà khi đã sử dụng ngắt timer (tức ngắt định thời) thì bạn không nên dùng delay trong nó (rất dở),vì ngắt timer được tạo ra để thay thế hoàn hảo cho delay, code của bạn mình sửa như sau :
#include<18F4450.h>
#fuses NOWDT,PUT,HS,NOPROTECT
#use delay(clock=4000000)
int16 count=0;
int8 a=1;

#int_timer0
void ngat(){
++count;
if(count==2000) {count=0;a=a<<1;} // dich trai a 1bit
if(a==256) {a=1;count=0; }}

void main(){
enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); //xung timer = xung máy/2
while(true) {
output_b(a);
}}

như vậy ở hàm trên ta sẽ thấy sau mỗi lần tràn ngắt timer_0 (sau hai xung máy) biến đếm count sẽ tăng lên 1 đơn vị và cứ thế cho đến khi đạt giá trị 2000 (đây là giá trị mà bạn cần phải tính để chọn đúng thời gian cần làm làm trễ) khi đó biến a sẽ đuợc dịch bit sang trái,....rồi tiếp tục... chắc khúc này bạn hiểu rồi há.
Thật sự cảm ơn sự chỉ giáo của thaithienanh. Mình cũng đang tập tành chơi với PIC thôi. Trước giờ cũng chưa từng đụng đến các loại vi xử lý thành ra không nắm rõ, khi đọc tài liệu cũng cảm thấy khó hiểu ở phần ngắt. Mình đang dự định dùng con PIC này để làm thành Keyboard USB, viết cả driver cho nó. Nhưng bây giờ cơ bản cũng còn chưa biết, chỉ có ý tửong7 thôi. Nhờ bạn chỉ them cho mình với nhé. Thế nhưng khi đưa trình ngắt này cho chạy thử thì vẫn thấy bặt vô âm tín, không hiểu bị sao nữa.
__________________
Già vẫn học. Chọc thì cười.
suongrong17 vẫn chưa có mặt trong diễn đàn  
Old 22-08-2007, 06:18 PM   #7
cuopbienquin
Đệ tử 2 túi
 
cuopbienquin's Avatar
 
Tham gia ngày: Jun 2007
Bài gửi: 43
:
Trích:
Nguyên văn bởi nhh View Post
Đây là chương trình dùng ngắt Timer0 định thì 1s.
Đầu tiên led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi.
Code:
//****************************************************
// Author  : nhh
// Date    : 02/04/06
// Hardware: PIC16F877A
//****************************************************
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#byte portb=0x06
#define led pin_B0
int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
set_timer0(6);
++count;
if(count==2000)
   {
count=0;
a=a<<1;  // dich trai a 1bit
   }
if(a==256)
   {
a=1;
count=0;
   }
}
//Chuong trinh chinh
main()
{
set_tris_b(0);
enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(6);
count=0;
a=1;
while(true)
   {
portb=a;
   }
}
Mình đang học về Timer .Theo bài này thì khi với thạch anh 4Mhz thì thời gian cho mồi dòng lệnh là 100us hay sau 100us thì timer sẽ báo tràn và quay trở lại 0. Có phải biến count là gán cho "mỗi dòng lệnh",nghĩa là khi count=2000 <=>delay 2000x100us= 20s chứ không phải 1s.
Tiếp theo ,về vấn đề thanh ghi pres_scaler ,mình không hiểu chế độ div _2,div_ 4 ảnh hưởng thề nào tới thời gian thực thi mỗi dòng lệnh,timer làm việc ra sao???Mình cũng có đọc chế độ hoạt động và xem block diagram mà chả hiểu gì cả.Mong các bạn giúp đỡ.Chúc vui

thay đổi nội dung bởi: cuopbienquin, 22-08-2007 lúc 06:24 PM.
cuopbienquin vẫn chưa có mặt trong diễn đàn  
Old 26-10-2007, 10:09 PM   #8
ngoctuan
Nhập môn đệ tử
 
Tham gia ngày: Oct 2007
Bài gửi: 1
:
hỏi về counter

chào các Bác, Em là thành viên mới , rất mong được chào đón. mong các bác chỉ cho Em về cuonter (Em đang làm đề tài mạch đếm sản phẩm ma chưa hiểu gì về cuonter) mong các bác chỉ dùm em .cám ơn các bác nhiều!
__________________
ngoctuan
ngoctuan vẫn chưa có mặt trong diễn đàn  
Old 02-04-2006, 03:33 PM   #9
ntc
Đệ tử 8 túi
 
ntc's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: HCM city
Bài gửi: 264
:
Send a message via Yahoo to ntc
Trích:
Mình cũng chưa hiểu ý nghĩa của hàm WDT_..., ko biết có phải khai báo như trên thì sau khoảng thời gian ms bao nhiêu đó đặt sau WDT_ thì sẽ reset lại Pic ?????
WDT là "chó giữ nhà" (Watchdog Timer). Bộ phận này có nhiệm vụ reset lại PIC sau một khoảng thời gian định trước. WDT sẽ reset vi điều khiển khi bộ đếm của WDT bị tràn. Mục đích của nó là tránh trường hợp vi điều khiển bị "treo" khi phải hoạt động liên tục trong một khoảng thời gian lâu dài.

Thời gian định trước này phụ thuộc vào tần số loại thạch anh sử dụng và bộ chia tần số trước (prescaler) của WDT.

Ta thấy WDT chỉ liên quan đến Timer 0, còn các Timer khác không có liên quan. Đó là tại vì WDT có bộ chia tần số (prescaler) dùng chung với Timer 0.

Lưu ý là muốn sử dụng WDT cần chú ý đến phần khai báo các "fuse" ở đầu chương trình.


Trích:
rtcc_state là một trong những constant sau:

RTCC_INTERNAL
RTCC_EXT_L_TO_H
RTCC_EXT_H_TO_L
Mỗi Timer đều có 2 tác dụng:

Tác dụng định thời: Timer sẽ dựa vào các xung tạo ra bởi bộ dao động (thạch anh, dao động RC, ...) cung cấp cho vi điều khiển để đếm. Và dựa vào tần số bộ dao động, giá trị các bộ chia tần số và giá trị của Timer, ta có thể xác định được thời gian thực. Như vậy trong trường hợp muốn Timer hoạt động ở chế độ định thời, ta phải khai báo rtcc_state là "RTCC_INTERNAL" (xử dụng tần số dao động nội).

Tác dụng đếm: Timer sẽ dựa vào các xung lấy từ môi trường bên ngoài để đếm. Tùy theo Timer mà ta sử dụng chân lấy xung tương ứng (Timer 0 là chân RA4, Timer1 là chân RC0). Các xung này có tác dụng phản ánh các hiện tượng trong thực tế, và việc đếm các xung cũng đồng nghĩa với việc đếm các hiện tượng đó. Và để linh động hơn trong quá trình xử lí, Timer còn cho phép chọn cạnh tác động lên bộ đếm (chế độ này chỉ có ở Timer 0). Như vậy muốn Timer hoạt động ở chế độ đếm, ta phải khai báo rtcc_state là một trong 2 trường hợp còn lại (sử dụng dao động ngoài).


Trích:
ps_state là một trong những constant sau:

RTCC_DIV_2
RTCC_DIV_4
RTCC_DIV_8
RTCC_DIV_16
RTCC_DIV_32
RTCC_DIV_64
RTCC_DIV_128
RTCC_DIV_256
WDT_18MS
WDT_36MS
WDT_72MS
WDT_144MS
WDT_288MS
WDT_576MS
WDT_1152MS
WDT_2304MS
Ở đây có đến 2 hàm dùng để ấn định tỉ số chia của prescaler, một hàm là "RTCC_DIV_...", một hàm là "WDT_ ...". Đó là bởi vì Timer 0 và WDT dùng chung bộ chia tần số. Khi bộ chia được Timer 0 sử dụng thì WDT không đựoc hỗ trợ với bộ chia này nữa. Như vậy sự khác biệt về thao tác giữa 2 hàm này có thể là như sau:

Hàm "RTCC_DIV_..." : cho phép Timer 0 sử dụng bộ chia tần số, không cho phép WDT sử dụng và ấn định tỉ số chia của nó.

Hàm "WDT_ ..." : cho phép WDT 0 sử dụng bộ chia tần số, không cho phép Timer 0 sử dụng và ấn định tỉ số chia của nó.

Trích:
T2_DISABLED
T2_DIV_BY_1
T2_DIV_BY_4
T2_DIV_BY_16

period là số nguyên từ 0-255, xác định giá trị xung reset
postscale là số nguyên 1-16, xác định reset bao nhiêu lần trước khi ngắt.
hôm nay 09:30 AM
Ta có thể nhận thấy là Timer 2 có đến 2 bộ chia tần số trước và sau, một bộ prescaler được đính kèm vào các chế độ hoạt động của Timer 2 (T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16), một bộ là postscaler cis tỉ số chia từ 1:16. Như vậy nó cho phép việc lựa chọn tỉ số chia linh động hơn.

Timer 2 không hoạt động ở chế độ đếm. Chức năng của nó chủ yếu là tác động lên tốc độ baud cho MSSP thì phải. Không nhớ rõ lắm.

Trích:
postscale là số nguyên 1-16, xác định reset bao nhiêu lần trước khi ngắt.
Cái này để mình coi lại đã, tại sao nó lại xác định reset bao nhiêu lần trước khi ngắt ??. Phải coi lại cái sơ đồ khối của Timer 2 mới biết được.
__________________

ntc vẫn chưa có mặt trong diễn đàn  
Old 05-04-2006, 11:05 AM   #10
nhh
Đệ tử 9 túi
 
nhh's Avatar
 
Tham gia ngày: Feb 2006
Bài gửi: 174
:
Send a message via Yahoo to nhh
Ngắt ngoài

Chào cả nhà !

Sao không thấy bác nào post bài vào luồng này vậy kà !Trầm quá...!Trầm quá...!Hay cái CCS C này không hấp dẫn mọi người chăng!
Không ai viết gì, tớ vẫn post cho nó đỡ trầm....!

Đã ví dụ về ngắt Timer, sau đây là 2 ví dụ về ngắt ngoài trên chân RB0 và trên các chân RB4 đến RB7:

Chương trình sau dùng ngắt ngoài trên RB0 đếm số lần cái button được nhấn xuống, hiển thị lên led 7 đoạn (common cathode).Nếu số lần nhấn vượt quá 9, chương trình sẽ quay về hiển thị lên led từ số 1.
Code:
//*****************************************************************************
// Author  : nhh
// Date    : 03/04/06
// Hardware: PIC16F877A
//*****************************************************************************
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#use fast_io(d)
#byte portb=0x06
#byte portd=0x08
const unsigned char digital[]={0b00000110, 0b01011011, 0b01001111, 0b01100110,\
						0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};
                  // ma hoa digital duoi dang mang
// Chuong trinh ngat
#int_ext
void ngat_RB0()
{
int i;
   if(i<9)
      {
      portd=digital[i];
      ++i;
      }
   if(i==9)
      {
      i=0;
      }
}
// Chuong trinh chinh
main()
{
set_tris_b(0b00000001);
set_tris_d(0);
enable_interrupts(global);
enable_interrupts(int_ext);
ext_int_edge(H_to_L);
portd=0b00111111;
while(true)
   {
   // chi doi ngat nen vong lap nay ko co gi ca !
   }
}
File Kèm Theo
File Type: rar dem1-9dungngatngoai.rar (13.6 KB, 1961 lần tải)

thay đổi nội dung bởi: nhh, 09-07-2007 lúc 09:06 PM. Lý do: Update
nhh vẫn chưa có mặt trong diễn đàn  
Old 29-04-2006, 03:01 PM   #11
hpecom
Đệ tử 2 túi
 
Tham gia ngày: Nov 2005
Bài gửi: 45
:
Trích:
Nguyên văn bởi nhh
Chào cả nhà !

Sao không thấy bác nào post bài vào luồng này vậy kà !Trầm quá...!Trầm quá...!Hay cái CCS C này không hấp dẫn mọi người chăng!
Không ai viết gì, tớ vẫn post cho nó đỡ trầm....!

Đã ví dụ về ngắt Timer, sau đây là 2 ví dụ về ngắt ngoài trên chân RB0 và trên các chân RB4 đến RB7:

Chương trình sau dùng ngắt ngoài trên RB0 đếm số lần cái button được nhấn xuống, hiển thị lên led 7 đoạn (common cathode).Nếu số lần nhấn vượt quá 9, chương trình sẽ quay về hiển thị lên led từ số 1.
Code:
//*****************************************************************************
// Author  : nhh
// Date    : 03/04/06
// Hardware: PIC16F877A
//*****************************************************************************
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#use fast_io(d)
#byte portb=0x06
#byte portd=0x08
const unsigned char digital[]={0b00000110, 0b01011011, 0b01001111, 0b01100110,\
						0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};
                  // ma hoa digital duoi dang mang
// Chuong trinh ngat
#int_ext
void ngat_RB0()
{
int i;
   if(i<9)
      {
      portd=digital[i];
      ++i;
      }
   if(i==9)
      {
      i=0;
      }
}
// Chuong trinh chinh
main()
{
set_tris_b(0b00000001);
set_tris_d(0);
enable_interrupts(global);
enable_interrupts(int_ext);
ext_int_edge(H_to_L);
portd=0b00111111;
while(true)
   {
   // chi doi ngat nen vong lap nay ko co gi ca !
   }
}
Theo tại hạ, hàm ngắt trên có vấn đề. Ở chỗ khai báo biến i. Biến i là biến cục bộ của hàm ngắt, vậy khi ra khỏi ngắt biến i sẽ bị mất khỏi bộ nhớ tức không được cấp phát ô nhớ. Lần sau ngắt xảy ra thì biến i này sẽ được khai báo lại. Tóm lại vần đề là tầm khai báo biến.
Bác nên khai báo biến i là biến toàn cục thì mới có khả năng đếm số lần ngắt.
Chúc khỏe.
hpecom.
__________________
Biết thì nói là biết,
Không biết thì nói là không biết,
..
hpecom vẫn chưa có mặt trong diễn đàn  
Old 06-05-2006, 01:56 PM   #12
ncv
Đệ tử 1 túi
 
Tham gia ngày: Apr 2006
Bài gửi: 16
:
Ngắt ngoài và đèn 7 đoạn

Một phương án khác:

#include <16F877A.h>
#fuses NOWDT, XT
#fuses NOLVP // important
#use delay(clock=4000000)

// 0 1 2 3 4 5 6 7 8 9
byte const DIGITS[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };
int8 i = 0;

///////////////////////////////////////////////////////////
/* private */void off_on_led_transistor() {
output_low(PIN_D1);
delay_ms(1);
output_high(PIN_D1);
}

///////////////////////////////////////////////////////////
/* private */void display(int8 digit) {
output_c(DIGITS[digit] ^ 0xff);
off_on_led_transistor();
}

///////////////////////////////////////////////////////////
#INT_EXT
void ngat_RB0() {
i = (i < 9) ? i+1 : 1;
delay_ms(200); // switch debounce period
}

///////////////////////////////////////////////////////////
/**
* Count number of key presses and display it on a 7-segment LED.
* If the number is 9, the next count will be 1
*
* Wiring (TM Board)
* (1) PIC's B0 to R0
* Matrix Key C0 to GND
* (2) PIC's C0-C6 to 7-segment LED's A-G
* PIC's D1 to 7-segment LED's C2
*/
void main() {
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);

while (true)
display(i);
}

Trích:
Nguyên văn bởi nhh
Chào cả nhà !

Sao không thấy bác nào post bài vào luồng này vậy kà !Trầm quá...!Trầm quá...!Hay cái CCS C này không hấp dẫn mọi người chăng!
Không ai viết gì, tớ vẫn post cho nó đỡ trầm....!

Đã ví dụ về ngắt Timer, sau đây là 2 ví dụ về ngắt ngoài trên chân RB0 và trên các chân RB4 đến RB7:

Chương trình sau dùng ngắt ngoài trên RB0 đếm số lần cái button được nhấn xuống, hiển thị lên led 7 đoạn (common cathode).Nếu số lần nhấn vượt quá 9, chương trình sẽ quay về hiển thị lên led từ số 1.
Code:
//*****************************************************************************
// Author  : nhh
// Date    : 03/04/06
// Hardware: PIC16F877A
...
// Chuong trinh chinh
main()
{
set_tris_b(0b00000001);
set_tris_d(0);
enable_interrupts(global);
enable_interrupts(int_ext);
ext_int_edge(H_to_L);
portd=0b00111111;
while(true)
   {
   // chi doi ngat nen vong lap nay ko co gi ca !
   }
}
ncv vẫn chưa có mặt trong diễn đàn  
Old 27-06-2007, 05:29 PM   #13
anh_gioi
Đệ tử 6 túi
 
Tham gia ngày: Oct 2006
Bài gửi: 147
:
Trích:
Nguyên văn bởi nhh View Post
Chào cả nhà !

Sao không thấy bác nào post bài vào luồng này vậy kà !Trầm quá...!Trầm quá...!Hay cái CCS C này không hấp dẫn mọi người chăng!
Không ai viết gì, tớ vẫn post cho nó đỡ trầm....!

Đã ví dụ về ngắt Timer, sau đây là 2 ví dụ về ngắt ngoài trên chân RB0 và trên các chân RB4 đến RB7:

Chương trình sau dùng ngắt ngoài trên RB0 đếm số lần cái button được nhấn xuống, hiển thị lên led 7 đoạn (common cathode).Nếu số lần nhấn vượt quá 9, chương trình sẽ quay về hiển thị lên led từ số 1.
Code:
//*****************************************************************************
// Author  : nhh
// Date    : 03/04/06
// Hardware: PIC16F877A
//*****************************************************************************
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#use fast_io(d)
#byte portb=0x06
#byte portd=0x08
const unsigned char digital[]={0b00000110, 0b01011011, 0b01001111, 0b01100110,\
						0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};
                  // ma hoa digital duoi dang mang
// Chuong trinh ngat
#int_ext
void ngat_RB0()
{
int i;
   if(i<9)
      {
      portd=digital[i];
      ++i;
      }
   if(i==9)
      {
      i=0;
      }
}
// Chuong trinh chinh
main()
{
set_tris_b(0b00000001);
set_tris_d(0);
enable_interrupts(global);
enable_interrupts(int_ext);
ext_int_edge(H_to_L);
portd=0b00111111;
while(true)
   {
   // chi doi ngat nen vong lap nay ko co gi ca !
   }
}
sao bai nay chỉ sủ dụng RB0 là chân vào thôi vậy.còn các chân khác sao lại không dc.
thank!
anh_gioi vẫn chưa có mặt trong diễn đàn  
Old 05-04-2006, 11:08 AM   #14
nhh
Đệ tử 9 túi
 
nhh's Avatar
 
Tham gia ngày: Feb 2006
Bài gửi: 174
:
Send a message via Yahoo to nhh
Ngắt ngoài trên RB4-RB7

Còn đây là ứng dụng ngắt ngoài trên RB4 đến RB7 để thay đổi kiểu cũng như tốc độ chớp nháy mấy con led chỉ để....ngắm cho vui mắt !

Ấn sw1, led1 nhấp nháy với delay 250ms
Ấn sw2, led1,2 nhấp nháy với delay 200ms
Ấn sw3, led1,2,3 nhấp nháy với delay 150ms
Ấn sw4, led1,2,3,4 nhấp nháy với delay 100ms
Code:
//*****************************************************************************
// Author  : nhh
// Date    : 03/04/06
// Hardware: PIC16F877A
//*****************************************************************************
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#byte portb=0x06
#byte intcon=0x000B
#bit RB4=portb.4
#bit RB5=portb.5
#bit RB6=portb.6
#bit RB7=portb.7
#bit RBIF=intcon.0 //dinh nghia co ngat RB
#bit RBIE=intcon.3 //dinh nghia bit cho phep ngat RB
int led=0,speed;
// Chuong trinh ngat
#int_RB
void ngat_RB()
{
if((RBIF)&&(RBIE)) 
   { 
      //Kiem tra sw1
      {
      if(RB4==0)
         {
         led=0b00000001; //led1 sang
         speed=250;
         } 
      }
      //Kiem tra sw2      
      {
      if(RB5==0)
         {
         led=0b00000011; //led1,2 sang
         speed=200;
         } 
      }
      //Kiem tra sw3
      {
      if(RB6==0)
         {
         led=0b00000111; //led1,2,3 sang
         speed=150;
         } 
      }
      //Kiem tra sw4
      {
      if(RB7==0)
         {
         led=0b00001111; //led1,2,3,4 sang
         speed=100;
         } 
      }
   RBIF=0; //Xoa co ngat RB      
   }
}
// Chuong trinh chinh
main()
{
set_tris_b(0b11110000);
portb=0b00001111;
enable_interrupts(global);
enable_interrupts(int_RB);
ext_int_edge(H_to_L);
while(true)
   {
   portb=led;
   delay_ms(speed);
   portb=0;
   delay_ms(speed);  
   }
}
Không như trong MPLAB, đã định nghĩa sẵng các thanh ghi và bit tương ứng, còn CCS C chỉ định nghĩa chân PIC, những thanh ghi, những bit mà CCS C cho là cần thiết, ta xem trong file PIC16F887A.h, thanh ghi, bit nào chưa định nghĩa mà muốn sử dụng thì phải định nghĩa nó.
Ta có thể viết riêng 1 file.h loại này sao cho mình dễ nhớ nhất, đến khi muốn sử dụng chỉ cần khai báo #include<file.h> vào là xài thôi!

File Kèm Theo
File Type: rar thaydoitocdochopleddungngatngoai.rar (14.0 KB, 1761 lần tải)

thay đổi nội dung bởi: nhh, 09-07-2007 lúc 09:02 PM. Lý do: Attach file
nhh vẫn chưa có mặt trong diễn đàn  
Old 04-12-2006, 11:20 AM   #15
alamanda
Đệ tử 1 túi
 
alamanda's Avatar
 
Tham gia ngày: Nov 2005
Bài gửi: 19
:
Question

[QUOTE=nhh;2261]Còn đây là ứng dụng ngắt ngoài trên RB4 đến RB7 để thay đổi kiểu cũng như tốc độ chớp nháy mấy con led chỉ để....ngắm cho vui mắt !

Ấn sw1, led1 nhấp nháy với delay 250ms
Ấn sw2, led1,2 nhấp nháy với delay 200ms
Ấn sw3, led1,2,3 nhấp nháy với delay 150ms
Ấn sw4, led1,2,3,4 nhấp nháy với delay 100ms
[code]//************************************************** ***************************
// Author : nhh
// Date : 03/04/06
// Hardware: PIC16F877A
//************************************************** ***************************
Bác nhh ơi,tui đang đang dùng CCS C version 4.013 ( tui mới học PIC gần đây). Khi tui copy file của bác về chạy thử thì nó báo lỗi. Ở khai báo #byte portb=0x06, nó báo lỗi là Expecting an identifier và Expecting a declaration. Còn ở lệnh: portb=led;thì nó báo lỗi Expecting LVALUE such as a variable name or *expression. Cụ thể là bài của bác tui dịch ra là 8 lỗi. Tui pó tay .Rất mong sự chỉ giáo của bác,và các bậc tiền bối.
alamanda vẫn chưa có mặt trong diễn đàn  
Ðề tài đã khoá


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến

Similar Threads
Ðề tài Người gửi Chuyên mục Trả lời Bài mới
TUT về USART trong PIC16F877A mafd_47a MPASM 16 19-02-2025 05:32 AM
TUT ve I2C ( pic16f877a ) mafd_47a MPASM 28 28-01-2025 10:45 PM
Lập nhóm PIC16F877A nhh Cơ bản về vi điều khiển và PIC 285 08-03-2017 11:08 PM
Bộ so sánh và PWM cho PIC16F877A anhquangngai Cơ bản về vi điều khiển và PIC 24 08-09-2012 09:00 AM
Pic16f877a TỪ DỄ TỚi KhÓ ntc Cơ bản về vi điều khiển và PIC 373 23-05-2009 10:24 PM


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


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam