April 2024 | Mon | Tue | Wed | Thu | Fri | Sat | Sun |
---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | | | | | Calendar |
|
Latest topics | » simviettel.net bán sim đẹp Viettel, số đẹp Vinaphone, sim số đẹp Mobifone 10 sốThu Nov 07, 2013 2:59 pm by simviettel.net » đo nhiệt độFri Nov 09, 2012 11:56 pm by trongthanh » Mạch cầu H kích FET dùng IR2110Tue Aug 07, 2012 7:26 pm by Ultra » HƯỚNG DẪN THIẾT KẾ FANLED CỦA CLBTue Jan 10, 2012 11:17 pm by dcthuan.cdt » Thông báo! Giải bóng đá CUP KSTN mùa giải 2011Mon Nov 07, 2011 8:52 pm by lethanhtoan » điểm danh xem ai đang làm gìThu Sep 22, 2011 12:18 pm by vanquy311 » về ngày hội việc làm và phỏng vấn thử thành công thậtThu Sep 22, 2011 12:07 pm by vanquy311 » cần trao đổiThu Sep 22, 2011 11:19 am by blue » cùng nhau hoàn thành tốt luận vănWed Sep 21, 2011 2:56 pm by biganaru |
| | Bài tập Counter0 | |
| | Tác giả | Thông điệp |
---|
rockc4 trưởng phòng
Tổng số bài gửi : 35 Join date : 30/03/2010
| Tiêu đề: Bài tập Counter0 Sat May 22, 2010 2:44 pm | |
| Chào các bạn, có nhiều cách để viết một chương trình = C cho VĐK. Sau buổi học Timer / Ngắt, có một số bạn đã làm bài tập và nộp bài, cách viết khác nhau và kết quả cũng khác nhau Đây là chương trình dùng Counter 0, đếm đến 10 thì bật LED (RE1) trong thời gian 300ms thì tắt. Chị sẽ viết một vài chương trình mẫu, để các bạn tham khảo cách viết chương trình chuyên nghiệp. Ngoài ra trong chương trình này mình có sử dụng 2 chương trình con, được viết trước hàm main(). Chương trình con / cũng như chương trình ngắt, có thể viết trước / hoặc sau main(). Tuy nhiên, chương trình con nếu đc viết sau main() thì trước main vẫn phải khai báo: ví dụ:void init_port(void); //khai báo chương trình con main() {...} void init_port(void) { //chương trình con ở đây } Lưu ý, khi các bạn chạy thử trên board mainpic của mình thì sửa lại 1 số chỗ cho đúng: . - Sửa Config bits: chị dùng board học PIC, thạch anh nội - Led nối với portE1, cấp mức 1 thì sáng, 0 thì tắt. - Nút nhấn có treo trở lên nguồn, gắn vào RA4, bình thường = 1, khi nhấn = 0; - Code:
-
/**************************************************************** * * PIC Training Course * ****************************************************************/
/**************************************************************** * * Module : main.c * Description : Counter0 / Count to 10 then Light On LED 1 * Tool : HI-TECH PIC * Chip : 16F887A * History : 19/05/2010 * * Author : Ho Thanh Phuong, CLB NCKH * Hardware notes : * - Hardware: LED1 assembles with RE1; RE1 = 1: light on LED1 * - A button is connected with RA4 (T0CKI); * Normal: RA4 = 1; push down: RA4 =0 ****************************************************************/
/**************************************************************** * IMPORT ****************************************************************/
#include <htc.h> __CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS);
#define _XTAL_FREQ 4000000 #define ON 1 #define OFF 0 /**************************************************************** * EXTERN ****************************************************************/
/*none...*/
/***************************************************************** GLOBAL VARIABLE ******************************************************************/
/*none...*/
/***************************************************************** * ROUTINES ******************************************************************/ /* -- void init_port(void) -------------------------------------- * * Description : disable all analog pins, init RE1 as output . * Parameters : none * Return : don't care */ void init_port(void) { ANSEL = 0; //AN[0-7] are analogs pins ANSELH = 0; //AN[8-13] are analogs pins TRISE1 = 0; //RE1 as output RE1 = OFF; //Turn off Led1 }
/* -- void init_counter0(void) -------------------------------------- * * Description : initialization counter 0 * Parameters : none * Return : don't care */ void init_counter0(void) { TRISA4 = 1; //init PortA[4] as input to use external clock for Counter0 T0CS=1; // Clock Select: 1: External clock for Counter 0 // 0: Internal clock for Timer 0 T0SE=1; // Source Edge: 1: Falling Edge // 0: Rising Edge PSA=1; // PreScaler: 1: Not use // 0: Use
TMR0=0xF6; // Overflow after 10 pulses GIE=1; // Global Interrupt Enable T0IF=0; // Clear Timer0 Interrupt Flag T0IE=1; // Timer0 Interrupt Enable }
/* -- void interrupt isr() ----------------------------------------- * * Description : Interrupt Service Routine * Parameters : none * Return : don't care * Notes : */ void interrupt isr() { if(T0IE && T0IF) { T0IF=0; // Clear Timer0 Interrupt Flag TMR0=0xF6; RE1=ON; // Light off Led1 __delay_ms(150); __delay_ms(150); RE1 = OFF; } }
/**************************************************************** * MAIN ****************************************************************/ /* -- void main (void) ----------------------------------------- * * Description : External Interrupt control. * Parameters : none * Return : don't care * Notes : */ void main(void) { init_port(); init_counter0(); while(1); }
/**************************************************************** * END OF main.c ****************************************************************/
download file .c ở đây http://www.mediafire.com/?gr4iywm0zdcVấn đề của chương trình này là: Nếu các bạn dùng phím nhấn để tạo clock đếm xung cho COunter0, thì sẽ có hiện tượng rung phím. Khi bạn chỉ nhấn phím 1 lần, nhưng bộ counter đọc đc 2,3 xung --> nhấn chưa tới 10 lần đèn đã báo. Vậy sẽ giải quyết thế nào? Các bạn xem chương trình, có gì thắc mắc mình sẽ trao đổi ở đây.
Được sửa bởi rockc4 ngày Sat May 22, 2010 9:30 pm; sửa lần 1. | |
| | | blue giám đốc điều hành
Tổng số bài gửi : 96 Join date : 28/12/2009 Age : 34 Đến từ : ninh thuận
| Tiêu đề: Re: Bài tập Counter0 Sat May 22, 2010 5:11 pm | |
| chị phương nói đúng,sẽ bị rung phím.e nhớ thầy Mỹ có nói là chống rung được bằng phần cứng (dùng RC gì đó),tiếc là e ngủ quên mất (trụ được 30 phút đầu, nửa tỉnh nửa mê trong suốt quãng thời gian còn lại ).chị phương chỉ lại cho e phương pháp này đi còn e dùng delay để giải quyết thôi.e đang sửa lại đoạn code đó,nhưng chưa test thử nên chưa dám đưa lên đây.sẽ đưa lên ngay khi test xong | |
| | | Lee phó tổng giám đốc
Tổng số bài gửi : 106 Join date : 29/12/2009 Age : 34 Đến từ : Tây Ninh
| Tiêu đề: Re: Bài tập Counter0 Sat May 22, 2010 6:11 pm | |
| Àh, cái vụ chống rung phím bằng phần cứng hôm đó t còn tỉnh để nghe . Chúng ta sẽ dùng 1 cái tụ, mắc cái tụ giữa mass và điện trở kéo lên nguồn(cách mắc giống như mạch để reset) để san bằng các gai xuất hiện do rung phím, giống như cách lọc gợn sóng.( Nếu nhớ không nhầm là như thế ). Còn về chương trình trên, t làm giống chị P, có điều khi ấn phím lần thứ 10 thì led sẽ nhấp nhái, ấn lần thứ 11 thì led tắt, cứ thế đến lần 20 thì led lại chớp tắt..... Code: void interrupt isr() { if(T0IE && T0IF) { T0IF=0; TMR0=0xF6; PORTE ^=7; // xor 3bit RE0,RE1,RE2. 7=111B } c=TMR0; while(TMR0==c) // CHO SU THAY DOI CUA BUTTON { __delay_ms(150); // CHO LED NHAY PORTE ^=7; } PORTE=0xFF; // DUA PORTE VE TRANG THAI BAN DAU, LED CHI SANG O LAN THU 10, SAU DO RESET LAI. (xuất 0 thì led sáng, xuất 1 thì led tắt) } Còn về phần rung phím, ý tưởng cũng giống như thầy Mỹ nói: See and Wait(hay W a S ấy, không nhớ rõ do gật gù ). Khi phát hiện ra sự thay đổi của nút nhấn thì chưa cho TMR0 tăng liền, mà phải chờ cho đến khi nút nhấn được xác lập, của 8051 là 30ms, còn PIC thì không biết bao nhiêu, chắc cũng khoảng đó). Sau đó hỏi lại phím 1 lấn nữa để xác nhận việc chuyển mức, nếu có chuyển trạng thái thì cho TMR0 tăng lên 1. Code:/nằm trong main() * while(1) * { c=TMR0; * if(RA4==0) * { __delay_ms(30); TMR0=c; } // CHO SU ON DINH CUA PHIM NHAN * if(RA4==0) TMR0=TMR0+1; // NEU RA4=0 THI THAT SU CO NHAN PHIM, // KHI DO MOI TANG TMR0 * __delay_ms(50); // CHO RA4 TRO VE GIA TRI 1 * } Ở đây, TMR0 đếm lên khi có xung kích cạnh xuống. Chương trình t chưa test được vì mô phỏng bằng protues sẽ ko phát hiện được rung phím. Còn phần cứng thì chắc là do config bit nên chạy sai hết cả(mô phỏng protues thì ok).Anh em xem góp ý sữa chữa cái đoạn code này dùm nghen. Và rất quan trọng, t chưa hiểu hết các ý nghĩa của các từ khóa config bit, đọc datasheet thấy có 1 số bit nằm trong từ khóa, còn 1 số từ khóa khác k biết ý nghĩa là gì tại nó không có trong datasheet, chẳng hạn XT hay RC. Anh em biết ý nghĩa từ khóa nào thì post lên, tổng hợp lại cho đỡ rối cái config( config mà sai là chạy sai lất hết , hiện chưa biết chỉnh sữa lại config lại như thế nào! ) | |
| | | Lee phó tổng giám đốc
Tổng số bài gửi : 106 Join date : 29/12/2009 Age : 34 Đến từ : Tây Ninh
| Tiêu đề: Re: Bài tập Counter0 Sat May 22, 2010 10:56 pm | |
| Phát hiện đầu tiên vể code chống rung phím, nhờ kil89. Code(repair lần 1): while(1) * { c=TMR0; odd=RA4; * if(odd==1 &&RA4==0) * { __delay_ms(30); TMR0=c; } // CHO SU ON DINH CUA PHIM NHAN * if(odd==1 && RA4==0) TMR0=TMR0+1; * } Đoạn code này làm cho việc TMR0 tăng không còn phụ thuộc vào bit T0SE( tại mình tự tay cho nó tăng mà). Ý tưởng: TMR0 chỉ tăng khi trạng thái trước đó là 1, trạng thái sau là 0,VD nếu có thằng nào ấn nút rồi giữ luôn thì trạng thái trước sẽ là 0, và trạng thái sau cũng là 0=>ko tăng TMR0. ( Cái này áp dụng tốt cho 8051, pic được hỗ trợ đếm khi có kick cạnh lên hay cạnh xuống nên chắc có lẽ sẽ có giải thuật tốt hơn) | |
| | | rockc4 trưởng phòng
Tổng số bài gửi : 35 Join date : 30/03/2010
| Tiêu đề: Re: Bài tập Counter0 Sat May 22, 2010 11:49 pm | |
| Cách của Hiệp cũng là cách người ta thường dùng để đọc phím từ 1 chân bất kì (ko phải chân ngắt), với 1 biến đếm (vai trò TMR0 trong đoạn code này) để mỗi khi có sự thay đổi trạng thái phím (1 --> 0 chẳng hạn) thì biến đếm đc tăng lên. Đoạn code kiểm tra trạng thái trong phần while(1) là cách thường dùng để chống rung phím. Theo cách trên Timer0 không tự tăng - mà đc cộng thêm sau mỗi lần xác nhận là có nhấn phím. Cho nên nói chính xác là, nó chưa hẳn là chức năng counter của bộ timer. Nếu phần cứng không phải là phím nhất mà là lazer, hồng ngoại, cảm biến khác ... thì sẽ không phải nhức đầu vì phần chống rung phím này (chuyển qua ngâm cứu chống nhiễu ) Còn với bộ counter, mình không kiểm soát được việc nó đọc bao nhiêu xung, cứ mỗi xung thì nó lại tự tăng giá trị chứa trong TMR0. cách tốt nhất để đảm bảo có lẽ là dùng delay. Vấn đề là dùng delay thế nào? NGoài ra để hạn chế rung = phần cứng thì nên gắn thêm tụ C như Hiệp nói. | |
| | | Nhok_kid phó giám đốc
Tổng số bài gửi : 66 Join date : 29/12/2009 Age : 34 Đến từ : Hà Tĩnh
| Tiêu đề: Re: Bài tập Counter0 Sun May 23, 2010 12:52 am | |
| Mình dùng cách này (chưa test ^ ^ do ko có gì test cả - cháy mạch nạp rồi) Ý tưởng : vẫn dùng cạnh tác động (ở đây mình chọn cạnh xuống), khi nhấn nút, lập tức TMR0 tăng lên, mình lưu lại giá trị này và sau 30ms nạp lại cho TMR0 nhằm xóa mọi tác động nếu có trong 30ms đó.
đoạn chương trình trong main
while(1) { while(RA4); // chờ nhấn phím, thoát ra ngay khi nhấn phím c = TMR0; // lưu giá trị dc tăng lên 1 của TMR0 __delay_ms(30); TMR0 = c; // loại bỏ mọi tác động trong thời gian delay }
nếu nhấn phím giữ hoài thì khi quay lại vòng lặp giá trị TMR0 sẽ chỉ thay đổi khi có cạnh xuống xuất hiện thời điểm sau lệnh TMR0 = c và trc lệnh c= TMR0 =>> thời gian rất ngắn, theo mình thì ko có sai số chỗ này. | |
| | | blue giám đốc điều hành
Tổng số bài gửi : 96 Join date : 28/12/2009 Age : 34 Đến từ : ninh thuận
| Tiêu đề: Re: Bài tập Counter0 Sun May 23, 2010 11:12 am | |
| cách của Lee và Đại và của mình nữa,ý tưởng là giống nhau.mình đã test thử rồi,chạy ok.chỉ góp ý là mỗi lần bấm phím sẽ gồm nhấn xuống và thả ra.trạng thái thả ra,tức RA4 =1 trở lại chính là thời điểm kết thúc nhấn phím.ta sẽ bắt thời điểm này để làm led hiển thị | |
| | | Nhok_kid phó giám đốc
Tổng số bài gửi : 66 Join date : 29/12/2009 Age : 34 Đến từ : Hà Tĩnh
| Tiêu đề: Re: Bài tập Counter0 Sun May 23, 2010 1:17 pm | |
| cách của Hiệp thì hiểu rồi nhưng cách của Hải đâu? | |
| | | blue giám đốc điều hành
Tổng số bài gửi : 96 Join date : 28/12/2009 Age : 34 Đến từ : ninh thuận
| Tiêu đề: Re: Bài tập Counter0 Sun May 23, 2010 1:55 pm | |
| đây: - Spoiler:
#include<htc.h> __CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN & IESODIS & FCMDIS & LVPDIS & DEBUGDIS); __CONFIG(BORV21); #define _XTAL_FREQ 4000000 //================================================================ //chuong trinh ung dung timer 0 o che do counter //cong tac nhan noi chan RA4,khong nhan = 1,nhan =0 //moi lan nhan 1 led se sang //khi nhan du 8 led sang thi se tat dan tung led,tat het thi se sang lai //board led la cua chi phuong dua (port ra muc 0 thi led sang)
void main(void) { char j,k; signed char i; // Khoi tao I/O cho cac port ANSEL=0x00; ANSELH=0x00; TRISA4 = 1; // Pin A.4 as input TRISB = 0x00; //port B as output PSA= 1; //no prescaler T0CS= 1; //timer 0 as counter T0SE= 1; //nhan canh xuong TMR0= 0x00;
PORTB=0xFF; i=0; k=0; while(1) { while(RA4); j=TMR0; __delay_ms(30); TMR0=j; if (RA4==1)//phim duoc nha { if (k%2==0) {PORTB -=1<<i; i++; } else{PORTB +=1<<i;i++;}; if (i>7) {i=0;k++;}; }; }; }
| |
| | | anhcmut phó phòng
Tổng số bài gửi : 24 Join date : 10/06/2010
| Tiêu đề: cho em hỏi cái này chut. Fri Feb 25, 2011 12:34 pm | |
| mình dùng counter0 mà dùng dao động nội để đưa vào chân A4 dùng để đếm xung được không ạ? | |
| | | Sponsored content
| Tiêu đề: Re: Bài tập Counter0 | |
| |
| | | | Bài tập Counter0 | |
|
Trang 1 trong tổng số 1 trang | |
| Permissions in this forum: | Bạn không có quyền trả lời bài viết
| |
| |
| |