Der interne RC-Oscillator arbeitet mit einer internen Frequenz von 7.3728 MHz und einer Toleranz von +/-2,5 %. Damit die Timer mit zeitlich korrekten Reloadwerten arbeiten, muss die Abweichung des RC-Oscillators ermittelt werden.
Erstellen sie ein Programm, in dem der Timer 0 in der Betriebsart 1 und mit einem Reloadwert von 1 ms arbeitet. Aufbau und Funktionsweise des Timers sind in Kapitel 10.10 [3] beschrieben. Die ISR des Timer 0 soll den Zustand des Portpins P1.0 wechseln. Das Rechtecksignal von P1.0 wird als Messkriterium für die Toleranz verwendet. Um die Kalibrierung zu vereinfachen, wird die Variable „ucValue“ für den Reloadwert verwendet, die mit Hilfe des Inkrementalgeber beeinflusst wird. Wird der Inkrementalgeber im Uhrzeigersinn gedreht, wird „ucValue“ um „1“ erhöht, ansonsten um „1“ erniedrigt. Erstellen sie das Projekt aus Tabelle 42.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
CallRCOsci |
Test_CallRCOsci |
TestCalibration.c, |
|
|
..\Library |
PortConfig.c |
Tabelle 42 Projekt CallRCOsci
|
|
#include <REG932.H> #include <PortConfig.H>
// Bourns EPS1D-F19-AE0036 (2-bit gray code) sbit EncSwitch = P0^6; // Taster (Jumper 7) sbit EncChA = P0^5; // Kanal A (Jumper 8) sbit EncChB = P0^7; // Kanal B (Jumper 9)
sbit sb1ms = P1^0;
unsigned int ucValue = 0xF196; // Reloadvalue 1 ms unsigned char ucActEncVal; // akt. Position des Inkrementalgebers
void v_InitTimer0_1ms(void) { // Timer 0 für 1msec initialisieren TMOD = TMOD | 0x01; TL0 = (unsigned char) ucValue; TH0 = ucValue/256; TF0 = 0; ET0 = 1; EA = 1; }
void v_InitEncoder(void) { KBMASK = 0xE0; // Maske fuer Portpin 5, 6 und 7 ucActEncVal = P0 & 0xA0; // Abspeichern der akt. Position KBPATN = P0 & 0xE0; // Setzen des Keyboard-Patterns KBCON = 0x00; EKBI = 1; // ISR fuer Keyboard-Int. freigeben }
void main(void) { v_PortConfig(Port1, Pin0, BiDir); // P2 als Quasi-bidir. v_InitTimer0_1ms(); TR0 = 1; // Timer 0 starten v_InitEncoder(); while(1); }
void v_Timer0Int(void) interrupt 1 using 1 { TL0 = (unsigned char)ucValue; TH0 = ucValue/256; sb1ms = !sb1ms; }
// ISR des Keyboard void v_KeyboardInt(void) interrupt 7 { KBPATN = P0 & 0xE0; // Neues Keyboard-Pattern setzen if (ucActEncVal != (P0 & 0xA0)) // Abfrage, ob Aenderung beim { // Inkrementalgeber erfolgt ist switch(P0&0xA0) { case 0x00: if (ucActEncVal == 0x20) ucValue--; else ucValue++; break; case 0x20: if (ucActEncVal == 0xA0) ucValue--; else ucValue++; break; case 0x80: if (ucActEncVal == 0x00) ucValue--; else ucValue++; break; case 0xA0: if (ucActEncVal == 0x80) ucValue--; else ucValue++; break; } ucActEncVal = P0 & 0xA0; // Abspeichern der neuen Positon } // des Inkrementalgebers KBCON = 0x00; // Loeschen des Keyboard Flags } |
Listing 28 Inhalt von TestCalibration.c
Erweitern sie das Programm so, dass der aktuelle Reloadwert von Timer 0 und die Abweichung auf dem LCD-Display ausgegeben werden. Dazu müssen sie die Sourcemodule „LCDLib_4bitPort.c“ und „CGRAM_V7.c“ zu ihrem Projekt hinzufügen.
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
CallRCOsci |
Test_CallRCOsci |
TestCalibration.c, |
|
|
..\Library |
PortConfig.c CGRAM_V7.c, LCDLib_4bitPort.c |
Tabelle 43 Projekt CallRCOsci (mit LCD-Ausgabe an Port 2)
|
|
#include <REG932.H> #include <PortConfig.H> #include <lcd_def.h> #include <stdio.h>
// Bourns EPS1D-F19-AE0036 (2-bit gray code) sbit EncSwitch = P0^6; // Taster (Jumper 7) sbit EncChA = P0^5; // Kanal A (Jumper 8) sbit EncChB = P0^7; // Kanal B (Jumper 9)
sbit sb1ms = P1^0;
unsigned int ucValue = 0xF196; // Reloadvalue 1 ms unsigned char ucActEncVal; // akt. Position des Inkrementalgebers
void v_InitTimer0_1ms(void) { // Timer 0 für 1msec initialisieren TMOD = TMOD | 0x01; TL0 = (unsigned char) ucValue; TH0 = ucValue/256; TF0 = 0; ET0 = 1; EA = 1; }
void v_InitEncoder(void) { KBMASK = 0xE0; // Maske fuer Portpin 5, 6 und 7 ucActEncVal = P0 & 0xA0; // Abspeichern der akt. Position KBPATN = P0 & 0xE0; // Setzen des Keyboard-Patterns KBCON = 0x00; EKBI = 1; // ISR fuer Keyboard-Int. freigeben }
void main(void) { v_PortConfig(Port2, AllPins, BiDir); // P2 als Quasi-bidir. uc_LCDIni(_2LINE | _7DOTS); // Initialisierung des LCD-Displays uc_Clrscr(); // Loeschen des HD44780 Speichers.
v_PortConfig(Port1, Pin0, BiDir); // P2 als Quasi-bidir. v_InitTimer0_1ms(); TR0 = 1; // Timer 0 starten v_InitEncoder();
do { printf("\n%cAct. Val:0x%x ",_1_LINE,ucValue); printf("\n%cDiv. Val:%i ",_2_LINE,0xF196 - ucValue); } while(1); }
void v_Timer0Int(void) interrupt 1 using 1 { TL0 = (unsigned char)ucValue; TH0 = ucValue/256; sb1ms = !sb1ms; }
// ISR des Keyboard void v_KeyboardInt(void) interrupt 7 { KBPATN = P0 & 0xE0; // Neues Keyboard-Pattern setzen
if (ucActEncVal != (P0 & 0xA0)) // Abfrage, ob Aenderung beim { // Inkrementalgebers erfolgt ist switch(P0&0xA0) { case 0x00: if (ucActEncVal == 0x20) ucValue--; else ucValue++; break; case 0x20: if (ucActEncVal == 0xA0) ucValue--; else ucValue++; break; case 0x80: if (ucActEncVal == 0x00) ucValue--; else ucValue++; break; case 0xA0: if (ucActEncVal == 0x80) ucValue--; else ucValue++; break; } ucActEncVal = P0 & 0xA0; // Abspeichern der neuen Positon } // des Inkrementalgebers KBCON = 0x00; // loeschen des Keyboard Flags } |
Listing 29 Inhalt von TestCalibration.c