1 | #include "p18cxxx.h"
|
2 | #include "xc.h"
|
3 | #include "config.h"
|
4 |
|
5 | #define BTN_IGNORE_FACTOR 10
|
6 | #define _XTAL_FREQ 1000000
|
7 |
|
8 | volatile unsigned char ad_msb = 0, ad_lsb = 0;
|
9 |
|
10 | void delay(int time);
|
11 | void SetupOscillator(void);
|
12 | void SetupPWM(void);
|
13 | void SetupADC(void);
|
14 | void interrupt low_priority Low_Priority_ISR(void);
|
15 |
|
16 | void main(void) {
|
17 |
|
18 | unsigned char button = 0, ignorebutton = 0;
|
19 |
|
20 | ANSEL = 0x00; //Eingänge Digital
|
21 | ANSELH = 0x00;
|
22 | INTCONbits.GIEH = 1; //Alle High-Priority Interrupts enabled
|
23 | INTCONbits.GIEL = 1; //Alle Low-Priority Interrupts enabled
|
24 | RCONbits.IPEN = 1; //Enable Priority levels on Interrupts
|
25 |
|
26 | SetupOscillator(); //Frequenz 1MHz
|
27 | SetupADC(); //Analogsignal RA0 einlesen, Digital RB0 einlesen(Taster)
|
28 | SetupPWM();
|
29 | while (1) {
|
30 | ADCON0bits.GO_DONE = 1; //A/D-Wandlung starten
|
31 | while(ADCON0bits.GO_DONE != 0); //auf A/D-Wandlung warten
|
32 | ad_msb = ADRESH; //A/D-Ergebnis Bit 2 bis 10
|
33 | ad_lsb = ADRESL; //A/D-Ergebnis Bit 0 und 1
|
34 | if (PORTBbits.RB0 == 0 && ignorebutton == 0) { //Taster gedrückt? (=0, 1= not pressed)
|
35 | button = button ^ 1; //Modus toggeln -> PWM/Laufschrift
|
36 | ignorebutton = BTN_IGNORE_FACTOR; //Taster für bestimmte Zeit ignorieren
|
37 | }
|
38 | if (ignorebutton > 0) ignorebutton--; //Ignorierzeit verringern
|
39 | if (button == 0) { //Modus checken
|
40 | PIE1bits.ADIE = 0; //ADC-Interrupt disabled
|
41 | CCPR2L = ad_msb;
|
42 | CCPR1L = ad_msb;
|
43 | CCP2CONbits.DC2B = ad_lsb; //Steigerung Duty Cycle auf 0,1%
|
44 | CCP1CONbits.DC1B = ad_lsb;
|
45 | //PIE1bits.ADIE = 1; //ADC-Inerrupt enabled
|
46 | LATD = ad_msb;
|
47 | } else{
|
48 | CCPR1L = CCPR1L - 1; //PWM Duty Cycle an CCP1/RC2 verringern -> abklingen
|
49 | delay(25); //25ms warten
|
50 | if(CCPR1L == 0){
|
51 | button = 0;
|
52 | }
|
53 |
|
54 | }
|
55 |
|
56 | }
|
57 | }
|
58 |
|
59 | void delay(int time) {
|
60 | int counter = 0;
|
61 | for (counter = 0; counter<time; counter++)
|
62 | __delay_ms(1);
|
63 | }
|
64 |
|
65 | void SetupOscillator(){
|
66 | OSCCONbits.SCS = 0x3; //Interner Oscillator
|
67 | OSCCONbits.OSTS = 0; //Interner Oscillator
|
68 | OSCCONbits.IRCF0 = 1;
|
69 | OSCCONbits.IRCF1 = 1;
|
70 | OSCCONbits.IRCF2 = 0; //Oscillatorfrequenz 1MHz
|
71 | OSCCONbits.IDLEN = 0; //Sleep-Mode bei sleep
|
72 | }
|
73 |
|
74 | void SetupPWM(){
|
75 | TRISCbits.RC1 = 1; //Port RC1/CCP2 PWM als Ausgang sperren
|
76 | TRISCbits.RC2 = 1; //Port RC2/CCP1 PWM als Ausgang sperren
|
77 | T2CONbits.T2CKPS = 0x00; //Timer 2 Eingang: Fosc 1MHz/4 = 250kHz
|
78 | PR2 = 249; //PWM-Periode: PR+1 * 1/250kHz = 1ms, f=1kHz
|
79 | CCP2CONbits.CCP2M = 0x0F; //CCP2 auf PWM
|
80 | CCP1CONbits.CCP1M = 0x0C; //CCP1 auf PWM
|
81 | CCP1CONbits.P1M = 0x00; //CCP1 Single Mode
|
82 | PSTRCONbits.STRA = 1; //P1A als Ausgang für CCP1
|
83 | TRISCbits.RC1 = 0; //Port RC1/CCP2 PWM als Ausgang
|
84 | TRISCbits.RC2 = 0; //Port RC2/CCP1 PWM als Ausgang
|
85 | T2CONbits.TMR2ON = 1; //Timer 2 an
|
86 | }
|
87 |
|
88 | void SetupADC(){
|
89 | TRISAbits.RA0 = 1; //Port RA0 Poti auf Eingang setzen
|
90 | TRISBbits.RB0 = 1; //Port RB0 Taster auf Eingang setzen
|
91 |
|
92 | ANSELbits.ANS0 = 1; //RA0 auf Analogeingang setzen (=1, 0 = digital)
|
93 | ADCON0bits.ADON = 1; //A/D-Wandler aktivieren
|
94 | ADCON0bits.CHS = 0x00; //AN0/RA0 als A/D-Converter Eingang
|
95 | ADCON1bits.VCFG1 = 0; //Negative Voltage Reference (=Vss , 0 = AN2,RA2)
|
96 | ADCON1bits.VCFG0 = 0; //Positive Voltage Reference (=Vdd , 0 = AN3,RA3)
|
97 | ADCON2bits.ADFM = 0; //A/D-Wandler Conversion Result Format: Links beginnend
|
98 |
|
99 | //PIE1bits.ADIE = 1; //ADC-Interrupt enabled
|
100 | IPR1bits.ADIP = 0; //ADC-Interrupt Low-Priority
|
101 | PIR1bits.ADIF = 0; //Interruptflag zurücksetzen
|
102 | ADCON0bits.GO_DONE = 1; //A/D-Wandler starten
|
103 | }
|
104 | void low_priority interrupt Low_Priority_ISR(){
|
105 | if(PIR1bits.ADIF == 1 && ADCON0bits.GO_DONE == 0){
|
106 | ad_msb = ADRESH;
|
107 | ad_lsb = ADRESL;
|
108 | PIR1bits.ADIF = 0;
|
109 | ADCON0bits.GO_DONE = 1;
|
110 | }
|
111 | return;
|
112 | }
|