; 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 
       
      ;************************************************************** 
       
       
       |