![]() |
ISR in C erstellen
Hallo,
kann mir jemand erklären wie man eine ISR in C erstellt? Ich habe hier auch eine fertige ISR, jedoch weiß ich nicht, was die einzelnen Elemente bedeuten ;-)
Code:
static void T1_isr (void) interrupt 3
{ TL1 = 0xC0; // L-Register laden insgesamt: 0xF831 TH1 = 0x07; // H-Register laden // ... Quelltext } Gruß, elko PS: Das ist eine Timer-ISR, wenn ich mich nicht täusche |
Re: ISR in C erstellen
Zitat:
Wichtig ist halt normalerweise: Eine ISR darf keine Register verändern (ausser wenn das explizit gewünscht wird, siehe Interrupts in DOS), wenn die Hardware also nicht selber die Register sichert, muss der Programmierer sich darum kümmern. In der Regel werden dazu alle relevanten Registerinhalte einfach auf den Stack gepackt und am Ende der ISR wieder zurückgeholt. Alternative Konzepte verwenden eine Art Bankswitching um Register zwischen "Normal" und "Interrupt" zu trennen. Der Rest ist eigentlich relativ trivial, je nach Plattform muss man nur wissen welche Interrupts wie benutzbar sind und ggf. noch auf die Prioritäten schauen (manche Architekturen erlauben Interrupts mit unterschiedlicher Priorität, ein Interrupt einer bestimmten Priorität kann dann nur von Interrupts höherer Priorität unterbrochen werden). Zitat:
Zitat:
|
Re: ISR in C erstellen
Hey, danke für die Info!
Ich programmiere zur Zeit für den AN2131 von Cypress. Das ist ein USB-Controller... Leider komme ich mit der Entwicklungsumgebung von Keil, MVision3 noch nicht ganz klar (bezüglich dem Debugger). Diese ISR bringt normalerweise eine LED an einem Port zum Blinken (den Quelltext hab ich oben rausgenommen). Mein Problem liegt jetzt darin, dass -wenn man die ISR nich auskommentiert- folgendes eigentlich winzige Programm nicht funktioniert...
Code:
Viele Grüße,
void main()
{ // ... while (1) { var1=3; OUTC=var0; var0=hallo(); OUTC=var0; } } unsigned char hallo(){ return 7; } //———————————————————————————————————————————————————————————————— // Timer für ms- Zähler (bringt die LED A4 blinken) static void T1_isr (void) interrupt 3 {// TL1 = 0xC0; // L-Register laden insgesamt: 0xF831 // TH1 = 0x07; // H-Register laden TL1 = 0xC0; // L-Register laden insgesamt: 0xF831 TH1 = 0xA0; // H-Register laden if (LED_BLINK) { if (LED_COUNT-- == 0) // Zähler zurücksetzen { LED_COUNT = 50; // Schleifenzähler neu setzen OUTA ^= 0x10; // LED umschalten } } } elko |
Re: ISR in C erstellen
Hi,
Dein Timerinterrupt wird ca. alle 25 Millisekunden aufgerufen. TH1 und THL1 stehen für Timer 1 High und Timer 1 Low. Die Werte erben A0C0, was umgerechnet 41152. Ich gehe mal davon aus, dass der Timer im 16 Bit Modus arbeitet, somit findet bei 2^16 ein Interrupt statt, also alle 24,384 Millisekunden. Da nun in der If-Abfrage was von wegen 50x runterzählen ist, blinkt die LED im 50x 24,384 Millisekunden Takt, also alle 1,2 Sekunden. Wie schaltest Du den Interrupt ein? |
Re: ISR in C erstellen
Hi,
Zitat:
Aber ich finde es toll, wie du auf die 25 ms gekommen bist! Das könnte sehr gut mit der Blinkfrequenz übereinstimmen!
Code:
Wieso muss man den Timer-Interrupt eigentlich einschalten? Würde der Timer ansonsten laufen, wie vorgesehen, aber kein Interrupt und damit auch keine ISR ausgelöst?
/*------------------------------------------------------------------------------
Blink.C Copyright 1999-2003 by MmVisual - M.Müller Erstellung BlinkLED 29.12.2001 -------------------------------------------------------------------------------- Testprogramm "Blinkende LED" LED ist an Port PA4 des Cypress- Chips angeschlossen. Es wird nur dieser eine Port als Ausgang definiert. Das Programm kann in den Speicher des AN21xx geladen und gestartet werden. Sofort muss die LED anfangen zu Blinken (ca. 3 Hz). ------------------------------------------------------------------------------*/ #include <REGAN21.H> /* Register des AN21xx */ #include <EZREGS.H> /* Externe Register des AN21xx */ // Definitionen der Routinen // Belegung des Speichers xdata unsigned char T0LED; xdata unsigned char LED_BLINK _at_ 0x0101; // LED blinken lassen xdata unsigned char LED_COUNT _at_ 0x0100; // Blinkende LED - Zähler nach Timer xdata unsigned char iOEA _at_ 0x0110; xdata unsigned char iOEB _at_ 0x0111; xdata unsigned char iOEC _at_ 0x0112; xdata unsigned char iOUTA _at_ 0x0113; xdata unsigned char iOUTB _at_ 0x0114; xdata unsigned char iOUTC _at_ 0x0115; xdata unsigned char iPINSA _at_ 0x0116; xdata unsigned char iPINSB _at_ 0x0117; xdata unsigned char iPINSC _at_ 0x0118; /*------------------------------------------------ The main C function. Program execution starts here after stack initialization. ------------------------------------------------*/ void main() { EA = 0; // Ohne die folgenden 5 Zeilen kann das USB-Board sich nicht am USB-Port melden, // wenn Sie aus der IIC- Datei ein EEPROM herstellen!!! EUSB = 1; // Enable Firmware- USB //***** USBCS = 4; //***** USBIRQ = 0x1E; //***** IBNIRQ = IBNIEN = TOGCTL = 0; //***** EPIO[0] = 0x0A; // Enable Firmware- USB Ende //***** OUTA = 0x00; // Register vorbelegen OEA = 0x30; // LED-Out ausschalten T2CON = 3; // Timer 2 aus //***** TR0 = 0; // Timer 0 aus //***** T1M = 0; // Clock div 12 //***** CT1 = 0; // Timer- Betrieb ein //***** TH1 = 0x07; // H-Register laden //***** TL1 = 0xC0; // L-Register laden insgesamt: 0xF831 //***** TF1 = 1; // Interrupt ein //***** ET1 = 1; // Timer 1 Interrupt ein //***** TR1 = 1; // Timer 1 einschalten //***** EA = 1; // Interrupt ein //***** LED_COUNT = LED_BLINK = 1; // Zähler zurücksetzen und Blinken einschalten PORTACFG = 0; //***** PORTBCFG = 0; //***** PORTCCFG = 0; //***** iOUTA = 0x00; // Register vorbelegen iOEA = 0x30; // LED-Out ausschalten while (1) // IO- Werte kopieren ... { OEA = iOEA; OEB = iOEB; OEC = iOEC; OUTA = iOUTA; OUTB = iOUTB; OUTC = iOUTC; iPINSA = PINSA; iPINSB = PINSB; iPINSC = PINSC; } } //———————————————————————————————————————————————————————————————— // Timer für ms- Zähler static void T1_isr (void) interrupt 3 using 3 { TL1 = 0xC0; // L-Register laden insgesamt: 0xF831 TH1 = 0x07; // H-Register laden if (LED_BLINK) { if (LED_COUNT-- == 0) // Zähler zurücksetzen { LED_COUNT = 50; // Schleifenzähler neu setzen iOUTA ^= 0x10; // LED umschalten OUTA = iOUTA; } } } Viele Grüße, elko |
Re: ISR in C erstellen
Die Zeilen die du da markiert hast, konfigurieren die Hardware indem in spezielle Register bestimmte Werte geschrieben werden. Du solltest dringend mal die Dokumentation zu dem Chip lesen, da stehen auch alle Register mit Beschreibung drin. Jedes Register hat einen bestimmten Zweck und wird mit einer Abkürzung versehen, diese Abkürzungen stehen dann auch mit den entsprechenden zugehörigen Adressen in z.B. einem Headerfile, so dass man mit diesem Konzept im Code gut lesbar direkt schreiben kann "MeinRegisterName = 0x1234;" oder was auch immer. Prinzipiell gilt beim Reset so eines Microcontrollers: Alle Interrupts sind erstmal gesperrt (spezielle Ausnahmen bestätigen die Regel) und alle Timer sind angehalten. So verhindert man dass der Controller beim Anlegen der Versorgungsspannung irgendwelchen Unsinn macht. Das darauf laufende Programm muss dann explizit jede genutzte Resource passend konfigurieren. Das wird in den Zeilen gemacht die Du markiert hast. Die Registernamen die Du dort siehst, findest Du in der Dokumentation zu dem Prozessor wieder, dort ist dann auch beschrieben was jedes Register für eine Aufgabe hat. Faustregel: Alles was Du benutzen willst, musst Du erstmal passend einstellen.
Nachtrag: Das Manual gibts zum Beispiel ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz