Guten Tag zusammen,
ich habe das Problem, dass ins PR2-Register und ins CCPR1L-Register
keine Werte reingeschrieben werden können (mit Simulator von MPLAB
kontrolliert). Der Controller übernimmt die Default-Werte und gibt das
PWM-Signal an GPIO2 auf 100%aus, was natürlich nicht erwünscht ist.
Hier ist der Code: 1 list p=12F683
2 #include "P12F683.INC"
3
4 ; config word
5 __CONFIG _CP_OFF & _WDT_OFF & _BOD_ON & _PWRTE_ON & _INTRC_OSC_CLKOUT & _MCLRE_ON & _CPD_OFF
6
7 ERRORLEVEL -302
8
9 org 0x000 ; Startadresse des PICs
10 goto INIT
11
12 ;**************************************************************************
13 ; configure interrupts
14 ;**************************************************************************
15 org 0x004
16 CLRF PIR1
17
18 retfie
19
20 ;**************************************************************************
21 ; PIC configuration
22 ;**************************************************************************
23
24 INIT
25 ; reset selects 4 MHz default
26 BSF STATUS,RP0 ; Bank1
27 BSF OSCCON, SCS ; intosc is used
28 CLRF OPTION_REG
29 BSF OPTION_REG,INTEDG ; interrupt on rising edge
30 BCF STATUS,RP0 ; Bank0
31
32 ; PWM vorbereiten
33 ; 4MHz-Takt -> 1 MHz-Zyklustakt
34 ; Vorteiler 1:1 und Timer2 einschalten
35 CLRF T2CON ; Vorteiler 1:1
36 BSF T2CON,TMR2ON ; Timer2 ein: B'00000010'
37
38 ; GP2/CCP1 auf Ausgang stellen
39 BSF STATUS,RP0 ; Bank1
40 CLRF TRISIO ; alles Ausgänge
41 BCF STATUS,RP0 ; Bank 0
42
43 ; PWM MODE mit CCP1 initialisieren
44 CLRF CCP1CON ; CCP1-Modus aus
45 BSF CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode, active high
46 BSF CCP1CON,CCP1M2 ;
47
48 BSF INTCON,GIE ; enable global interrupt
49
50 BSF STATUS,RP0
51 BSF PIE1,CCP1IE
52 BSF PIE1,TMR2IE
53 BCF STATUS,RP0
54
55
56 ; Frequenz auf 32 kHz einstellen
57 ; BCF STATUS,RP0 ; Bank0
58 MOVLW d'124' ; 2.5 kHz new
59 MOVWF PR2
60
61 movlw d'62' ; new
62 movfw CCPR1L
63
64
65 ; IO-Pins vorbereiten
66 CLRF GPIO ; Init GPIO
67 MOVLW 0x07 ; Set GP<2:0> to
68 MOVWF CMCON0 ; digital I/O
69 BSF STATUS,RP0 ; Bank1
70 CLRF ANSEL ; digital I/O
71 BCF STATUS,RP0 ; Bank 0
72
73
74 ;**************************************************************************
75 ; main programme
76 ;**************************************************************************
77 MAIN
78 BTFSC PIR1,1
79 CALL 0x004
80 ; rufe Interruptroutine auf, wenn Flag bei Timerüberlauf gesetzt wird
81 goto MAIN
82
83 end
Hat hierbei jemand einen Tipp für mich, wie der Controller die
übergebenen Werte annimmt?
Gruß, Mark
Hallo,
das Register PR2 befindet sich in Bank1. Ich habe das in deinem Code mal
geändert. Prüfe auch die anderen Register nochmal, ich habe jetzt nicht
Alles durchgesehen.
1 ; Frequenz auf 32 kHz einstellen
2 BSF STATUS , RP0 ; Bank1 <--- !
3 MOVLW d ' 124 ' ; 2 . 5 kHz new
4 MOVWF PR2
5 BCF STATUS , RP0 ; Bank0 <--- !
von
Hermann U.
(Firma: www.pcb-devboards.de)
(gera82 )
02.10.2009 13:12
HI.
Was möchtest du genau tun?
Das kann nicht sauber funktionieren: 1 MAIN
2 BTFSC PIR1 , 1
3 CALL 0x004
4 ; rufe Interruptroutine auf , wenn Flag bei Timer ü berlauf gesetzt wird
5 goto MAIN
das kann auch nicht gehen: 1 ; **************************************************************************
2 ; configure interrupts
3 ; **************************************************************************
4 org 0x004
5 CLRF PIR1
6
7 retfie
ändere so: 1 org 4
2
3 bsc INTCON , GIE
4
5 MOVWF W_TEMP
6 SWAPF STATUS , W
7 CLRF STATUS
8 MOVWF STATUS_TEMP
9 MOVF PCLATH , W
10 MOVWF PCLATH_TEMP
11 CLRF PCLATH
12
13
14 // hier kannst du interrupt auswerten, z.b. BTFSC PIR1,1
15
16
17
18 MOVF PCLATH_TEMP , W
19 MOVWF PCLATH
20 SWAPF STATUS_TEMP , W
21 MOVWF STATUS
22 SWAPF W_TEMP , F
23 SWAPF W_TEMP , W
24
25 bsf INTCON , GIE
26 retfie
gera82:
>Das kann nicht sauber funktionieren:
Da hast du absolut recht, das habe ich mir vorhin gar nicht angeschaut.
Dein Beispiel ist noch nicht 100pro richtig:
1 org 4
2
3 bsc INTCON , GIE ; wird vom PIC in HW erledigt , Zeile sollte
4 ; ganz entfernt werden
5 ; au ß erdem : Tippfehler , Befehl schreibt sich : bcf
6
7 MOVWF W_TEMP
8 SWAPF STATUS , W
9 CLRF STATUS
10 MOVWF STATUS_TEMP
11 MOVF PCLATH , W
12 MOVWF PCLATH_TEMP
13 CLRF PCLATH
14
15
16 // hier kannst du interrupt auswerten, z.b. BTFSC PIR1,1
17
18
19
20 MOVF PCLATH_TEMP , W
21 MOVWF PCLATH
22 SWAPF STATUS_TEMP , W
23 MOVWF STATUS
24 SWAPF W_TEMP , F
25 SWAPF W_TEMP , W
26
27 bsf INTCON , GIE ; erledigt der PIC in HW , Zeile auch raus
28 retfie
Grüße,
Edson
Danke für die schnellen Antworten. Das fehlerhafte Register habe ich
korrigiert. CCPR1L übernimmt im Simulator noch nicht den vorgegebenen
Wert. Es steht auf dem Default-Wert 0x00. Ist da ein Denkfehler von
meiner Seite? Es werden doch beide Register benötigt.
PR2 für den maximalen Zählerwert.
CCPR1L für den Verhältniswert.
Allgemein soll ein 50%-Verhältnis als Signal an den Ausgang gelegt
werden.
Bei der Interruptroutine habe ich zunächst einfach schauen wollen, ob er
da überhaupt hineinspringt und dabei das Flag / die Flags gelöscht.
>CCPR1L übernimmt im Simulator noch nicht den vorgegebenen
>Wert.
Hast du berücksichtigt, dass dieses Register wiederum in Bank0
anzusprechen ist?
Das hatte ich berücksichtigt.
Die Passage mit den angesprochenen Registern sieht nun wie folgt aus: 1 movlw d'62' ; new
2 movfw CCPR1L
3
4 BSF STATUS,RP0 ; Bank1
5 MOVLW d'124' ; 2.5 kHz new
6 MOVWF PR2
7 BCF STATUS,RP0 ; Bank0
Auf dem Oszilloskop gibt er mir ein dauerhaftes high aus.
Ich habe hier mal die Anleitung aus dem Datenblatt mit ein paar
Anmerkungen versehen:
1 11.3.7 SETUP FOR PWM OPERATION
2
3 The following steps should be taken when configuring
4 the CCP module for PWM operation:
5
6 1. Disable the PWM pin (CCP1) output drivers by
7 setting the associated TRIS bit.
8
9 ---> das machst du nicht, in deinem Code wird TRISIO zu Beginn gelöscht
10
11 2. Set the PWM period by loading the PR2 register.
12
13 3. Configure the CCP module for the PWM mode
14 by loading the CCP1CON register with the
15 appropriate values.
16
17 4. Set the PWM duty cycle by loading the CCPR1L
18 register and DC1B bits of the CCP1CON register.
19
20 ---> die Reihenfolge der letzten 3 Punkte stimmt in deinem Code nicht
21
22 5. Configure and start Timer2:
23 • Clear the TMR2IF interrupt flag bit of the
24 PIR1 register.
25 • Set the Timer2 prescale value by loading the
26 T2CKPS bits of the T2CON register.
27 • Enable Timer2 by setting the TMR2ON bit of
28 the T2CON register.
29
30 ---> beachte, dass die Interrupt-Flags vor dem 'enable' gelöscht werden
31
32 6. Enable PWM output after a new PWM cycle has
33 started:
34 • Wait until Timer2 overflows (TMR2IF bit of
35 the PIR1 register is set).
36 • Enable the CCP1 pin output driver by
37 clearing the associated TRIS bit.
38
39 ---> Punkt6 wird in deinem Code gar nicht berücksichtigt
Meister Eder schrieb: 1 > 1. Disable the PWM pin (CCP1) output drivers by
2 > setting the associated TRIS bit.
3 >
4 > ---> das machst du nicht, in deinem Code wird TRISIO zu Beginn
5 > gelöscht
Heißt das, dass der Pin als Eingang definiert wird?
Dem Rest widme ich mich gegen Abend.
>Heißt das, dass der Pin als Eingang definiert wird?
Ja, bis zum zweiten Punkt unter 6), ab da ist es dann der PWM-Ausgang.
Dadurch wird verhindert, dass der Ausgangstreiber während der
Initialisierung den Pin beeinflusst.
Mit den PWM-Anforderungen komme ich nun zum nachstehenden Code. Die
Interruptroutine ist einfach gehalten. Die Abfrage des gesetzten Flags
in der Main-Routine wird jedesmal abgefangen, sollte somit
funktionieren.
Das Problem besteht immer noch: CCPR1L nimmt nicht den zugewiesenen Wert
an. Woran könnte es liegen?
1 ;**************************************************************************
2 ; configure interrupts
3 ;**************************************************************************
4 org 0x004
5
6 MOVWF W_TEMP
7 SWAPF STATUS,W
8 CLRF STATUS
9 MOVWF STATUS_TEMP
10 MOVF PCLATH, W
11 MOVWF PCLATH_TEMP
12 CLRF PCLATH
13
14 ; // hier kannst du interrupt auswerten, z.b. BTFSC PIR1,1
15
16 BTFSC PIR1,1
17 CLRF PIR1
18
19 MOVF PCLATH_TEMP, W
20 MOVWF PCLATH
21 SWAPF STATUS_TEMP,W
22 MOVWF STATUS
23 SWAPF W_TEMP,F
24 SWAPF W_TEMP,W
25
26 CLRF TMR2
27 retfie
28
29 ;**************************************************************************
30 ; PIC configuration
31 ;**************************************************************************
32
33 INIT
34 ; reset selects 4 MHz default
35 BSF STATUS,RP0 ; Bank1
36 BSF OSCCON, SCS ; intosc is used
37 CLRF OPTION_REG
38 BSF OPTION_REG,INTEDG ; interrupt on rising edge
39 BCF STATUS,RP0 ; Bank0
40
41 ; GP2/CCP1 auf Eingang stellen
42 BSF STATUS,RP0 ; Bank1
43 BSF TRISIO,GP2
44 BCF STATUS,RP0 ; Bank0
45
46 ; PR2 festlegen
47 BSF STATUS,RP0 ; Bank1
48 MOVLW d'124' ;
49 MOVWF PR2
50 BCF STATUS,RP0 ; Bank0
51
52 ; PWM MODE mit CCP1 initialisieren
53 CLRF CCP1CON ; CCP1-Modus aus
54 BSF CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode, active high
55 BSF CCP1CON,CCP1M2 ;
56
57 BCF CCP1CON,DC1B1
58 BCF CCP1CON,DC1B0
59
60 ; Verhältnis einstellen
61 movlw d'62' ; new
62 movfw CCPR1L
63
64 ; PWM vorbereiten
65 ; 4MHz-Takt -> 1 MHz-Zyklustakt
66 ; Vorteiler 1:1 und Timer2 einschalten
67 CLRF PIR1
68 CLRF T2CON ; Vorteiler 1:1
69 BSF T2CON,TMR2ON ; Timer2 ein: B'00000010'
70
71 CLRF INTCON
72 BSF INTCON,GIE ; enable global interrupt
73
74 BSF STATUS,RP0 ; Bank1
75 CLRF PIE1
76 BSF PIE1,CCP1IE
77 BSF PIE1,TMR2IE
78 BCF STATUS,RP0 ; Bank0
79
80 ; IO-Pins vorbereiten
81 CLRF GPIO ; Init GPIO
82 MOVLW 0x07 ; Set GP<2:0> to
83 MOVWF CMCON0 ; digital I/O
84 BSF STATUS,RP0 ; Bank1
85 CLRF ANSEL ; digital I/O
86 BCF STATUS,RP0 ; Bank 0
87
88
89 ; wait until timer2 overflows
90 TMR2OF
91 BTFSS PIR1,1
92 GOTO TMR2OF
93 CLRF PIR1
94
95 ; PWM auf Ausgang nach Timer2-Durchlauf
96 BSF STATUS,RP0 ; Bank1
97 BSF TRISIO,2
98 BCF STATUS,RP0 ; Bank0
99
100 ;**************************************************************************
101 ; main programme
102 ;**************************************************************************
103 MAIN
104 BTFSC PIR1,1
105 CALL 0x004
106 ; rufe Interruptroutine auf, wenn Flag bei Timerüberlauf gesetzt wird
107 goto MAIN
108
109 end
von
holger (Gast)
05.10.2009 18:18
>; Verhältnis einstellen
> movlw d'62' ; new
> movfw CCPR1L
movwf CCPR1L
>BTFSC PIR1,1
>CALL 0x004
>; rufe Interruptroutine auf, wenn Flag bei Timerüberlauf gesetzt wird
Was soll denn der Quatsch mit dem Call 0x004?
Das macht der PIC von alleine! Also weg damit.
Danke, in der Simulation hat der uC den Interrupt nicht ausgelöst.
Deshalb hatte ich es im Code stehen lassen. Verschwindet natürlich
jetzt.
von
holger (Gast)
05.10.2009 19:18
Wenn du PEIE in INTCON auch noch setzt könnte
das sicher hilfreich sein.
Hallo,
um einen Pin als Ausgang zu benutzen, muss das entsprechende TRIS Bit
logisch 0 sein.
1 ; PWM auf Ausgang nach Timer2 - Durchlauf
2 BSF STATUS , RP0 ; Bank1
3 ; BSF TRISIO , 2 ; Pin ist Eingang
4 BCF TRISIO , 2 ; Pin ist Ausgang
5 BCF STATUS , RP0 ; Bank0
Das stimmt. Aber nun sind alle Fehler ausgemerzt und PWM funktioniert.
Vielen Dank an Holger, Meister Eder und Hermann, die mir helfen konnten.
von
Dennis (Gast)
06.08.2010 21:12
Hi,
Ich hoffe ich hab das richtige Forum erwischt.
Und zwar versuchen wir hier auch vergeblichst mit einem PIC12 F683 ein
PWM zu erzeugen.
Wir sind so zu sagen richtige Anfänger aber es ist ja noch nie ein Profi
vom Himmel gefallen :)
So haben wir uns mal am Anfang ein Source Code aus dem Internet
angeschaut und versucht in zu verwenden ( Wird weiter unten gezeigt ).
Unser einzigstes Problem ( so glauben wir ) liegt am definieren von GPIO
zu PORTA und das definieren von TRISIO zu TRISA.
Entschuldigung wenn wir komplett daneben liegen.
Wir benutzen das 8-Pin MPBLAB ICD 2 Header wenn ihr damit was anfangen
könnt!
Hier ein Bild:
Vorne: http://www.microchipdirect.com/images/devtools/ac162050.jpg
Von Hinten habe ich leider kein Orginales Bild gefunden.
Aber hinten ist nur der 8-Pin Sockel drauf.
Bild von dem Sockel:
http://rocky.digikey.com/weblib/On-Shore%20Technology/Web%20Photo/BU060Z-178-HT.jpg
Hier nun der Source Code:
1 ; Listing der Version für 16F684
2
3 ;**************************************************************
4 ;*
5 ;* Pinbelegung
6 ;* ---------------------------------- 683 / 684
7 ;* GPIO: 0 < Taster up Pin 7 / 13
8 ;* 1 < Taster down Pin 6 / 12
9 ;* 2 > PWM-Ausgang (32 kHz) (12F683) Pin 5
10 ;* 3 < Reset (MCLR) Pin 4
11 ;* 4 < Encoder B Pin 3
12 ;* 5 < Encoder A Pin 2
13 ;*
14 ;* PORTC: 5 > PWM-Ausgang (32 kHz) (16F684) Pin 5
15 ;*
16 ;**************************************************************
17 ;
18 ; sprut (zero) Bredendiek 11/2008
19 ;
20 ; PWM-Poti
21 ;
22 ; 12F683 erzeugt mit einer PWM eine Gleichspannung
23 ; gesteuert wird das durch:
24 ; 2 Taster in 16 Stufen (4 Bit)
25 ; Rotary-Encoder in 32 Stufen (5 Bit)
26 ;
27 ; 12F683 erzeugt an GP2 ein 32 kHz-PWM-Signal
28 ; PS=1; PR2=0x1F; resolution 5-Bit (32 Stufen)
29 ;
30 ;
31 ; Prozessortakt: 4 MHz intern, Zyklustakt 1 MHz
32 ;
33 ; Test mit 16F684
34 ;
35 ;**************************************************************
36 ; Includedatei einbinden
37
38 list p=12f683
39 #include <P12f683.INC>
40 ; list p=16f684
41 ; #include <P16f684.INC>
42
43 ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES
44
45 ; kein Power on Timer, kein Watchdog, int-Oscillator, kein Brown out
46 __CONFIG _MCLRE_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOD_OFF
47
48
49 ;**************************************************************
50 ; Variablen
51 loops2 EQU 0x20 ; fuer waitms
52 dc EQU 0x21 ; Taktverhaeltnis als 5-Bit Wert fuer CCPR1L
53 flags EQU 0x22
54 dcold EQU 0x23 ; alter dutycycle
55 neu EQU 0x24 ; neue Encoder-Stellung
56 alt EQU 0x25 ; alte Encoder-Stellung
57 temp EQU 0x26 ; fuer Encoder
58 t1count EQU 0x27
59
60 W_TEMP EQU 0xF0
61 STATUS_TEMP EQU 0xF1
62
63
64 ; Definitionen
65 #define KeyUp GPIO,0
66 #define KeyDown GPIO,1
67 #define UpKeyFlag flags,0
68 #define DownKeyFlag flags,1
69
70 #define encoder GPIO
71
72 ; fuer 16F684
73 #define GPIO PORTA
74 #define TRISIO TRISA
75
76 ;**************************************************************
77 ;voreingestellte Default-Werte im EEPROM
78 org H'2100' ; EEPROM
79 de 0x0F ; Adr 0 = 0x0F
80
81
82
83 ;**************************************************************
84 org 0 ; Anfang des Flash
85 GOTO init
86
87 org 0x04 ; Int
88 Int
89 MOVWF W_TEMP ; Copy W to TEMP register
90 SWAPF STATUS, W ; Swap status to be saved into W
91 CLRF STATUS ; bank 0, regardless of current bank, Clears IRP,RP1,RP0
92 MOVWF STATUS_TEMP ; Save status to bank zero STATUS_TEMP register
93
94 ; Timer1 loest mit 2 Hz Int aus
95 BTFSS PIR1, TMR1IF ; ist es Timer1?
96 GOTO IntEnd ; nein
97 DECFSZ t1count, f ; Zeit rum?
98 GOTO IntT1End ; nein
99 MOVLW D'10'
100 MOVWF t1count ; 5 Sekunden einstellen
101 MOVFW dc
102 xorwf dcold, w ; ist neu = alt?
103 bz IntT1End ; ja: nichts tun
104 ; neuen Wert im EEPROM speichern
105 MOVFW dc
106 MOVWF dcold
107 CALL EEWrite
108 IntT1End
109 BCF PIR1, TMR1IF ; Flag loeschen
110
111 IntEnd
112 SWAPF STATUS_TEMP,W ; Swap STATUS_TEMP register into W
113 ; (sets bank to original state)
114 MOVWF STATUS ; Move W into Status register
115 SWAPF W_TEMP,F ; Swap W_TEMP
116 SWAPF W_TEMP,W ; Swap W_TEMP into W
117 RETFIE
118
119
120 ;**************************************************************
121 ; Anfangsinitialisierung
122 init
123
124 ; internen Takt 4MHz
125 ; reset selects 4 MHz default
126 BSF STATUS,RP0 ; Bank1
127 BSF OSCCON, SCS ; intosc is used
128 BCF STATUS,RP0 ; Bank0
129 CLRF flags
130
131
132 ; PWM vorbereiten
133 ; 4MHz-Takt -> 1 MHz-Zyklustakt
134 ; Vorteiler 1:1 und Timer2 einschalten
135 CLRF T2CON ; Vorteiler 1:1
136 BSF T2CON,TMR2ON ; Timer2 ein
137
138 ; Frequenz auf 32 kHz einstellen
139 BSF STATUS,RP0 ; Bank1
140 MOVLW 0x1E ;
141 MOVWF PR2 ; 32 kHz
142 BCF STATUS,RP0 ; Bank0
143
144 ; Tastverhältnis auf alten Wert einstellen
145 CLRW ; Adresse fuer EEPROM = 0
146 CALL EERead ; alten Potiwert aus EEPROM lesen
147 MOVWF dc
148 MOVWF dcold
149 MOVWF CCPR1L ; PWM auf alten Wert einstellen
150
151 ; GP2/CCP1 auf Ausgang stellen
152 BSF STATUS,RP0 ; Bank1
153 BCF TRISIO, 2 ; GP2: output=0 12F683
154 BCF TRISC, 5 ; outout 16F684
155 BCF STATUS,RP0 ; Bank 0
156
157 ; PWM MODE mit CCP1 initialisieren
158 CLRF CCP1CON ; CCP1-Modus aus
159 BSF CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode, active high
160 BSF CCP1CON,CCP1M2 ;
161
162
163 ; IO-Pins vorbereiten
164 CLRF GPIO ; Init GPIO
165 MOVLW 0x07 ; Set GP<2:0> to
166 MOVWF CMCON0 ; digital I/O
167 BSF STATUS,RP0 ; Bank1
168 CLRF ANSEL ; digital I/O
169 MOVLW 0x33 ; pull-up fuer GP0,1,4,5
170 MOVWF WPU
171 BCF OPTION_REG, 7 ; pull-up master
172 BCF STATUS,RP0 ; Bank 0
173
174
175 ; Start-Encoderstand merken
176 MOVFW encoder ; Port lesen
177 MOVWF alt ; aktuelle encoder-Stellung nach alt
178 MOVLW B'00110000' ; Schablone für die beiden Bits
179 ANDWF alt, f ; nur die 2 Bits stehen lassen
180
181
182 ; Timer 1 zum EEPROM-schreiben , testet alle 2 Sekunden auf Aenderung
183 ; 1 MHz / 8 / 65536 = 1,9 Hz
184 MOVLW D'10'
185 MOVWF t1count ; 5 Sekunden einstellen
186 CLRF TMR1L
187 CLRF TMR1H
188 MOVLW B'00110001' ; Timer1 on, Vorteiler 8:1, interner Takt
189 MOVWF T1CON
190 BSF STATUS,RP0 ; Bank1
191 CLRF PIE1
192 BSF PIE1, TMR1IE ; Int on
193 BCF STATUS,RP0 ; Bank0
194 CLRF INTCON
195 BSF INTCON, PEIE
196 BSF INTCON, GIE
197
198
199 ;**********************************************************
200 ; Hauptprogrammschleife
201 Main
202
203
204 ; Tasten abfrage
205 UpKeyTest
206 BTFSC KeyUp
207 GOTO DownKeyTest
208 CALL wait1ms
209 BTFSC KeyUp
210 GOTO DownKeyTest
211 INCF dc,f
212 INCF dc,f
213 BSF UpKeyFlag
214 DownKeyTest
215 BTFSC KeyDown
216 GOTO Encoder
217 CALL wait1ms
218 BTFSC KeyDown
219 GOTO Encoder
220 DECF dc,f
221 DECF dc,f
222 BSF DownKeyFlag
223
224
225 ; Encoder abfragen
226 Encoder
227 ; Schritt A B
228 ; GP4 GP5
229 ; 0 - -
230 ; 1 H -
231 ; 2 H H
232 ; 3 - H
233 ; 0 - -
234 ; 1 H -
235 ; 2 H H
236 ; 3 - H
237
238 ; clrf RotorFlags
239 MOVFW encoder ; Port lesen
240 MOVWF neu ; aktuelle encoder-Stellung nach new
241 MOVLW B'00110000' ; Schablone für die beiden Bits
242 ANDWF neu, f ; nur die 2 Bits stehen lassen
243 MOVFW neu ; wurde der encoder bewegt?
244 MOVWF temp
245 MOVFW alt
246 XORWF temp, w ; ist neu = alt?
247 BZ Limits ; ja: nicht verdreht, also nichts tun
248 ; nein: encoder verdreht, aber in welche Richtung?
249 ; drehen wir mal Bit0 des alten werts zum Vergleich
250 ; nach links
251 BCF alt, 5
252 CLRC ; Carry-Flag löschen
253 RLF alt, f ; alten Encoder-Stand um 1 Stelle nach links drehen
254 MOVFW neu
255 XORWF alt, f ; falls xorf >1 ergibt, dann war es eine Rechtsdrehung
256 BZ links ; links: decrement counter
257 BTFSS alt, 4
258 GOTO rechts
259 BTFSS alt, 5
260 GOTO links
261 rechts
262 INCF dc,f ; rechts: increment counter
263 GOTO weiter
264 links
265 DECF dc,f ; links: decrement counter
266 weiter
267 MOVFW neu
268 MOVWF alt ; neu für nächsten Vergleich als alt speichern
269
270
271 ; pruefen ob dc zwischen 0 und 1F liegt
272 Limits
273 BTFSC dc, 7 ; negativ?
274 CLRF dc ; dc = 0
275 MOVLW B'11100000'
276 ANDWF dc, w ; > 0x1F ?
277 BTFSC STATUS, Z
278 GOTO LimitsEnd
279 MOVLW 0x1F
280 MOVWF dc
281 LimitsEnd
282
283
284 ; Wert an PWM übergeben
285 MOVFW dc
286 MOVWF CCPR1L
287
288
289 ; warten auf freie Tasten
290 Free
291 CALL wait1ms ; unterdruecken von Tasterprellen
292 FreeUp
293 BTFSS UpKeyFlag
294 GOTO FreeDown
295 FreeUpL
296 BTFSS KeyUp
297 GOTO FreeUpL
298 CALL wait1ms ; unterdruecken von Tasterprellen
299 FreeUpL1
300 BTFSS KeyUp
301 GOTO FreeUpL1
302 BCF UpKeyFlag
303
304 FreeDown
305 BTFSS DownKeyFlag
306 GOTO FreeEnd
307 FreeDownL
308 BTFSS KeyDown
309 GOTO FreeDownL
310 CALL wait1ms ; unterdruecken von Tasterprellen
311 FreeDownL1
312 BTFSS KeyDown
313 GOTO FreeDownL1
314 BCF DownKeyFlag
315 FreeEnd
316
317
318 GOTO Main
319
320
321 ;**************************************************************
322 ; Warteschleife 1 ms für einen 4-MHz-PIC-Takt
323 wait1ms
324 MOVLW .110 ; Zeitkonstante für 1ms
325 MOVWF loops2
326 Wai2 NOP
327 NOP
328 NOP
329 NOP
330 NOP
331 NOP
332 DECFSZ loops2, F ; 1 ms vorbei?
333 GOTO Wai2 ; nein, noch nicht
334 RETURN
335
336
337 ;**************************************************************
338 ; EEPROM-Routine für 12F683
339 ;**************************************************************
340 ; 12F683 hat 256 EEPROM-Zellen
341 ; 1 000 000 Schreibzyklen sind garantiert = 6 Tage lang mit 2 Hz Tasten druecken
342 ; = 60 Tage lang alle 5 Sekunden
343
344 ; lesen der Zelle, deren Adresse in W steht, nach W
345 EERead
346 BSF STATUS, RP0 ; EEADR liegt in der Bank 1
347 MOVWF EEADR ; schreibe die Adresse in EEADR
348 BSF EECON1, RD ; EEPROM Leseprozeß starten
349 MOVF EEDAT, W ; Die Daten der EEPROM Zelle nach W kopieren
350 BCF STATUS, RP0 ; Bank 0
351 RETURN
352
353
354 ; beschreiben des EEPROM; Adresse ist 0; Wert in w
355 EEWrite
356 BSF STATUS, RP0 ; der Bank 1
357 CLRF EEADR ; Die Zelle 0x00 soll beschrieben werden
358 MOVWF EEDATA ; w wollen wir schreiben
359 BSF EECON1, WREN ; nun ist Schreiben erlaubt
360 ; folgende Zeilen sind nicht noetig, wenn aus Int gerufen
361 ;EEW_GIE
362 ; BCF INTCON, GIE ; verbieten aller Interrupts
363 ; BTFSC INTCON,GIE ; See AN576
364 ; GOTO EEW_GIE
365 ; Die folgenden 5 Zeilen müssen genau so im Code stehen!!!
366 MOVLW 0x55 ;
367 MOVWF EECON2 ; schreibe 55h nach EECON2
368 MOVLW 0xAA ;
369 MOVWF EECON2 ; schreibe AAh nach EECON2
370 BSF EECON1, WR ; starte den Schreibzyklus
371 ; BSF INTCON, GIE ; Interrupts wieder erlauben , falls noetig
372 BCF STATUS, RP0 ; Bank 0
373 RETURN
374
375 ;**************************************************************
376
377
378
379 end
380
381 ;**************************************************************
Hilfe wäre echt nett :)
mfg Dennis
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.