Kalibrierung des RC-Oscillators

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 Re­load­­wert 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 ver­wen­det, die mit Hilfe des Inkrementalgeber beeinflusst wird. Wird der Inkrementalgeber im Uhr­zeiger­sinn gedreht, wird „ucValue“ um „1“ erhöht, ansonsten um „1“ erniedrigt. Er­stel­len 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 Ab­weichung 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