www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik RB0 als externe Interrupt-"Quelle"


Autor: bemyguest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab nen PIC18F mit einem FPGA verbunden und möchte das der FPGA 
einen Interrupt im PIC auslösen kann. Dafür möchte ich RB0 verwenden. 
Leider klappt das nicht (blutiger Anfänger :/). Mein C-Code:
main()

{
  
   char command, shift;
  
   Init_Hardware(); //setzt bestimmte Portbits 
   delay_s(3); //zusätzlich eingeführt um sicher zu stellen das alle       
               //Betriebsspannungen aufgebaut sind 
   trisb.0=0;
   trisb.2=0; 
   
   //Interrupt an RB0 erlauben (fallende Flanke)
   intcon.GIE=1;       // Interrupts erlauben
   intcon.INT0IE=1;          // Interrupt von RB0 erlauben.
   intcon2.INTEDG0=0;        // Fallende Flanke am RB0

   while(1)
   {
   .
   .
   .
   }
}

void interrupt()
{
  if (intcon.RBIF==1) //Flag-Abfrage
  {
    intcon.RBIF=0; //Lösche Flagbit
    trisb.2=0; 
    portb.1=1; //Testausgabe ob Interrupt aufgerufen wurde
    delay_s(1); 
    portb.2=0;   
    delay_s(1);
  }
  
  intcon.GIE = 1; //Interrupts wieder erlauben
}

Der FPGA is einfach so programmiert, das er bei einem Reset RB0 auf 0 
zieht, ansonsten immer 1.
Was ich realisieren möchte ist, das der PIC aus der while(1)-Schleife 
rausspringt, sobald er das Signal vom FPGA bekommt und kurzfristig etwas 
wichtige Befehle abarbeitet...
Was hab ich vergessen, was mach ich falsch? hoffentlich nicht alles...

Pls help!

Autor: bemyguest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe den Code noch einmal editiert, funzt leider immer noch nicht...
main()
{
  //Init_Hardware();
  porta.4=1;
  delay_s(3);        
        trisb.0=1;    //RB0=Input
        trisb.2=0;              //RB2=Output //toggle led to indicate  
                                //interrupt.
  inter_ini();

  while(1)
  {
  }

}         
        
void interrupt()
{  
  intcon.INT0IF=0; //clear flag
  delay_s(2);
  portb.2=1;
  delay_s(2);
}
               
               
               
void inter_ini()
{
  intcon.INT0IE=1; //enable external interrupt 1 on B0.
  intcon.INT0IF=0; //clear external interrupt flag.
  intcon2.RBPU=1; //turn off pull-ups
  intcon.PEIE=0; //peripheral enable bit set false
  intcon.INT0IE=0; //active on falling edge
  intcon.GIE=1; //global interrupt enable on
}


wieso springt der Interrupt nicht auf einen Flankenwechsel an RB0 an???

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
schau Dir mal das hier an:
http://pic-projekte.de/pic_c.html#intpic

Du musst eine richtige ISR einleiten. Einfach eine Funktion als 
INTERRUPT zu benennen funktioniert so leider nicht. Schau dir den Link 
mal an, mal sehen ob es Dir weiterhilft.

Nabend

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag: Außerdem schau mal:
void inter_ini()
{
> intcon.INT0IE=1; //enable external interrupt 1 on B0.
  intcon.INT0IF=0; //clear external interrupt flag.
  intcon2.RBPU=1; //turn off pull-ups
  intcon.PEIE=0; //peripheral enable bit set false
> intcon.INT0IE=0; //active on falling edge
  intcon.GIE=1; //global interrupt enable on
}

Bei dem zweiten suchst Du wahrscheinlich dieses hier: INTEDG0

Autor: bemyguest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok die Intcon-Register-settings waren nicht 100% korrekt, diese habe ich 
jetzt berichtigt.

Allerdings verstehe ich immer noch nicht wie ich den Interrupt jetzt 
genau initialisiere. Ich benötige also eine pragma-Direktive in der ich 
dem Compiler mitteile an welche Adresse bzw. in welche Routine (die an 
angegebener Adresse sich befindet) er bei einem Interrupt springen soll, 
soweit so gut.

Allerdings sind alle Direktiven die ich bisher im Netz gefunden habe 
nicht mit meinem Compiler kompatibel. Ich benutze Sourceboost und habe 
weder in der Hilfe noch in der PIC18F4520.h-Datei eine Direktive 
gefunden die sich auf eine Interrupt-Initialisierung bezieht. Kennt sich 
hier jemand mit Sourceboost in Verbindung mit der 18F-Familie aus?!

Ich möchte definiv keine if- oder while-Schleife verwenden in der ich 
das Intcon-Interrupt-Flag abfrage, sondern eine richtige 
Interrupt-Routine, welche bei auftreten eines Interrupts (Flankenwechsel 
an RB0) direkt das main()-prog verlässt und in Interruptroutine springt.

Please help :)

Autor: heinzhorst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der 18F4520 hat einen Silicon-Bug beim Aufruf der ISR. Muss man mit 
einem kleichen Workarround fixen. Bin ich vor kurzen auch drauf 
reingefallen, allerdings mit dem Timer0-Interrupt. Allerdings hab ich 
noch nie was von Sourcebost gehört. Ich poste mal meinen ISR-Code für 
den MCC18, vielleicht hilft dir das ja weiter.

//  interrupt service routine

#pragma interruptlow LowISR
void LowISR(void){

  //  add low priority interrupt handlers here    

  TickUpdate();  // Timer0 ISR

}


#pragma interrupt HighISR
void HighISR(void){

  //  add high priority interrupt handlers here

  uart_isr();
  
}


#pragma code LowVector=0x18
void LowVector(void){_asm goto LowISR _endasm}
#pragma code HighVector=0x08
void HighVector(void){_asm goto HighISR _endasm}
#pragma code // Return to default code section


//  main


void main(void){

// initialisation

RCONbits.IPEN = 1;

TickInit();


//  enable global interrupt
INTCONbits.GIEL = 1;
INTCONbits.GIEH = 1;

uart_puts_rom("Hello world!");

while(1){

  // main loop
}


so, dazu noch die Initialisierung des Timers:

void TickInit(void)
{

  // Use Timer0 for 8 bit processors
    // Initialize the time
    TMR0H = 0;
    TMR0L = 0;

  // Set up the timer interrupt
INTCON2bits.TMR0IP = 0;    // Low priority
    INTCONbits.TMR0IF = 0;
    INTCONbits.TMR0IE = 1;    // Enable interrupt

    // Timer0 on, 16-bit, internal timer, 1:256 prescalar
    T0CON = 0x87;


}

Autor: bemyguest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

allerdings bekomme ich auch hier die Meldung: Unknown or Invalid Pragma 
für #pragma interrupt HighISR und #pragma code LowVector=0x18.


Welchen Compiler könnt ihr den empfehlen, evtl ist Sourceboost auch 
einfach murks...wenns geht freeware...

THX!

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bemyguest schrieb:
> Danke!
>
> allerdings bekomme ich auch hier die Meldung: Unknown or Invalid Pragma
> für #pragma interrupt HighISR und #pragma code LowVector=0x18.
>
>
> Welchen Compiler könnt ihr den empfehlen, evtl ist Sourceboost auch
> einfach murks...wenns geht freeware...
>
> THX!

Das ist ein Code für MPLAB und den entsprechenden C18 Compiler den es 
kostenlos von Microchip gibt.

http://pic-projekte.de/pic_c.html

Da geht's los.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.