Hallo, ich bin leider absoluter Anfänger in Mikrocontroller bzw. C programmieren, deshalb benötige ich jetzt Hilfe. Ich hab mir ein Steuerkästchen gebaut, mit dem man einen Elektromotor per Schalter starten bzw. stoppen und mittels Poti die Drezahl regeln kann. Ich will das Poti über den AD-Wandler einlesen und dann über ein PWM Signal an den Motor ausgeben. 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, kann mir da bitte jemand ein Code Beispiel oder so geben? Ich verwende den PIC 18F67K22. Vielen Dank! while (1) { int i; int warte; i = 0; int summe; summe = 0; for (i; i<=3; i++) { // kurz warten warte = 200; while(warte--); // Wandeln starten ADCON0 |= 0b00000011; warte = 2500; while ((ADCON0bits.GODONE == 1) && (warte-- != 0)); erg = ADRESH; erg <<= 8; erg |= ADRESL; summe = summe + erg; } erg = summe/3; CLRWDT(); }
:
Verschoben durch User
Mit Beispielen für PIC18 kann ich leider direkt nicht dienen. Microchip bietet aber selber Code Examples an: https://www.microchip.com/CodeExamplesByFunc.aspx Sonst gibts noch die MLA: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en547784 Ich bin übrigens bisher immer gut damit durchgekommen, die Datenblätter "apzutippen". Das relevante Kapitel bei deinem PIC wäre 20.3 oder 20.4.
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 | }
|
vloki schrieb: > Die Periode wird mit PRx (Periodenregister des Timers) eingestellt, das > Tastverhältnis im Register CCPRxL. Für den Anfang kannst du ja mal PRx auf 255 und dann CCPRxL = ADRESH oder CCPRxL = 255-ADRESH
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.