Gast
#5765616
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
