; Listing der Version für
16F684
;**************************************************************
;*
;* Pinbelegung
;*
----------------------------------
683 / 684
;*
GPIO:
0 < Taster
up
Pin
7 / 13
;*
1
< Taster
down
Pin
6 / 12
;*
2
> PWM-Ausgang (32 kHz)
(12F683) Pin 5
;*
3
< Reset
(MCLR)
Pin
4
;*
4
< Encoder
B
Pin
3
;*
5
< Encoder
A
Pin
2
;*
;*
PORTC:
5 > PWM-Ausgang (32 kHz)
(16F684)
Pin
5
;*
;**************************************************************
;
; sprut (zero) Bredendiek
11/2008
;
; PWM-Poti
;
; 12F683 erzeugt mit einer
PWM eine Gleichspannung
; gesteuert wird das durch:
;
2
Taster in 16 Stufen (4 Bit)
;
Rotary-Encoder
in 32 Stufen (5 Bit)
;
; 12F683 erzeugt an GP2 ein
32 kHz-PWM-Signal
; PS=1; PR2=0x1F; resolution
5-Bit (32 Stufen)
;
;
; Prozessortakt: 4 MHz
intern, Zyklustakt 1 MHz
;
; Test mit 16F684
;
;**************************************************************
; Includedatei einbinden
;
list
p=12f683
;
#include
<P12f683.INC>
list
p=16f684
#include
<P16f684.INC>
ERRORLEVEL
-302
;SUPPRESS
BANK SELECTION MESSAGES
; kein Power on Timer, kein
Watchdog, int-Oscillator, kein Brown out
__CONFIG
_MCLRE_ON &
_PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BOD_OFF
;**************************************************************
; Variablen
loops2
EQU
0x20
;
fuer waitms
dc
EQU
0x21
;
Taktverhaeltnis als 5-Bit Wert fuer CCPR1L
flags
EQU
0x22
dcold
EQU
0x23
;
alter dutycycle
neu
EQU
0x24
;
neue Encoder-Stellung
alt
EQU
0x25
;
alte Encoder-Stellung
temp
EQU
0x26
;
fuer Encoder
t1count
EQU
0x27
W_TEMP
EQU
0xF0
STATUS_TEMP
EQU
0xF1
; Definitionen
#define
KeyUp GPIO,0
#define
KeyDown GPIO,1
#define
UpKeyFlag flags,0
#define
DownKeyFlag flags,1
#define
encoder GPIO
; fuer 16F684
#define
GPIO
PORTA
#define
TRISIO TRISA
;**************************************************************
;voreingestellte
Default-Werte im EEPROM
org
H'2100'
; EEPROM
de
0x0F
;
Adr 0 = 0x0F
;**************************************************************
org
0
;
Anfang des Flash
GOTO
init
org
0x04
;
Int
Int
MOVWF
W_TEMP
; Copy W
to TEMP register
SWAPF
STATUS, W ; Swap
status to be saved into W
CLRF
STATUS
; bank 0,
regardless of current bank, Clears IRP,RP1,RP0
MOVWF
STATUS_TEMP ; Save status to
bank zero STATUS_TEMP register
;
Timer1 loest mit 2 Hz Int aus
BTFSS
PIR1, TMR1IF ; ist es Timer1?
GOTO
IntEnd
; nein
DECFSZ
t1count, f ; Zeit rum?
GOTO
IntT1End
; nein
MOVLW
D'10'
MOVWF
t1count
; 5 Sekunden
einstellen
MOVFW
dc
xorwf
dcold, w ;
ist neu = alt?
bz
IntT1End
; ja: nichts tun
;
neuen Wert im EEPROM speichern
MOVFW
dc
MOVWF
dcold
CALL
EEWrite
IntT1End
BCF
PIR1, TMR1IF ; Flag
loeschen
IntEnd
SWAPF
STATUS_TEMP,W ; Swap STATUS_TEMP register
into W
;
(sets bank to original state)
MOVWF
STATUS
; Move W
into Status register
SWAPF
W_TEMP,F ;
Swap W_TEMP
SWAPF
W_TEMP,W ;
Swap W_TEMP into W
RETFIE
;**************************************************************
; Anfangsinitialisierung
init
; internen Takt 4MHz
;
reset selects 4 MHz default
BSF
STATUS,RP0 ;
Bank1
BSF
OSCCON, SCS ;
intosc is used
BCF
STATUS,RP0 ;
Bank0
CLRF
flags
; PWM vorbereiten
; 4MHz-Takt -> 1
MHz-Zyklustakt
; Vorteiler 1:1 und Timer2
einschalten
CLRF
T2CON
;
Vorteiler 1:1
BSF
T2CON,TMR2ON ; Timer2 ein
; Frequenz auf 32 kHz
einstellen
BSF
STATUS,RP0 ;
Bank1
MOVLW
0x1E
;
MOVWF
PR2
;
32 kHz
BCF
STATUS,RP0 ;
Bank0
; Tastverhältnis auf
alten Wert einstellen
CLRW
;
Adresse fuer EEPROM = 0
CALL
EERead
; alten
Potiwert aus EEPROM lesen
MOVWF
dc
MOVWF
dcold
MOVWF
CCPR1L
; PWM auf
alten Wert einstellen
; GP2/CCP1 auf Ausgang
stellen
BSF
STATUS,RP0 ;
Bank1
BCF
TRISIO,
2 ; GP2: output=0 12F683
BCF
TRISC,
5 ; outout 16F684
BCF
STATUS,RP0 ;
Bank 0
; PWM MODE mit CCP1
initialisieren
CLRF
CCP1CON
; CCP1-Modus aus
BSF
CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode,
active high
BSF
CCP1CON,CCP1M2 ;
; IO-Pins vorbereiten
CLRF
GPIO
;
Init GPIO
MOVLW
0x07
;
Set GP<2:0> to
MOVWF
CMCON0
; digital
I/O
BSF
STATUS,RP0 ;
Bank1
CLRF
ANSEL
;
digital I/O
MOVLW
0x33
;
pull-up fuer GP0,1,4,5
MOVWF
WPU
BCF
OPTION_REG, 7 ; pull-up master
BCF
STATUS,RP0 ;
Bank 0
; Start-Encoderstand merken
MOVFW
encoder
; Port lesen
MOVWF
alt
;
aktuelle encoder-Stellung nach alt
MOVLW
B'00110000' ; Schablone
für die beiden Bits
ANDWF
alt,
f ; nur die 2
Bits stehen lassen
; Timer 1 zum
EEPROM-schreiben , testet alle 2 Sekunden auf Aenderung
; 1 MHz / 8 / 65536 = 1,9 Hz
MOVLW
D'10'
MOVWF
t1count
; 5 Sekunden
einstellen
CLRF
TMR1L
CLRF
TMR1H
MOVLW
B'00110001' ; Timer1 on,
Vorteiler 8:1, interner Takt
MOVWF
T1CON
BSF
STATUS,RP0 ;
Bank1
CLRF
PIE1
BSF
PIE1, TMR1IE ; Int on
BCF
STATUS,RP0 ;
Bank0
CLRF
INTCON
BSF
INTCON, PEIE
BSF
INTCON, GIE
;**********************************************************
; Hauptprogrammschleife
Main
; Tasten abfrage
UpKeyTest
BTFSC
KeyUp
GOTO
DownKeyTest
CALL
wait1ms
BTFSC
KeyUp
GOTO
DownKeyTest
INCF
dc,f
INCF
dc,f
BSF
UpKeyFlag
DownKeyTest
BTFSC
KeyDown
GOTO
Encoder
CALL
wait1ms
BTFSC
KeyDown
GOTO
Encoder
DECF
dc,f
DECF
dc,f
BSF
DownKeyFlag
; Encoder abfragen
Encoder
;
Schritt
A B
;
GP4
GP5
;
0
-
-
;
1
H
-
;
2
H
H
;
3
-
H
;
0
-
-
;
1
H
-
;
2
H
H
;
3
-
H
;
clrf
RotorFlags
MOVFW
encoder
;
Port lesen
MOVWF
neu
;
aktuelle encoder-Stellung nach new
MOVLW
B'00110000'
;
Schablone für die beiden Bits
ANDWF
neu,
f
;
nur die 2 Bits stehen lassen
MOVFW
neu
;
wurde der encoder bewegt?
MOVWF
temp
MOVFW
alt
XORWF
temp,
w
;
ist neu = alt?
BZ
Limits
;
ja: nicht verdreht, also nichts tun
;
nein: encoder verdreht, aber in welche Richtung?
;
drehen wir mal Bit0 des alten werts zum Vergleich
;
nach links
BCF
alt, 5
CLRC
;
Carry-Flag löschen
RLF
alt,
f
;
alten Encoder-Stand um 1 Stelle nach links drehen
MOVFW
neu
XORWF
alt,
f
;
falls xorf >1 ergibt, dann war es eine Rechtsdrehung
BZ
links
;
links: decrement counter
BTFSS
alt, 4
GOTO
rechts
BTFSS
alt, 5
GOTO
links
rechts
INCF
dc,f
;
rechts: increment counter
GOTO
weiter
links
DECF
dc,f
;
links: decrement counter
weiter
MOVFW
neu
MOVWF
alt
;
neu für nächsten Vergleich als alt speichern
; pruefen ob dc zwischen 0
und 1F liegt
Limits
BTFSC
dc,
7 ; negativ?
CLRF
dc
;
dc = 0
MOVLW
B'11100000'
ANDWF
dc,
w ; >
0x1F ?
BTFSC
STATUS, Z
GOTO
LimitsEnd
MOVLW
0x1F
MOVWF
dc
LimitsEnd
; Wert an PWM übergeben
MOVFW
dc
MOVWF
CCPR1L
; warten auf freie Tasten
Free
CALL
wait1ms
; unterdruecken
von Tasterprellen
FreeUp
BTFSS
UpKeyFlag
GOTO
FreeDown
FreeUpL
BTFSS
KeyUp
GOTO
FreeUpL
CALL
wait1ms
; unterdruecken
von Tasterprellen
FreeUpL1
BTFSS
KeyUp
GOTO
FreeUpL1
BCF
UpKeyFlag
FreeDown
BTFSS
DownKeyFlag
GOTO
FreeEnd
FreeDownL
BTFSS
KeyDown
GOTO
FreeDownL
CALL
wait1ms
; unterdruecken
von Tasterprellen
FreeDownL1
BTFSS
KeyDown
GOTO
FreeDownL1
BCF
DownKeyFlag
FreeEnd
GOTO
Main
;**************************************************************
; Warteschleife 1 ms
für einen 4-MHz-PIC-Takt
wait1ms
MOVLW
.110
;
Zeitkonstante für 1ms
MOVWF
loops2
Wai2 NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ
loops2, F ; 1 ms vorbei?
GOTO
Wai2
;
nein, noch nicht
RETURN
;**************************************************************
; EEPROM-Routine
für 12F683
;**************************************************************
; 12F683 hat 256
EEPROM-Zellen
; 1 000 000 Schreibzyklen
sind garantiert = 6 Tage lang mit 2
Hz Tasten druecken
;
=
60 Tage lang alle 5 Sekunden
; lesen der Zelle, deren
Adresse in W steht, nach W
EERead
BSF
STATUS, RP0 ; EEADR liegt
in der Bank 1
MOVWF
EEADR
;
schreibe die Adresse in EEADR
BSF
EECON1, RD ; EEPROM
Leseprozeß starten
MOVF
EEDAT, W ;
Die Daten der EEPROM Zelle nach W kopieren
BCF
STATUS, RP0 ; Bank 0
RETURN
; beschreiben des EEPROM;
Adresse ist 0; Wert in w
EEWrite
BSF
STATUS, RP0 ; der
Bank 1
CLRF
EEADR
; Die
Zelle 0x00 soll beschrieben werden
MOVWF
EEDATA
; w wollen
wir schreiben
BSF
EECON1, WREN ; nun ist
Schreiben erlaubt
; folgende Zeilen sind nicht
noetig, wenn aus Int gerufen
;EEW_GIE
;
BCF
INTCON, GIE ;
verbieten aller Interrupts
;
BTFSC
INTCON,GIE ; See AN576
;
GOTO
EEW_GIE
;
Die folgenden 5 Zeilen müssen genau so im Code stehen!!!
MOVLW
0x55
;
MOVWF
EECON2
; schreibe
55h nach EECON2
MOVLW
0xAA
;
MOVWF
EECON2
; schreibe
AAh nach EECON2
BSF
EECON1, WR ;
starte den Schreibzyklus
;
BSF
INTCON, GIE ;
Interrupts wieder erlauben , falls noetig
BCF
STATUS, RP0 ; Bank 0
RETURN
;**************************************************************
end
;**************************************************************
|