Gschwande schrieb:
> Für den AD-Wandler hab ich mir schon bissl was gebastelt (siehe weiter
> unten), aber wie das mit dem PWM hinhaut hab ich leider gar keine
> Ahnung,
Im Prinzip steht, wie WehOhWeh schon erwähnt hat, natürlich alles im
Datenblatt. Bei den PICs mit mehreren gleichen Modulen kann es aber
trotzdem etwas verwirrend sein.
Also wenn du ein PWM Modul verwenden möchtest, dann hat der 67K22 wohl 7
davon (Nr. 4..10). Da suchst du dir das aus, welches den passendsten
Ausgangs-PIN hat. (Der am günstigsten liegt oder was auch immer)
Ich häng mal unten ein Beispiel an wo das das Modul mit der Nummer "1"
war, die es bei dir aber nicht gibt.
Bevor du weitermachst schaust du dir die Abbildung "FIGURE 19-3
SIMPLIFIED PWM BLOCK DIAGRAM" im Datenblatt an. (ist beispielhaft mit
CCP4 und Timer2)
Das Modul stellst man über das zugehörige CCPxCON Register auf den
richtigen Modus (PWM mit einem Ausgang) ein.
Die Verknüpfung mit dem gewünschten Timer wird im Register CCPTMRSx
vorgenommen.
Bei dir wird vermutlich die Periode immer die gleiche sein und das
Tastverhältnis soll sich ändern. Im Beispiel unten ist es umgekehrt da
wird die Periode geändert und das Tastverhältnis ist immer ~50%.
Die Periode wird mit PRx (Periodenregister des Timers) eingestellt, das
Tastverhältnis im Register CCPRxL.
Die Auflösung der PWM "kann" 10bit betragen. Wenn für deine Anwendung
8bit ausreichen, dann war es das eigentlich schon. Sobald der Timer
läuft, läuft auch die PWM.
Ach ja, der PWM-Output muss natürlich noch als solcher konfiguriert
werden.
PS: bei 8bit -> ADC linksbündig und nur ADRESH verwenden. Was sind das
eigentlich für Wartezeiten bei der AD Wandlung?
1 | void Sound_PWM(void){ //PWM ###TODO -> Lautstaerke !
|
2 | unsigned short frequency = 300;
|
3 | //--------------------------------------------------- __init()
|
4 | OSCCONbits.IRCF = IRCF_4MHZ;
|
5 | LCD_Init();
|
6 | LCD_ConstTextOut(0,0,"uC-Quick");
|
7 | LCD_ConstTextOut(1,0," Sound ");
|
8 | ENC_INT_TRI = INPUT_PIN; // encoder setup
|
9 | ENC_DIR_TRI = INPUT_PIN;
|
10 | mENC_IR_CLR();
|
11 | mENC_IR_EN();
|
12 |
|
13 | //#####################################################################
|
14 | CCP1CONbits.CCP1M = 0b1100; // PWM mode
|
15 |
|
16 | CCP1CONbits.P1M = 0; // single
|
17 |
|
18 | CCPTMRS0bits.C1TSEL = 0; // CCP1-TMR2
|
19 |
|
20 | PR2 = 62500 / frequency; // 1MHz:16
|
21 |
|
22 | CCPR1L = PR2 >> 1;
|
23 |
|
24 | SPEAKER_TRI = OUTPUT_PIN; // PWM output
|
25 |
|
26 | OpenTimer2(TIMER_INT_OFF & T2_PS_1_16 & T2_POST_1_1);
|
27 | // OpenTimer2(TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1);
|
28 | //#####################################################################
|
29 |
|
30 | flags.all = 0;
|
31 | INTCONbits.GIE = 1;
|
32 | //----------------------------------------------- main()
|
33 | while(1){
|
34 | if(flags.encUp){
|
35 | if(frequency < 800) {frequency = frequency + 10;}
|
36 | else {frequency = frequency + 100;}
|
37 | if(frequency > 15600){frequency = 15600;}
|
38 | PR2 = (62500 / frequency) -1; // 1MHz : 16
|
39 | CCPR1L = PR2 >> 1;
|
40 | LCD_ConstTextOut(1,0," "); // delete old value
|
41 | LCD_ValueOut(1,1,frequency);
|
42 | flags.encUp = 0;
|
43 | }
|
44 | if(flags.encDown){
|
45 | if(frequency < 800) {frequency = frequency - 10;}
|
46 | else {frequency = frequency - 100;}
|
47 | if(frequency < 250) {frequency = 250;}
|
48 | PR2 = (62500 / frequency)-1; // 1MHz : 16
|
49 | CCPR1L = PR2 >> 1;
|
50 | LCD_ConstTextOut(1,0," "); // delete old value
|
51 | LCD_ValueOut(1,1,frequency);
|
52 | flags.encDown = 0;
|
53 | }
|
54 | }
|
55 | }
|
56 |
|
57 | void interrupt high_isr(void)
|
58 | {
|
59 | if (ENC_IR){ // encoder interrupt
|
60 | if(ENC_DIR == ENC_DIR_UP)
|
61 | flags.encUp = 1;
|
62 | else
|
63 | flags.encDown = 1;
|
64 | mENC_IR_CLR();
|
65 | return;
|
66 | }
|
67 | ...
|
68 | }
|