Forum: Mikrocontroller und Digitale Elektronik CCP2, Alternate Pins und PIC16F1827


von BeastyK (Gast)


Lesenswert?

Moin Leute,

ich hab mich dem PIC16F1827 zugewendet weil ich einen kleinen µC für ein 
kleines Gerät haben wollte.
Bisher hab ich alles nur simuliert, gerade weil ich mit dem CCP-Modul 
noch nicht so gearbeitet hab.
Genau dort liegt auch mein Problem, ich hab mit APFCON0 den Pin von RB6 
auf RA7 umgelegt, teste ich den Code in Proteus hab ich das PWM-Signal 
auf RB6...eigentlich wollte ich an RA6 und RA7 einen Piezo hängen. Ich 
hab später nur eine CR3210 (zumindest nur eine Kopfzelle) und ich möchte 
den Piezo irgendwie richtig laut bekommen. Den WDT hab ich erstmal 
aussen vor gelassen.
Über jede Anregung freu ich mich auf jedenfall...den Code poste ich hier 
einfach rein, denke mal bei der größe des Codes geht das noch.
1
// PIC16F1827 Configuration Bit Settings
2
3
// 'C' source line config statements
4
5
// CONFIG1
6
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
7
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
8
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
9
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
10
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
11
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
12
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
13
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
14
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
15
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
16
17
// CONFIG2
18
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
19
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
20
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
21
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
22
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
23
24
// #pragma config statements should precede project file includes.
25
// Use project enums instead of #define for ON and OFF.
26
27
#define _XTAL_FREQ 8000000
28
29
void setup(void);
30
void PWMSound(void);
31
void PWMSound2(void);
32
33
#include <xc.h>
34
#include <adc.h>
35
#include <stdlib.h>
36
#include <plib.h>
37
38
void setup(void){
39
40
//    WDTCONbits.WDTPS = 0b10000;
41
// Alternate Pin Function Control Register: CCP2/P2A & P1C from RB6 -> RA7 
42
    APFCON0 = 0b00001010;
43
//----- I/O Port-----------------------------------------------------------
44
    ANSELA = 0b00000000;//All Digital I/O without RA0 and RA1
45
    ANSELB = 0b00000000;//All Digital I/O
46
    TRISA  = 0b00100011;//All Output without RA0 and RA1 (RA5 is Input Only)
47
    TRISB  = 0b00000110;//All Output without RB1 and RB2
48
    PORTA = 0b00000000;
49
    PORTB = 0b00000000;
50
//----- Oscillator Control Register----------------------------------------
51
    OSCCON = 0b01110000;
52
//----- CCP2 Control Register----------------------------------------------
53
    CCP2CON = 0b11001100;
54
//----- CCPTMRS: PWM TIMER SELECTION CONTROL REGISTER----------------------
55
    CCPTMRSbits.C2TSEL = 0b00;
56
//----- Timer2 Timer Control Register--------------------------------------
57
    T2CON = 0b00000010;
58
//----- Interrupt Control Register-----------------------------------------
59
    PIE1bits.TMR2IE = 1;
60
    INTCONbits.PEIE = 1;
61
    INTCONbits.GIE = 1;
62
    TMR2 = 0;
63
    PR2 = 255;
64
}
65
66
 void PWMSound(void){
67
       PR2 = 200;
68
       T2CONbits.TMR2ON = 0;
69
    __delay_ms(250);
70
    T2CONbits.TMR2ON = 1;
71
    __delay_ms(50);
72
    T2CONbits.TMR2ON = 0;
73
    __delay_ms(50);
74
    T2CONbits.TMR2ON = 1;
75
    __delay_ms(50);
76
 }
77
 
78
 void PWMSound2(void){
79
      PR2 = 150;
80
      T2CONbits.TMR2ON = 0;
81
    __delay_ms(250);
82
    T2CONbits.TMR2ON = 1;
83
    __delay_ms(50);
84
    T2CONbits.TMR2ON = 0;
85
    __delay_ms(50);
86
    T2CONbits.TMR2ON = 1;
87
    __delay_ms(50);
88
 }
89
 
90
void interrupt intr (void){
91
    PIR1bits.TMR2IF = 0;
92
} 
93
 
94
void main() {
95
    //CLRWDT();
96
    setup();
97
    __delay_ms(100);
98
    LATBbits.LATB0 = 1;
99
    // CLRWDT();
100
    while(1){
101
        if(PORTBbits.RB2 == 1){
102
         PWMSound();
103
          LATBbits.LATB4 = 1;
104
          __delay_ms(500);
105
          LATBbits.LATB4 = 0;
106
          __delay_ms(250);
107
          LATBbits.LATB2 = 0;
108
        }
109
        if (PORTBbits.RB1 == 1){
110
         //PWMSound2();
111
          LATBbits.LATB5 = 1;
112
          __delay_ms(500);
113
          LATBbits.LATB5 = 0;
114
          __delay_ms(250);
115
          LATBbits.LATB1 = 0;
116
        }
117
   // CLRWDT();    
118
        
119
}
120
           }

MfG
BeastyK

von BeastyK (Gast)


Lesenswert?

Ok, ich war etwas unpräzise!
Die Batterie ist eine CR2032, Proteus V8.4, die Frage ist ob ich einen 
Fehler im Code hab, weil ich nur eine Ausgabe der PWM über RB6 sehe.
Ich war der Ansicht das ich enhanced PWM auf Half Bridge gestellt hab 
und über P2A und P2B ausgebe, wobei ich ja oben APFCON0 mit P2A und P2B 
auf RA6 und RA7 hab, der Analogteil ist auch auf digital. Warum nur 
blinkt dann RB6 wie ein Weihnachtsbaum koppkratz.

MfG
BeastyK

von Profiprog (Gast)


Lesenswert?

Hallo,
versuch doch mal
    APFCON0 = 0b00001000;
persönlich traue ich den Simulatoren nicht so recht....
Gruss

von BeastyK (Gast)


Lesenswert?

Moin,

danke für die Idee mit

Profiprog schrieb:
> APFCON0 = 0b00001000;

das hat mich leider nicht weiter gebracht, hab den Teil in dem Setup 
auch hinter die I/O-Port Initialisierung gesetzt, der Erfolg blieb 
allerdings aus.

Man darf sich nicht selbst trauen und

BeastyK schrieb:
> //----- CCP2 Control
> Register----------------------------------------------
>     CCP2CON = 0b11001100;

macht mir keine Half-Bridge, wie ich wollte, sondern ne Full Bridge, 
also schnell korrigieren:
1
//----- CCP2 Control Register ----------------------------------------------
2
    CCP2CON = 0b10001101; // 10 = Half-Bridge output, XX - DCxB????,
3
                          //1101 = PWM mode: PxA, PxC active-high; PxB, PxD active-low

Mit DCxB was die beiden letzten Bits des 10bit PWM Signals sein soll 
konnte ich nicht wirklich etwas anfangen und hab beide auf 0 gesetzt.

Also: RA7 (P2A) blinkt nun freudig vor sich hin, was darauf schließen 
läßt das das Mapping von RB6 auf RA7 funktioniert hat und die 
Half-Bridge auch eine solche ist.
RA6 (P2B) tut es aber nicht und RB7 blinkt obwohl es nicht mehr sollte.
Ich hab auch festgestellt das RB3 an geht und ich ihn extra mit 
TRISBbits.TRISB3 = 1 wieder ruhigstellen muß.

Ich schick nochmal den setup Teil rüber:
1
void setup(void){
2
3
//    WDTCONbits.WDTPS = 0b10000;
4
//----- I/O Port -----------------------------------------------------------
5
    ANSELA = 0b00000000;//All Digital I/O without RA0 and RA1
6
    ANSELB = 0b00000000;//All Digital I/O
7
    TRISA  = 0b00100011;//All Output without RA0 and RA1 (RA5 is Input Only)
8
    TRISB  = 0b00000110;//All Output without RB1 and RB2
9
    PORTA = 0b00000000;
10
    PORTB = 0b00000000;
11
//----- Oscillator Control Register ----------------------------------------
12
    TRISBbits.TRISB6 = 1;
13
    TRISAbits.TRISA6 = 1;
14
    TRISAbits.TRISA7 = 1;
15
//----- Alternate Pin Function Control Register: CCP2/P2A & P1C from RB6 -> RA7 --
16
    APFCON0 = 0b00001010;
17
//-------------------------------------------------------------------------------    
18
    OSCCON = 0b01110000; // 4xPLL in config, 1110=8 MHz mit PLL -> 32MHz
19
                         // The SCS bits must be set to ‘00’ to use the 4xPLL 
20
                         // with the internal oscillator.
21
//----- CCP2 Control Register ----------------------------------------------
22
    CCP2CON = 0b10001101; // 10 = Half-Bridge output, XX - DCxB????,
23
                          //1101 = PWM mode: PxA, PxC active-high; PxB, PxD active-low
24
//----- CCPTMRS: PWM TIMER SELECTION CONTROL REGISTER ----------------------
25
    CCPTMRSbits.C2TSEL = 0b00; // 00 = CCP2 is based off Timer 2 in PWM Mode
26
    TRISBbits.TRISB6 = 0;
27
    TRISAbits.TRISA6 = 0;
28
    TRISAbits.TRISA7 = 0;
29
    TRISBbits.TRISB3 = 1;
30
//----- Timer2 Timer Control Register --------------------------------------
31
    T2CON = 0b00000010; // 0000 = 1:1 Postscaler, TImerOn = 0, 10 = Prescaler is 16
32
//----- Interrupt Control Register -----------------------------------------
33
    PIE1bits.TMR2IE = 1;
34
    INTCONbits.PEIE = 1;
35
    INTCONbits.GIE = 1;
36
    TMR2 = 0;
37
    PR2 = 255;
38
}

Für mich steht noch die Frage warum RB7 (P2B) als PWM noch läuft und 
wieso RB3 einfach an ist, hat doch kein LAT von mir bekommen?

MfG
BeastyK

von BeastyK (Gast)


Lesenswert?

Moin,

ich war hier etwas auf dem Holzweg, ich hab ja den Timer2 benutzt und 
P1C brauch ich ja garnicht mit umpinnen.

BeastyK schrieb:
> //----- Alternate Pin Function Control Register: CCP2/P2A & P1C from RB6
> -> RA7 --
>     APFCON0 = 0b00001010;

im Grunde wunderte ich mich über RB7 (P2B) und warum der noch läuft, 
wenn man aber das richtige Bit an der richtigen Stelle setzt 
funktioniert das auch:

bit 4 P2BSEL: Pin Selection bit
0 = P2B function is on RB7
1 = P2B function is on RA6
bit 3 CCP2SEL: Pin Selection bit
0 = CCP2/P2A function is on RB6
1 = CCP2/P2A function is on RA7

also APFCON0 = 0b00011000

Nun wollte ich ja mit der Half-Bridge das P2A auf High ist während P2B 
auf low liegt, das CCP2 Control Register hab ich deshalb wie folgt 
initialisiert:

BeastyK schrieb:
> //----- CCP2 Control Register
> ----------------------------------------------
>     CCP2CON = 0b10001101; // 10 = Half-Bridge output, XX - DCxB????,
>                           //1101 = PWM mode: PxA, PxC active-high; PxB,
> PxD active-low

Leider ist das ausgegebene Rechtecksignal so dass P2A auf High ist und 
P2B auch, also nicht so wie ich dachte das es ist. Hab ich das 
Datenblatt da falsch verstanden?

Ich hab hier einen Piezo mit 4,4KHz Resonanzfrequenz, von Reichelt, weiß 
jemand ob der mit 3,3V noch einen pieps von sich gibt?

MfG
BeastyK

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
Noch kein Account? Hier anmelden.