;************************************************************************************************** ; ; Einlesen eines Analog-Wertes und Umrechnen in eine 8-Bit Zahl ; -------> Ausgeben als 8-Bit PWM ; -------> Ausgeben als 10-Bit PWM ; ;************************************************************************************************** .device AT90S8535 .include "8535def.inc" ;************************************************************************************************** ; Variablen Deklaration ;************************************************************************************************** .def rdll = r0 ;LSB Divident .def rdlh = r1 ;MSB Divident .def rdlu = r2 ;Hilfsregister .def rd2 = r3 ;Divisor .def rel = r4 ;LSB Ergebnis .def reh = r5 ;MSB Ergebnis .def hexl = r6 .def hexh = r7 .def int_serv = r16 .def temp = r19 ;Schmierregister 1 .def temp2 = r20 ;Schmierregister 2 .def ADCLow = r21 ;LSB ADC .def ADCHigh = r22 ;MSB ADC .def ADCLow2 = r23 ;LSB ADC2 .def ADCHigh2 = r24 ;MSB ADC2 .org 0x00 ;************************************************************************************************** ; Stackpointer initialiseren ;************************************************************************************************** ldi temp, LOW(RAMEND) out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ;************************************************************************************************** ; Port C + D auf Ausgang schalten ;************************************************************************************************** ldi temp, 0xFF out DDRC, temp out DDRD, temp ;************************************************************************************************** ; PWM initialisieren ;************************************************************************************************** ldi temp, 0x07 out ADCSR, temp sbi ADCSR, ADEN sbi ADCSR, ADIE ldi temp, 0xA3 ;PWM als 10-Bit konfigurieren out TCCR1A, temp ldi temp, 0 out OCR1AH, temp ldi temp, 1 out OCR1AL, temp ldi temp, 0 out OCR1BH, temp ldi temp, 1 out OCR1BL, temp ldi temp, 0x01 ;Seite 37 vom Datenblatt out TCCR1b, temp ldi temp, 0b01111001 ;Timer 2 als 8-Bit PWM-Konfiguriert out TCCR2, temp ldi temp, 0x00 ;Vergleichsregister löschen out OCR2, temp ;sei main: rjmp adc lds rdlh, $68 ;ADC-Wert ins Rechenregister kopieren lds rdll, $60 ldi temp, 4 ;0x04 als Divisor mov rd2, temp rcall dividieren out OCR2, rel ;PWM 3 --> nur 8 Bit lds ADCHigh, $68 lds ADCLow, $60 out OCR1AH, ADCHigh ;erst das ADCH-Byte schreiben. dann out OCR1AL, ADCLow ;das Low Byte. Sonst funktioniert ;es nicht lds ADCHigh2, $78 lds ADCLow2, $70 out OCR1BH, ADCHigh2 out OCR1BL, ADCLow2 rjmp main dividieren: ; Dividieren von rdlh:rdll durch rd2 div8: clr rdlu ;Hilfsregister löschen clr reh ;Leere Ergebnisregister clr rel ;(Ergebnisregister dient auch als inc rel ;Zähler bis 16! Bit 1 auf 1 setzen) div8a: clc ;Carry-Bit löschen rol rdll ;nächsthöheres Bit des Dividenden rol rdlh ;in das Hilfsregister rotieren rol rdlu ;(entspricht Multiplikation mit 2) brcs div8b ;Eine 1 ist herausgerollt, ziehe ab cp rdlu, rd2 ;Divisionsergebnis 1 oder 0? brcs div8c ;Überspringe Subraktion wenn kleiner div8b: sub rdlu, rd2 ;Subtrahiere Divisor sec ;Setze Carry-Bit, Ergebnis ist eine 1 rjmp div8d ;zum Sieben des Ergebnisses div8c: clc ;Lösche Carry-Bit, Ergebnis ist eine 0 div8d: rol rel ;Rotiere Carry-Bit in das Ergebnis rol reh brcc div8a ;solange Nullen aus dem Ergebnis ;rotieren: weitermachen ret ; Ende der Division ;**************************************************************************************** ; ; 8 Kanal ADC Wandlung, ; ;**************************************************************************************** ;----------------------- ;ADC aktivieren, In 1 ;----------------------- adc: ldi temp,0x00 out ADMUX,temp ;Kanal 0 vom ADC auswählen sbi ADCSR,ADSC ;Singlemode ein rcall fertig ;Warten bis Wandlung beendet in hexl,ADCL ;lowbyte auslesen in hexh,ADCH ;hibyte auslesen sts $60,hexl ;low byte speichern sts $68,hexh ;high byte speichern ;----------------------- ;ADC aktivieren, In 2 ;----------------------- ldi temp,0x01 out ADMUX,temp ;Kanal 1 vom ADC auswählen sbi ADCSR,ADSC ;Singlemode ein rcall fertig ;Warten bis Wandlung beendet in hexl,ADCL ;lowbyte auslesen in hexh,ADCH ;hibyte auslesen sts $70,hexl ;low byte speichern sts $78,hexh ;high byte speichern ret ;zurück ins Hauptprogramm fertig: sbis ADCSR,ADIF ;Warten bis Wandlung nop nop nop rjmp fertig ;beendet ret