עבור לתוכן

הפעלת טיימר2 במיקרו בקר 89c52 איך עושים זאת? (צריך הסבר גם איך עובד הטיימר)

Featured Replies

פורסם

אני רוצה ליצור השהייה של 1 ms באמצעות טיימר2 במיקרו בקר שלי (89c52) (טיימר 2, לא טיימר 0 או 1)

בשפת C כמובן..

ובנוסף רציתי לדעת איך הטיימר עובד?

תודה רבה!

  • תגובות 30
  • צפיות 4.6k
  • נוצר
  • תגובה אחרונה
פורסם

כמו טיימרים 0 ו-1 גם טיימר 2 יכול לעבוד כמונה או כקוצב זמן.

את אופני הפעולה בוחרים ע"י האוגר T2CON, כאשר אות השעון מגיע מהמתנד של המיקרובקר או ממקור חיצוני ברגל T2,זה נקבע בסיבית C/T2 כמו בסיבית C/T שבטיימרים 0 ו-1. סיבית TR2 מפעילה את הטיימר.

לטיימר 2 יש שלושה מצבי פעולה:

auto-reload- מצב זה נבחר כאשר הסיבית CP/RL2 שבאוגר T2CON ב-0. האוגרים RCAP2L ו-RCAP2H שומרים על ערך שיטען לאוגרים TL2 וTH2 (ולא כמו בטיימר 0 ו-1 כאשר האוגר TL שימש כמונה 8 סיביות והאוגר TH שמר על ערך התחלתי,כאן טיימר 2 משמש כמונה 16 סיביות עם טעינה אוטומטית).

גלישה מFFFFH תעלה את דגל הפסיקה TF2.

כאשר הסיבית EXEN2 ב-1 תתבצע טעינה במעבר מ-1 ל-0 ברגל T2EX שבמיקרובקר.

capture- המצב נבחר כאשר הסיבית CP/RL2 ב-1. טיימר 2 משמש כמונה 16 סיביות,שוב במעבר מFFFFH ל0000H דגל TF2 עולה ל-1.

כאשר סיבית EXEN2 ב-1,במעבר מ-1 ל-0 ברגל T2EX הערכים שבאוגרים TL2/TH2 יועתקו בהתאמה לאוגרים RCAP2L/RCAP2H והדגל EXF2 יעלה ל-1.

baud rate generator-במצב זה טיימר 2 יוצר את קצב השידור בפורט הטורי. הסיביות TCLK וRCLK קובעות מאיפה יסופק הBaud rate בשידור ובקליטה בהתאמה,כאשר אחד מהם ב-1 קצב השידור יקבע ע"י טיימר 2, אם ב-0 הקצב בשידור או בקליטה יקבע ע"י טיימר 1.

כדי לאפשר פסיקות מטיימר 2 יש לקבוע 1 בסיבית ET2 באוגר IE.

עדיפות פסיקה לטיימר 2 נקבעת בסיבית PT2 באוגר IP.

פורסם
  • מחבר

תודה רבה רבה על התשובה!

לפי מה שהבנתי הכי פשוט כדי ליצור השהייה של 1MS נגיד עדיף מצב capture?

עכשיו כדי לעשות את זה אני עושה את הפעולות הבאות

סיבית

TR2=1;

CP/RL2=1;

עכשיו הוא מונה 16 סיביות שהוא מגיע ל0xFFFF (מצב גלישה) דגל TF2=1

עכשיו אם יש לי גביש של 12Mhz מה הזמן מחזור של טיימר זה ואיך אני מחשב אם אני רוצה 1MS?

שוב תודה רבה, תום.

פורסם

אתה רוצה שאות השעון לטיימר יתבסס על תדר מתנד של 12MHz לכן סיבית CP/RL2 צריכה להיות ב-0. (סכימת המלבנים של הטיימר בתמונה למטה)

כפי שאתה יכול לראות,אות השעון שמגיע למתנד מחולק ב-12,לכן הוא יהיה 1MHz,והמונה יקודם כל מיקרושניה.

בשביל מילישניה המונה צריך לספור 1000 דפקים שזה 3E8H.

לכן נטען את האוגרים TL/TH ב-FFFFH-3E8H = FC17H כך שדגל הפסיקה יעלה ל-1 לאחר 1000 דפקים.

TH2=FCH

TL2=17H

[attachment deleted by admin]

פורסם
  • מחבר

האם אני צריך להשתמש באוגרים RCAP2L/RCAP2H ?

ובסיבית EXEN2 ?

או שאני פשוט טוען את TL/TH במספרים ועושה פסיקה מתי שהדגל עולה ל-1 ובפסיקה טוען שוב את TL/TH?

שוב תודה, תום.

פורסם

קודם כל בהודעה הקודמת שלי כתבתי שסיבית CP/RL2 צ"ל ב-0,התכוונתי לסיבית C/T2. סיבית C/RL2 אכן צריכה להיות ב-1 במצב capture.

אינך צריך להשתמש בסיבית EXEN2 ובאוגרים RCAP2L/H בשביל השהיה.

כמו שאמרת,תטען את האוגרים TL/TH שוב.

אל תשכח להוריד את הדגל TF2 ל-0 בפסיקה.

פורסם
  • מחבר

אוקי זה התוכנית שעשיתי, עכשיו אם אני רוצה השהייה של 1MS אני פשוט שם את התת תוכנית TIMER2_1ms() בVOID MAIN? (בתוכנית הראשית)


#include "reg_c51.h"
#include <stdio.h>

int a;


TIMER2_1ms()
{


TH2=0xFC; //load TH2 and TH1 in FC17h
TL2=0x17;
EXF2=0; /* reset flag */
TCLK=0;RCLK=0; /* disable baud rate generator */

C_T2=0; /* timer mode */
CP_RL2=1; /* capture mode */
EA=1; /* interupt enable */
ET2=1; /* enable timer2 interrupt */
TR2=1; /* timer2 run */



}



it_timer2() interrupt 5
{
if(TF2) a++;


TF2 = 0; /* reset interrupt flag */
TH2=0xFC; //load TH2 and TH1 in FC17h
TL2=0x17;
}

פורסם

#include "reg_c51.h"
#include <stdio.h>

int a;


void TIMER2_1ms()
{


TH2=0xFC; //load TH2 and TH1 in FC17h
TL2=0x17;
EXF2=0; /* reset flag */
TCLK=0;RCLK=0; /* disable baud rate generator */

C_T2=0; /* timer mode */
CP_RL2=1; /* capture mode */
EA=1; /* interupt enable */
ET2=1; /* enable timer2 interrupt */
TR2=1; /* timer2 run */



}



it_timer2() interrupt 5
{
if(TF2) a++;


TF2 = 0; /* reset interrupt flag */
TH2=0xFC; //load TH2 and TH1 in FC17h
TL2=0x17;
}
void main()
{
TIMER2_1ms(); //calls timer2_1ms function
}

בעקרון זה מה שאתה אמור לעשות, ערכתי את הקוד שלך.

אם אני לא טועה (לא מבין גדול כל כך בc51) צריך להגדיר את הערך שהפונקציה מחזירה (void במקרה הזה).

ולקרוא לפונקציה בתוכנית הmain.

פורסם

ממעט היכרותי עם C51,לדעתי זה אמור להיות כך:

#include "reg_c51.h"
#include <stdio.h>

int a;

void TIMER2_1ms()
{

T2CON=0x01;
EA=1;
ET2=1;

TH2=0xFC;
TL2=0x17;

TR2=1;
}


void it_timer2() interrupt 5
{
a++;

TF2 = 0; /* reset interrupt flag */
TH2=0xFC; //load TH2 and TH1 in FC17h
TL2=0x17;
}

void main()
{
TIMER2_1ms(); //calls timer2_1ms function

while(1);
}

פורסם
  • מחבר

אוקי, תודה.

עכשיו איך אני עושה שהתוכנית תרוץ מס' פעמים למשל אם אני רוצה חצי שניה אז לרשום בתוכנית הראשית:

TIMER2_1ms(500); 

איך עושים שזה יפעל?

פורסם

אם אתה רוצה לשנות את זמן ההשהיה,אז לדעתי תעשה ככה:

#include "reg_c51.h"
#include <stdio.h>

int count;

void it_timer2(void) interrupt 5
{
TH2=0xFC;
TL2=0x17;
count++;
}

void delay(int cycles)
{
count=0;
while(count<cycles)
count=count;
count=0;
}

void main()
{
count=0;
T2CON=0x01;
EA=1;
ET2=1;
TH2=0xFC;
TL2=0x17;
TR2=1;

while(1);
}

עכשיו אם אתה רוצה השהיה מסויימת, אז תקרא לפונקציה delay כאשר delay=1ms*cycles.

בשביל חצי שניה תכתוב

delay(500);

פורסם
  • מחבר

אני לא רוצה שבתוכנית הראשית יהיה הוראות לטיימר, לא הבנתי מה עשית שם.

בתוכנית הראשית אני רוצה רק לשים את התת תוכנית למשל

delay(100)

איך עושים את זה?

פורסם

אם לדוגמא כתבת delay(100) המשתנה count יעלה ב-1 כל 1ms ושהוא יגיע ל-100 הלולאה תסתיים ותקבל את ההשהיה הדרושה.


#include "reg_c51.h"
#include <stdio.h>

int count;

void t2_init();
{
count=0;
T2CON=0x01;
EA=1;
ET2=1;
TH2=0xFC;
TL2=0x17;
TR2=1;
}

void it_timer2(void) interrupt 5
{
TH2=0xFC;
TL2=0x17;
count++;
}

void delay(int cycles)
{
count=0;
while(count<cycles)
count=count;
count=0;
}

void main()
{
t2_init();

while(1);
}

פורסם
  • מחבר

אז לפי מה שאתה אומר אם אני רוצה לשים השהייה של 100MS אני צריך לשים :



void main();


t2_init();
delay(100);

צריך לשים את שניהם בייחד? אי אפשר לאחד בניהם איך שהוא?


ועוד משהו לא הבנתי את התת תוכנית DELAY שעשית איך היא עובדת?

עריכה:

אם אני עושה את זה מה יקרה?:

void TIMER2_1ms(int cycles)
{


TH2=0xFC; //load TH2 and TH1 in FC17h
TL2=0x17;
EXF2=0; /* reset flag */
TCLK=0;RCLK=0; /* disable baud rate generator */

C_T2=0; /* timer mode */
CP_RL2=1; /* capture mode */
EA=1; /* interupt enable */
ET2=1; /* enable timer2 interrupt */
TR2=1; /* timer2 run */



}



it_timer2() interrupt 5
{
if(TF2)
{

TF2 = 0; /* reset interrupt flag */
TH2=0xFC; //load TH2 and TH1 in FC17h
TL2=0x17;

}

}

void main()
{
TIMER2_1ms(100); //calls timer2_1ms function
}

פורסם

הפונקציה t2_init() מאתחלת את הטיימר,לכן תכתוב אותה רק פעם אחת,בתחילת התוכנית הראשית.

הסברתי,כאשר אתה קורא לפונקציית ההשהיה delay הערך שהכנסת מועתק ל-cycles.

הלולאה שבפונקציה תעצור כאשר המשתנה count (שמקודם ב-1 כל 1ms) הגיע לערך שהכנסת, כך שתתקבל השהיה של 1ms*cycles.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים