Hallo verehrte Gemeinde! Seit einigen Tagen beschäftige ich mich mit dem Thema PIC-Programmierung, da ich kleinere Anwendungen hierüber sehr gut für Testumgebungen in unserer Entwicklungsumgebung einsetzen kann. Ich habe hier auf der Seite und im Forum schon etliche hilfreiche Tipps gefunden. Jetzt habe ich mich trotz hunderter Tutorials und anderer Anleitungen mit meinen Miniversuchen festgefahren und hoffe auf Eure Expertenhilfe. Wie im Betreff bereits angedeutet arbeite ich mit einem PIC18F13K22 und habe das Gefühl das 400-seitige Datenblatt häufiger gelesen zu haben als so mancher Priester die Bibel. Ich habe mir eine Testplatine gebastelt und konnte auch schon diverse kleine Versuchsprojekte umsetzen. Ich habe eine LED am Pin RA0 und setze über die Standardschnittstelle ein PICKit3 zur Programmierung und zum Debuggen über MPLAB v8.90 ein. Ich bekomme die LED zum Leuchten, einen ADC Input von einem Poti ausgewertet und schaffe es auch über die delay-Funktion einen Ausgang blinken zu lassen. Hardwaremäßig scheint soweit also alles mal zu passen. Wenn ich jetzt allerdings versuche den Timer0 einzusetzen bekomme ich das Ganze nicht mehr zum Laufen. Bitte helft mir den Fehler zu finden. Zunächst bin ich mir nicht sicher ob meine Configurationbits alle korrekt sind, daher hier mein config.h - file: //Konfigurationsbits für PIC18F13K22 __CONFIG(1, OSC_INT_RC & PLLEN_OSCILLATOR_USED_DIRECTLY & PCLKEN_PRIMARY_CLOCK_ENABLED & FCMEN_DISABLED & IESO_ENABLED); __CONFIG(2, nPWRTEN_ENABLED & BOREN_ENABLED_IN_HARDWARE__SBOREN_DISABLED & BORV_1_9V & WDTEN_DISABLED_CONTROLLED_BY_SWDTEN_BIT & WDTPS_1_32768); __CONFIG(3, HFOFST_THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE & MCLRE_MCLR_ENABLED_RA3_DISABLED); __CONFIG(4, STVREN_ENABLED & LVP_DISABLED & BBSIZ_1_KW_BOOT_BLOCK_SIZE & XINST_DISABLED & BACKBUG_ENABLED); __CONFIG(5, CPB_DISABLED & CPD_DISABLED & CP_1_DISABLED & CP_0_DISABLED); __CONFIG(6, WRT_0_DISABLED & WRT_1_DISABLED & WRTC_DISABLED & WRTB_DISABLED & WRTD_DISABLED); __CONFIG(7, EBTR_0_DISABLED & EBTR_1_DISABLED & EBTRB_DISABLED); Des weiteren ist hier mein C-Code: /** I N C L U D E S *******************************************/ #include <htc.h> #include <pic18f13k22.h> #include "config.h" /** C O N F I G U R A T I O N *********************************/ //Die Configurationsbits wurden mit der config.h eingebunden //Die Definitionen der Bits finden sich in der pic18f13k22.h /** D E F I N E S *********************************************/ #define LED1 LATAbits.LATA0 //LED liegt an Port A RA0 #define Taster1 LATCbits.LATC0 //Taster liegt an Port C RC0 /** G L O B A L E ** V A R I A B L E N ************************/ int zeit=0; int wartezeit=10; char status=0; /** P R O T O T Y P E S ***************************************/ void interrupt ISRTimer(void); void initTimer0(void); void restartTimer0(void); void stopTimer0(void); void wait(int sec); void delay( int ms ); /** I N T E R R U P T S ***************************************/ void interrupt ISRTimer(void) { INTCONbits.TMR0IF = 0; //Interruptflag des Timers zurücksetzen zeit++; //Zeit inkrementieren bis Wartezeit if(zeit >= wartezeit){ //erreicht ist zeit = 0; stopTimer0(); INTCONbits.INT0IF = 0; //Interruptflag zurücksetzen INTCONbits.INT0IE = 1; //Tasterinterrupt freischalten if(LED1==0){ LED1=1; }else{ LED1=0; } }else{ restartTimer0(); } return; } /** H A U P T P R O G R A M M *********************************/ void main(void) { OSCCON=0x76; // Takt auf 16MHz setzen //Port A LATA = 0x00; TRISA = 0x00; // Alle Pins von Port A sind Ausgänge //Port B LATB = 0x00; TRISB = 0x10; // RB4 ist ein Eingang, alle anderen Pins von Port B sind Ausgänge //Port C LATC = 0x00; TRISC = 0x01; // Alle Pins von Port C sind Ausgänge nur C0 ist ein Eingang ANSEL = 0x00; // RA0-RA4 und RC0-RC3 sind digitale I/Os ANSELH = 0x04; // RB4 ist ein analoger Eingang RB5, RC6 und RC7 sind digitale I/Os INTCONbits.PEIE = 1; // Peripheral Interrupts aktivieren INTCONbits.INT0IF = 0; // Interruptflag zurücksetzen INTCONbits.INT0IE = 1; // externen Interrupt aktivieren INTCONbits.GIE = 1; // Globale Interrupts aktivieren initTimer0(); restartTimer0(); while(1) { //Hauptschleife //tue nichts } } /** F U N K T I O N E N *********************************/ // Timer 0 wird initialisiert void initTimer0(void){ T0CON = 0b00000111; // 16-Bit-Timer, Prescaler = 256 TMR0H = 0x00; // Highbyte ist 0 --> die ersten beiden Stellen 0xHHLL (HH) TMR0L = 0x00; // Lowbyte ist 0 --> die letzten beiden Stellen 0xHHLL (LL) INTCONbits.TMR0IF = 0; // Interruptflag zurücksetzen INTCONbits.TMR0IE = 1; // Timerinterrupt aktivieren return; } // Timer 0 wird zurückgesetzt void restartTimer0(void){ int TimerValue=0; T0CON = 0b00000111; // 16-Bit-Timer, Prescaler = 256, Timer0 deaktiviert TMR0H = 0xC2; // Timer-Wert für 1 sec: 65535-15625=49910 = 0xC2F6 TMR0L = 0XF6; // Highbyte und Lowbyte s. "initTimer0" INTCONbits.TMR0IE = 1; // Timer0-Interrupt aktivieren INTCONbits.TMR0IF = 0; // Interruptflag zurücksetzen T0CONbits.TMR0ON = 1; // Timer0 aktivieren return; } // Timer anhalten void stopTimer0(void){ T0CON = 0b00000111; TMR0H = 0x00; TMR0L = 0x00; INTCONbits.TMR0IF = 0; // Interruptflag zurücksetzen INTCONbits.TMR0IE = 0; // Timer0-Interrupt deaktivieren return; } // Pausensequenz -> nur für Testzwecke void delay( int ms ) { int i=0; //1 ms = 4000 Befehlstakte (16 MHz Quarz / 4) for( i=0; i<ms; i++ ) { _delay(4000); } } Ich würde mich sehr freuen, wenn mir jemand helfen könnte. Viele Grüße aus dem Schwarzwald
Irgendwie ist alles doppelt und dreifach bei dir gemacht worden mit dem Timer0. Hier eine Routine für 10MHz Quartz. Alle 50ms wird ein Interrupt ausgelöst. //Timer0 //Prescaler 1:2; TMR0 Preload = 3034; Actual Interrupt Time : 50 ms //Place/Copy this part in declaration section void InitTimer0(){ T0CON = 0x80; TMR0H = 0x0B; TMR0L = 0xDA; GIE_bit = 1; TMR0IE_bit = 1; } void Interrupt(){ if (TMR0IF_bit){ TMR0IF_bit = 0; TMR0H = 0x0B; TMR0L = 0xDA; //Enter your code here } }
Hallo Stefan, vielen Dank für die schnelle Antwort! Das schien mir auch etwas viel doppelt gemoppelt, aber ich hatte einiges davon aus Beispielen bzw. aus dem FRANZIS-Werk "PIC-Mikrocontroller" Ich habe jetzt das mal soweit es mir sinnvoll schien verschlankt, es funktioniert!!! Der Vollständigkeit halber hier der Code der funktioniert:
1 | /** I N C L U D E S *******************************************/
|
2 | |
3 | #include <htc.h> |
4 | #include <pic18f13k22.h> |
5 | #include "config.h" |
6 | |
7 | /** C O N F I G U R A T I O N *********************************/
|
8 | |
9 | //Die Configurationsbits wurden mit der config.h eingebunden
|
10 | //Die Definitionen der Bits finden sich in der pic18f13k22.h
|
11 | |
12 | /** D E F I N E S *********************************************/
|
13 | |
14 | #define LED1 LATAbits.LATA0 //LED liegt an Port A RA0
|
15 | #define Taster1 LATCbits.LATC0 //Taster liegt an Port C RC0
|
16 | |
17 | /** G L O B A L E ** V A R I A B L E N ************************/
|
18 | |
19 | int zeit=0; |
20 | int wartezeit=10; |
21 | |
22 | /** P R O T O T Y P E S ***************************************/
|
23 | |
24 | void interrupt ISRTimer(void); |
25 | void initTimer0(void); |
26 | void restartTimer0(void); |
27 | void delay( int ms ); |
28 | |
29 | /** I N T E R R U P T S ***************************************/
|
30 | void interrupt ISRTimer(void) { |
31 | |
32 | INTCONbits.TMR0IF = 0; //Interruptflag des Timers zurücksetzen |
33 | |
34 | zeit++; //Zeit inkrementieren bis Wartezeit |
35 | if(zeit >= wartezeit){ //erreicht ist |
36 | zeit = 0; |
37 | INT0IF = 0; //Interruptflag zurücksetzen |
38 | if(LED1==0){ |
39 | LED1=1; |
40 | }else{ |
41 | LED1=0; |
42 | }
|
43 | restartTimer0(); |
44 | }else{ |
45 | restartTimer0(); |
46 | }
|
47 | return; |
48 | |
49 | }
|
50 | |
51 | /** H A U P T P R O G R A M M *********************************/
|
52 | |
53 | void main(void) |
54 | {
|
55 | |
56 | OSCCON=0x76; // Takt auf 16MHz setzen |
57 | |
58 | |
59 | //Port A
|
60 | LATA = 0x00; |
61 | TRISA = 0x00; // Alle Pins von Port A sind Ausgänge |
62 | |
63 | //Port B
|
64 | LATB = 0x00; |
65 | TRISB = 0x10; // RB4 ist ein Eingang, alle anderen Pins von Port B sind Ausgänge |
66 | |
67 | //Port C
|
68 | LATC = 0x00; |
69 | TRISC = 0x01; // Alle Pins von Port C sind Ausgänge nur C0 ist ein Eingang |
70 | |
71 | ANSEL = 0x00; // RA0-RA4 und RC0-RC3 sind digitale I/Os |
72 | ANSELH = 0x04; // RB4 ist ein analoger Eingang RB5, RC6 und RC7 sind digitale I/Os |
73 | |
74 | |
75 | GIE = 1; // Globale Interrupts aktivieren |
76 | initTimer0(); |
77 | restartTimer0(); |
78 | |
79 | |
80 | while(1) { //Hauptschleife |
81 | //tue nichts
|
82 | }
|
83 | |
84 | }
|
85 | |
86 | /** F U N K T I O N E N *********************************/
|
87 | |
88 | // Timer 0 wird initialisiert
|
89 | void initTimer0(void){ |
90 | T0CON = 0b00000111; // 16-Bit-Timer, Prescaler = 256 |
91 | TMR0H = 0xC2; // Highbyte ist 0 --> die ersten beiden Stellen 0xHHLL (HH) |
92 | TMR0L = 0xF6; // Lowbyte ist 0 --> die letzten beiden Stellen 0xHHLL (LL) |
93 | // Timer-Wert für 1 sec: 65535-15625=49910 = 0xC2F6
|
94 | TMR0IF = 0; // Interruptflag zurücksetzen |
95 | TMR0IE = 1; // Timerinterrupt aktivieren |
96 | return; |
97 | }
|
98 | |
99 | // Timer 0 wird zurückgesetzt
|
100 | void restartTimer0(void){ |
101 | int TimerValue=0; |
102 | T0CON = 0b00000111; // 16-Bit-Timer, Prescaler = 256, Timer0 deaktiviert |
103 | TMR0IF = 0; // Interruptflag zurücksetzen |
104 | TMR0ON = 1; // Timer0 aktivieren |
105 | return; |
106 | }
|
Danke, danke, danke! Ich hoffe ich kann hier auch irgendwann mal jemandem sinnvolle Tipps geben. Viele Grüße
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.