Forum: Mikrocontroller und Digitale Elektronik Atmega32 Dimmer Schaltung in Assembler


von Harry (Gast)


Lesenswert?

Falls jemand eine übers Internet Dimmer Schaltung mit Atmega 32
sucht und nichts findet , so wie ich , kann dies mal testen.
Wurde mit AVR Studio 4 geschrieben und getestet.
Die Schaltung hab ich über Bastelplatine selbst zusammen-
gebaut mit USB Übertragung.


;***********************************************************************
;**  Dimmer Schaltung !!                                              **
;**                                                                   **
;**  PortD4 = Leuchtdiode  PA0 = Poti  Taster PD0                     **
;**  Gelbe Leuchtdiode als Test in PB0  Dauerbetrieb                  **
;**  RotDimmerschaltunginPD4
;**  Anschlüsse:
;**                                                                   **
;**  Poti Anschluss : Lings = Minus > Rechts = Plus > Mitte = ist PA0 **
;**  Poti = 100kOhm    Diode über 220 Ohm Widerstand                  **
;**  Taster PD0 und Minuspol                                          **
;**                                                                   **
;***********************************************************************


.NOLIST
 .INCLUDE <m32def.inc>
 .LIST
 .def DimWertL=r22
 .def DimWertH=r23
 .def VerzoegWert0=r20
 .def VerzoegWert1=r21
 .def temp1 = r24
 .def temp2 = r25
 .def adlow = r1       ; Ergebnis vom ADC-Mittelwert der 256 Messungen
 .def adhigh = r2
 .equ XTAL = 4000000       ;4000000 >> 4MHz ???  1000000 = 1MHz ??? 
4000000 = langsam
 .def leds = r17
 .def temp3 = r18


RESET:
  jmp INIT           ; springen nach "INIT"
 ;------------------------------------------------------
 ;     ISR VECTORS
 ;------------------------------------------------------
 .ORG OVF1addr
  rjmp  OVF1_Handler
INIT:
 ;------------------------------------------------------
 ;     INITIALIZE
 ;------------------------------------------------------
  ldi  r16,  high(RAMEND)     ;Stack Pointer setzen
  out   SPH,  r16
  ldi   r16,  low(RAMEND)
  out   SPL,  r16

;Taster init

ldi r16,0b00000000
Out DDRD,r16
ldi r16,0b00000001
Out PortD,r16                            ;Tastereingang > von PortD 
aktiv machen
;ldi temp3,0x00
sbi DDRB,DDB0                             ;Test Diodeleuchte vorbereiten

 ;------------------------------------------------------
 ;   eigene Initialisierungen
 ;------------------------------------------------------
  ldi  r16,  0b00010000         ;0x10
  out  DDRD,  r16        ;PORTD4 als Ausgang initialisieren

  ;ldi  r16,  0b00010000        ;PortD4  0x10
  ;out  PORTD,  r16

  ldi  r16,  1<<COM1A1 | 1<<COM1B1 | 1<<WGM10 | 1<<WGM11
  out  TCCR1A,  r16            ;TimerCounter1:10-Bit-Fast-PWM
  ldi  r16,  1<<WGM12 | 1<<CS10    ;Mode: 7
  out  TCCR1B,  r16

  ldi  r16,  1<<TOIE1
  out  TIMSK,  r16            ;Timer/Counter1 Interrupt Enable(setzen)


;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- 
*-
;
; ADC initialisieren: Single Conversion, Vorteiler 128
; Kanal 0, interne Referenzspannung AVCC
ldi temp1, (1<<REFS0)
out ADMUX, temp1
ldi temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
out ADCSRA, temp1
;
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- 
*-

sei                         ;Interrupts allgemein aktivieren(im 
Status-Register)


ldi  r18,      1            ;
mov  VerzoegWert0,  r18     ; Überlauf Werte
ldi  r19,      1            ;
mov  VerzoegWert1,  r19     ;Überlauf Werte

ldi   r16,  0x01            ;0x03-0xFF Zähler setzen, jetz fangt er mit 
der
out   TCNT1H,  r16          ;Hauptschleife zu zählen an
ldi   r16,  0xFF
out   TCNT1L,  r16
;------------------------------------------------------
;   HAUPTSCHLEIFE
;------------------------------------------------------
Hauptschleife:
        com temp3
        com temp3
        nop

rjmp    Hauptschleife


OVF1_Handler:               ;Timer/Counter1-Überlauf
        ldi r16,0x00
        cp  r16,temp3
        Breq Pin_out
        rjmp Pin_off

Pin_out:
        sbis PinD,0            ;wenn ja dann Pin_on
        rjmp Pin_an            ;zu Pin_on
        rjmp ret_OVF1_H


Pin_off:
        sbis PinD,0            ;wenn ja dann Pin_aus
        rjmp Pin_aus            ;zu Pin_on
        rjmp Pin_start

Pin_aus:
ldi r16,0b00000000           ;D4 nicht aktiv  Rot Led aus keine 
Dimmerung
Out DDRD,r16
ldi r16,0b00000001           ;Tastereingang > von PortD aktiv lassen
Out PortD,r16
;Test Leuchtdiode PB0   Aus
;----------------------------
sbi PORTB,PORTB0             ;Portpin PB0 auf Eins, Led aus
;Test Ende...
ldi r16, 0x00
ldi temp3,0x00
reti


Pin_an:
ldi  r16,  0b00010000        ;D4 aktiv  Rot Led an dimmer aktiv
out  DDRD,  r16
ldi  r16,  0b00010001        ;PortD4 an und Tastereingang > von PortD 
aktiv lassen
out  PORTD,  r16
;Test Leuchtdiode PB0  An
;----------------------------
cbi PORTB,PORTB0             ;Portpin PB0 auf Null, Gelb Led an
;Test Ende...
ldi r16, 0x01
ldi temp3,0x01


Pin_start:

dec  VerzoegWert0           ;---------------------------------
breq  Zeitgeber1
ret_OVF1_H:
reti                        ;springe zurück in die Hauptschleife
                            ;warte eine bestimmte Anzahl von Überläufen 
ab
Zeitgeber1:                 ;(Wert durch VerzögWert0 und VerzögWert1 
bestimmen)
mov  VerzoegWert0,  r18
dec  VerzoegWert1           ;---------------------------------
breq  NeueDWerte            ;springe zu NeueDWerte
rjmp  ret_OVF1_H            ;springe zu ret_OVF1_H

NeueDWerte:
mov  VerzoegWert1, r19
;
;
clr temp1
clr temp2
clr r26
clr r27
ldi r28, 0                  ; 256 Schleifendurchläufe
                            ; neuen ADC-Wert lesen (Schleife - 256 mal)
adc_messung:
sbi ADCSRA, ADSC            ; den ADC starten
adc_warten:
sbic ADCSRA, ADSC           ; wenn der ADC fertig ist, wird dieses Bit
                            ; gelöscht
                            ;
rjmp adc_warten
                            ; ADC einlesen:
in adlow, ADCL              ; immer zuerst LOW Byte lesen
in adhigh, ADCH             ; danach das mittlerweile gesperrte High 
Byte
                            ; alle 256 ADC-Werte addieren
                            ; dazu wird mit den Registern temp4, temp3 
und temp2 ein
                            ; 24-Bit breites Akkumulationsregister 
gebildet, in dem
                            ; die 10 Bit Werte aus adhigh, adlow 
aufsummiert werden
add temp2, adlow            ; addieren
adc r26, adhigh             ; addieren über Carry
adc r27, temp1              ; addieren über Carry, temp1 enthält 0
dec r28                     ; Schleifenzähler MINUS 1
brne adc_messung            ; wenn noch keine 256 ADC Werte -> nächsten 
Wert einlesen
                            ; Aus den 256 Werten den Mittelwert 
berechnen
                            ; Bei 256 Werten ist das ganz einfach: Das 
niederwertigste Byte
                            ; (im Register temp2) fällt einfach weg
                            ;
                            ; allerdings wird der Wert noch gerundet
cpi temp2,128               ; "Kommastelle" kleiner als 128 ?
brlo nicht_runden           ; ist kleiner ==> Sprung
                            ; Aufrunden
subi r26, low(-1)           ; addieren von 1
sbci r27, high(-1)          ; addieren des Carry
nicht_runden:
                            ; Ergebnis nach adlow und adhigh kopieren
                            ; damit die temp Register frei werden
mov DimWertL, r26
mov DimWertH, r27
out  OCR1AL,  DimWertL      ;gib DimWertL in OCR1AL aus
out  OCR1AH, DimWertH       ;gib DimWertH in OCR1AH aus
out  OCR1BL,  DimWertL      ;gib DimWertL in OCR1BL aus
out  OCR1BH, DimWertH       ;gib DimWertH in OCR1BH aus
rjmp  ret_OVF1_H            ;springe zu ret_OVF1_H





                            ;   ENDE
Ende:                       ; Braucht man normal nicht ! Aber sicher ist 
sicher !
  rjmp  Ende

von Stefan F. (Gast)


Lesenswert?

Um Quelltext ordentlich darzustellen gibt es formatier-tags auf die du 
beim  Erstellen dieses Beitrages dick und fett hingewiesen wurdest.

Es wäre nett, wenn du den Schaltplan nachreichen würdest. Du wolltest 
doch eine Schaltung präsentieren.

Was hat die Sache mit Internet zu tun?

Oder wolltest du etwas fragen?

von Karl B. (gustav)


Angehängte Dateien:

Lesenswert?

Stefanus F. schrieb:
> Um Quelltext ordentlich darzustellen gibt es formatier-tags auf
> die du
> beim  Erstellen dieses Beitrages dick und fett hingewiesen wurdest.
>
> Es wäre nett, wenn du den Schaltplan nachreichen würdest. Du wolltest
> doch eine Schaltung präsentieren.
>
> Oder wolltest du etwas fragen?

Hi,
.INCLUDE "m32def.inc" muss es heißen.
sonst bei
.INCLUDE <m32def.inc>
C:\Users\..\..\Leddim.asm(30): error: syntax error, unexpected INTEGER


Das Prob. mit den Kommentarzeilen. Die sind zu lang und da muss dann 
nach Zeilenumbruch noch ein Semikolon rein.
Trotzdem mal nachher schauen ob es bei mir läuft.

ciao
gustav

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.