Timer0-Interrupt 18F2520
Mittwoch, 23. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  PIC Mikrocontroller Allgemein  |  Timer0-Interrupt 18F2520 « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Timer0-Interrupt 18F2520  (Gelesen 380 mal)
 
Umschüler
Newbie
*
Offline Offline

Beiträge: 20


Profil anzeigen
« am: Dezember 28, 2011, 16:27:24 »

Hallo an Alle, die sich besser auskennen als ich.

Ich hoffe Ihr habt Weihnachten gut überstanden und nicht zu viele Kilo zugenommen  Zwinkernd.
Nun zu meiner Frage, kann sich mal jemand mein Programm anschauen und mir sagen, was
da noch alles falsch ist? Es sind meine ersten Schritte in C mit MPLAB und C18.
Das fertige Programm soll später mal eine Uhr steuern,mit Wecker und Kalender.
Jetzt soll aber erst mal das Grundprogramm laufen und fehlerfrei sein, dann gehts
weiter. C18 bringt nach dem compilieren keine Fehlermeldung, trotzdem bin ich der Meinung,
so richtig ist nicht alles was ich geschrieben habe.
Die Interruptroutine und der Array machen mir noch Sorgen,der Array soll später mal dazu dienen,
die Bitmuster der Zahlen auf den 7-Segmentanzeigen auszugeben.
Die Kommentare sollten eigentlich Vieles erklären, wenn nicht, dann fragt mich eben.
Einiges habe ich im Internet abgeschaut (z.Bsp. SPRUT)aber nicht so richtig umsetzen können.
Vielen Dank schon mal im Voraus, Gruß der EX-Umschüler.



Code:
//-----------------------------------------------------------------------------------------------------------------------------------------------

// Pinbelegung PIC 18F2520

//    RB7  RB6  RB5  RB4  RB3  RB2  RB1  RB0  VDD  VSS  RC7  RC6  RC5  RC4
// | + ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  +  |
// |   28   27   26   25   24   23   22   21   20   19   18   17   16   15      |
// |+-+                                                                     |
//                     |                                                                                             //                |+-+                                     |
// |   1    2    3    4    5    6    7    8    9    10   11   12   13   14      |
// | + ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  +  |
//    MCLR RA0  RA1  RA2  RA3  RA4  RA5  VSS  OS1  OS2  RC0  RC1  RC2  RC3

//-----------------------------------------------------------------------------------------------------------------------------------------------

/*
Darstellung der Ziffern durch PORTB:

Ziffer    Ports Segmente        HEX     BIN DEZ Zuordnung
  0 RB/0/1/2/3/4/5 a/b/c/d/e/f 0x3F  00111111  63             a = RB0
  1 RB/1/2 b/c 0x06  00000110        06             b = RB1
  2 RB/0/1/3/4/6 a/b/d/e/g 0x5B  01011011  91             c = RB2
  3 RB/0/1/2/3/6 a/b/c/d/g 0x4F  01001111  79             d = RB3
  4 RB/1/2/5/6 b/c/f/g 0x66  01100110       102             e = RB4
  5 RB/0/2/3/5/6 a/c/d/f/g 0x6D  01101101       109             f = RB5
  6 RB/0/2/3/4/5/6 a/c/d/e/f/g 0x7D  01111101       125             g = RB6
  7 RB/0/1/2 a/b/c 0x07  00000111        07
  8 RB/0/1/2/3/4/5/6 a/b/c/d/e/f/g        0x7F  01111111       127
  9 RB/0/1/2/3/5/6 a/b/c/d/f/g 0x6F  01101111       111
 
            0 > Segment a     AAAAA  
1 > Segment b  F     B  
2 > Segment c  F     B  
3 > Segment d   GGGGG      
4 > Segment e  E     C
5 > Segment f  E     C  
6 > Segment g   DDDDD  
7 > frei

PORTA: RA0 = S5 (Minus)
RA1 = S4 (Start/Stop)
RA2 = S3 (Plus)
RA3 = S2 (Menue)
RA4 = TOCKI (Eingang externer Takt = 3,2768 MHz)
RA5 = Summer

RA0 - RA4 = Eingang
RA5 = Ausgang

PORTC: RC0 = 7-Segmentanzeige Stunden   - ZEHNER = LATC = 0xFE;
RC1 = 7-Segmentanzeige Stunden   - EINER = LATC = 0xFD;
RC2 = 7-Segmentanzeige Minuten   - ZEHNER = LATC = 0xFB;
RC3 = 7-Segmentanzeige Minuten   - EINER = LATC = 0xF7;
RC4 = 7-Segmentanzeige Sekunden  - ZEHNER = LATC = 0xEF;
RC5 = 7-Segmentanzeige Sekunden  - EINER = LATC = 0xDF;

RC0 - RC5 = Ausgang

Externer Takt (FOSC = 3,2768 MHz)
Prescaler = 128
Vorteiler = 4
Timer0 = 256 Takte bis zum Überlauf

3,2768MHz / (4 * 256 * 128) = 25 Überläufe pro Sekunde

*/

//Delay1KTCYx(10); //Zeitschleife von   10 ms (100Hz)
//Delay1KTCYx(20); //Zeitschleife von   20 ms (50Hz)
//Delay10KTCYx(10); //Zeitschleife von  100 ms (10Hz)
//Delay10KTCYx(25); //Zeitschleife von  250 ms (4Hz)
//Delay10KTCYx(50); //Zeitschleife von  500 ms (2Hz)


#include <p18cxxx.h>     /* Headerdatei für PIC automatisch einbinden,
        Festlegung erfolgt im Projekt */
 
#include <delays.h>     //Headerdatei Zeitschleifen
#include <stdio.h>
#include <stdlib.h>

#pragma config WDT = OFF, OSC = XT,  IESO = OFF, LVP = OFF, MCLRE = ON, STVREN = OFF, DEBUG = OFF, WRT0 = OFF, WRT1 = OFF, CP0 = OFF, CP1 = OFF, CPD = OFF, BOREN = OFF, PBADEN = OFF

#define  TRISA   0x1F; //PortA : RA0 - RA4 = Eingang / RA5 = Ausgang
#define  TRISB   0x00; //PortB  = Ausgang
#define  TRISC 0x00; //PortC = Ausgang

#define Delay1TCY() Nop()

#pragma code _LOW_INTERRUPT_VECTOR = 0x18

#pragma interruptlow InterruptHandler

void _low_ISR (void)
{
    _asm
        goto InterruptHandler       // Sprung zur Interruptroutine
    _endasm
}
//-----------------------------------------------------------------------------------------------------------------------------------------------
#pragma code   /* Nun kommt das eigentliche Programm.
 Da es in den Programmspeicher geschrieben
 werden soll, muß zuerst die #pragma code -
 Direktive stehen.*/
//-----------------------------------------------------------------------------------------------------------------------------------------------

unsigned char i; //Zahlenbereich von 0 - 255
 
unsigned char TASTEN;           //Zahlenbereich von 0 - 255 für Abfrage TASTEN

unsigned char counter = 0; //Überlaufzähler Timer0 = Zahlenbereich von 0 - 255 und zurückgesetzt auf NULL
   
//-----------------------------------------------------------------------------------------------------------------------------------------------
void InterruptHandler (void)
{

if(INTCONbits.INT0IF == 1) //Wenn Timer0-Interruptflag gesetzt,
{

counter++; //dann erhöhe Überlaufzähler um 1.

if(counter==25) //Wenn der Überlaufzähler den Wert 25 hat,
{
//dann...Funktion für Uhr

counter=0; //Überlaufzähler zurücksetzen

}
}

INTCONbits.INT0IF = 0; //Interruptflag löschen
}

//----------------------------------------------------------------------------------------------------------------------------------------------

void t0_ini (void)
{
// Datenblatt Seite 125
T0CON = 0b11100110;
        // 1------- Timer0 = ON
        // -1------ Timer0 = 8bit (0 - 255)
// --1----- Takt an T0CKI (RA4) für Timer0 verwenden
// ---0---- Bei externem Takt an steigender Flanke inkrementieren
// ----0--- Prescaler für Timer0 verwenden
// -----110 Prescaler 1:128

// Datenblatt Seite 95
INTCON = 0b11110110;
// 1------- Enables all unmasked interrupts
// -1------ Enables all unmasked peripheral interrupts
// --1----- Enables the TMR0 overflow interrupt
// ---1---- Enables the INT0 external interrupt
// ----0--- Disables the RB port change interrupt
// -----1-- TMR0 register has overflowed (must be cleared in software)
// ------1- The INT0 external interrupt occurred (must be cleared in software)
// -------0 None of the RB<7:4> pins have changed state

}
//------------------------------------------------------------------------
void setup (void)
{
ADCON0  = 0x00; // Pins als digital I/O

PORTA  = 0x00; // Port A,B und C löschen
PORTB  = 0x00;
PORTC  = 0x00;
}

//-----------------------------------------------------------------------------------------------------------------------------------------------
void ANZEIGEN_NULL_(void) //Bitmuster Ziffer 0 ausgeben
{
for(i=0;i<=5;i++)
{
LATC  =  0xDF; //Segment Sekunden EINER einschalten
LATB  =  0x3F; //Bitmuster Ziffer 0
Delay10KTCYx(10); //Zeitschleife von 100 ms (10Hz)
LATB  =  0x00; //Anzeige AUS
Delay10KTCYx(25); //Zeitschleife von 250 ms (4Hz)

LATC  =  0xEF; //Segment Sekunden ZEHNER einschalten
LATB  =  0x3F; //Bitmuster Ziffer 0
Delay10KTCYx(10); //Zeitschleife von 100 ms (10Hz)
LATB  =  0x00; //Anzeige AUS
Delay10KTCYx(25); //Zeitschleife von 250 ms (4Hz)

LATC  =  0xF7; //Segment Minuten EINER einschalten
LATB  =  0x3F; //Bitmuster Ziffer 0
Delay10KTCYx(10); //Zeitschleife von 100 ms (10Hz)
LATB  =  0x00; //Anzeige AUS
Delay10KTCYx(25); //Zeitschleife von 250 ms (4Hz)

LATC  =  0xFB; //Segment Minuten ZEHNER einschalten
LATB  =  0x3F; //Bitmuster Ziffer 0
Delay10KTCYx(10); //Zeitschleife von 100 ms (10Hz)
LATB  =  0x00; //Anzeige AUS
Delay10KTCYx(25); //Zeitschleife von 250 ms (4Hz)

LATC  =  0xFD; //Segment Stunden EINER einschalten
LATB  =  0x3F; //Bitmuster Ziffer 0
Delay10KTCYx(10); //Zeitschleife von 100 ms (10Hz)
LATB  =  0x00; //Anzeige AUS
Delay10KTCYx(25); //Zeitschleife von 250 ms (4Hz)

LATC  =  0xFE; //Segment Stunden ZEHNER einschalten
LATB  =  0x3F; //Bitmuster Ziffer 0
Delay10KTCYx(10); //Zeitschleife von 100 ms (10Hz)
LATB  =  0x00; //Anzeige AUS
Delay10KTCYx(25); //Zeitschleife von 250 ms (4Hz)
}
}
//-----------------------------------------------------------------------------------------------------------------------------------------------
void TASTA(void) //Funktion, wenn S2 betätigt wird
{
ANZEIGEN_NULL_(); //Bitmuster Ziffer 0 ausgeben
}
//----------------------------------------------------------------------------
void TASTB(void)
{

}
//----------------------------------------------------------------------------
void TASTC(void)
{

}
//----------------------------------------------------------------------------
void TASTD(void)
{

}
//----------------------------------------------------------------------------
void main(void) //Hauptprogramm
{

setup();
t0_ini();
InterruptHandler();
{
unsigned char ZAHLEN_array[11];

ZAHLEN_array[0]    =  0x00; //Anzeige AUS
   ZAHLEN_array[1]    =  0x3F; //Ziffer 0
   ZAHLEN_array[2]    =  0x06; //Ziffer 1
  ZAHLEN_array[3]    =  0x5B; //Ziffer 2
   ZAHLEN_array[4]    =  0x4F; //Ziffer 3
ZAHLEN_array[5]    =  0x66; //Ziffer 4
   ZAHLEN_array[6]    =  0x6D; //Ziffer 5
   ZAHLEN_array[7]    =  0x7D; //Ziffer 6
  ZAHLEN_array[8]    =  0x07; //Ziffer 7
   ZAHLEN_array[9]    =  0x7F; //Ziffer 8
ZAHLEN_array[10]  =  0x6F; //Ziffer 9
}



while(1) //Beginn Endlosschleife

   {TASTEN = (0x0F&(~PORTA)); //Abfrage PortA, welche Taste ist gedrückt

switch(TASTEN) //Beginn Auswahlanweisung

{

case 8:               //wenn S2 betätigt dann:
TASTA(); //Unterprogramm TASTA
  break;

  case 4:             //wenn S3 betätigt dann:
TASTB(); //Unterprogramm TASTB
  break;

  case 2:               //wenn S4 betätigt dann:
TASTC(); //Unterprogramm TASTC
  break;

  case 1:               //wenn S5 betätigt dann:
TASTD(); //Unterprogramm TASTD
  break;
        
  }
} //Ende Endlosschleife
} //Ende Hauptprogramm

//---------------------------------------------------------------------------------

Edit: Bitte COde-Tags verwenden!
Stampede
« Letzte Änderung: Dezember 29, 2011, 11:32:48 von Stampede » Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #1 am: Dezember 29, 2011, 11:43:22 »

Hallo,

Zitat
#define  TRISA     0x1F;         //PortA : RA0 - RA4 = Eingang / RA5 = Ausgang
#define  TRISB     0x00;         //PortB  = Ausgang
#define  TRISC      0x00;         //PortC = Ausgang
Das ist Käse und bewirkt garnichts.

Code:
void setup (void)
{
ADCON0  = 0x00; // Pins als digital I/O
TRISA = 0x1F;
        TRISB = 0x0;
        TRISC = 0x0;                    // HIER MUSS DAS HIN!!!!
PORTA  = 0x00; // Port A,B und C löschen
PORTB  = 0x00;
PORTC  = 0x00;
}

Zitat
Die Interruptroutine und der Array machen mir noch Sorgen,der Array soll später mal dazu dienen,
die Bitmuster der Zahlen auf den 7-Segmentanzeigen auszugeben.
Das Array und die ISR sehen seowit ok aus. Der Aufruf von InterruptHandler(); in der main macht für mich keinen Sinn.

Gruß
Stefan
Gespeichert

Umschüler
Newbie
*
Offline Offline

Beiträge: 20


Profil anzeigen
« Antworten #2 am: Dezember 29, 2011, 19:35:00 »

Hallo Stefan,

vielen Dank für die ersten sehr hilfreichen Tips. Habe die Fehler gleich beseitigt und mache mich
jetzt erst mal an die Anzeige durch die 7-Segmentanzeigen - ich schreibe nebenbei ein kleines Testprogramm,
um erst mal die Hardware der Platine zu testen. Ohne Interrupt usw. und die Anzeigen sollen auf Tastendruck
reagieren. Die erste Kontrolle der Platine erfolgt natürlich ohne PIC.

Könnte ein Element eines Arrays auch so aussehen:" ZAHLEN_array[4]    =  (PORTB=0x4F);      //Ziffer 3

Gruß Mike.
« Letzte Änderung: Dezember 29, 2011, 19:45:08 von Umschüler » Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #3 am: Dezember 29, 2011, 20:34:33 »

Hi Mike,

Zitat
Könnte ein Element eines Arrays auch so aussehen:"
Code:
ZAHLEN_array[4]    =  (PORTB=0x4F);      //Ziffer 3
Eine Zuweisung mit zwei Gleichheitszeichen ist nicht zulässig, das wirst du aber beim Komplilieren selbst merken Smiley
Zitat
Die erste Kontrolle der Platine erfolgt natürlich ohne PIC.
Insofern die Vdd stimmt, ist es schon vergleichsweise schwierig einen PIC zu zerstören.

Gruß
Stefan
Gespeichert

Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.048 Sekunden mit 18 Zugriffen.
 
Top! Top!