; .include "tn2313def.inc" .include "m48def.inc" #define CPU_Frequency 16000000 #define putchar lcd_wrdat #define lcd_rs_port portb #define lcd_rs_ddr ddrb #define lcd_rs_bit 6 #define lcd_en_port portd #define lcd_en_ddr ddrd #define lcd_en_bit 4 #define lcd_dat_port portd #define lcd_dat_ddr ddrd #define i2c_port portd #define i2c_pin pind #define i2c_ddr ddrd #define i2c_sda 6 #define i2c_scl 5 #define taster_pin pinb #define taster_port portb #define taster_bit 7 #define encoder_a_pin pinb #define encoder_a_port portb #define encoder_a_bit 0 #define encoder_b_pin pind #define encoder_b_port portd #define encoder_b_bit 7 .def temp0 =r0 ;Übergabe für LDEZ .def temp1 =r1 ;Übergabe für LDEZ .def temp2 =r2 ;Hoch/Runterzählen .def temp3 =r3 ;des jeweiligen Wertes .def temp4 =r4 .def temp5 =r5 .def steptime0 =r6 ;Zeit zwischen .def steptime1 =r7 ;2 Schritten am Rad .def volt0 =r8 ;Sollwert .def volt1 =r9 ;Spannung .def amper0 =r10 ;Sollwert .def amper1 =r11 ;Strom .def adubuf0 =r12 .def adubuf1 =r13 .def aducount =r14 .def BitFlag =r15 ;0=ein/aus, 1=Spannung/Strom ;################################ ;Variablen im RAM .dseg .org SRAM_START MaskSrg: .byte 1 ;hier wird das Encoder-Bitmuster gespeichert PressTime: .byte 1 ;Wie lange der Knopf gedrückt StepTime: .byte 2 ;Pause zwischen 2 Schritten VoltIst: .byte 2 AmperIst: .byte 2 ;################################ .cseg rjmp reset rjmp int0_isr rjmp int1_isr rjmp tim1_capt rjmp tim1_compa rjmp tim1_ovf rjmp tim0_ovf rjmp usart0_rxc rjmp usart0_dre rjmp usart0_txc rjmp ana_comp rjmp pcint rjmp timer1_compb rjmp timer0_compa rjmp timer0_compb rjmp usi_start rjmp usi_overflow rjmp ee_ready rjmp wdt_overflow int0_isr: int1_isr: tim1_capt: tim1_compa: tim1_ovf: tim0_ovf: usart0_rxc: usart0_dre: usart0_txc: ana_comp: pcint: timer1_compb: timer0_compa: timer0_compb: usi_start: usi_overflow: ee_ready: wdt_overflow: reti reset: ldi r16,LOW(RAMEND) out spl,r16 ldi r16,1<<1|1<<2 ;PWM-Ausgänge aktiv out ddrb,r16 sbi encoder_a_port,encoder_a_bit ;Pullups für Eingänge aktivieren sbi encoder_b_port,encoder_b_bit sbi taster_port,taster_bit ;Timer1 für 16Bit PWM initialisieren ldi r16,15 sts icr1h,r16 ldi r16,255 ;maximaler Zählumfang 4096 sts icr1l,r16 ldi r16,0b10100000 ;Phasen und Frequenzkorrigiert sts tccr1a,r16 ldi r16,0b00010001 ;Vorteiler 1 sts tccr1b,r16 rcall i2c_init ;gespeicherte Werte aus EEPROM rcall i2c_start ;wieder einlesen ldi r16,0xa0 rcall i2c_wrbyte ldi r16,0 rcall i2c_wrbyte rcall i2c_start ldi r16,0xa1 rcall i2c_wrbyte rcall i2c_rdbyte mov Volt0,r16 rcall i2c_rdbyte mov Volt1,r16 rcall i2c_rdbyte mov Amper0,r16 rcall i2c_rdbyte mov Amper1,r16 rcall i2c_rdbyte mov BitFlag,r16 rcall i2c_stop ;###################################### ;ADU initialisieren ldi r16,0b11000000 ;Digitale Eingänge der 2 ADU-Pins sperren sts DIDR0,r16 ldi r16,1<' rcall lcd_wrdat ldi r16,' ' rcall lcd_wrdat lds r0,VoltIst lds r1,VoltIst+1 rcall ldez_V disp_amper: ldi r16,0b11000000 ;Cursor auf Anfang 2. Zeile rcall lcd_wrcom ;Strom, Soll oder Ist anzeigen? tst r6 brne disp_amper_ist sbrs BitFlag,1 ;Spannung in der Einstellung? rjmp disp_amper_ist ;Strom Sollwert anzeigen ldi r16,'S' rcall lcd_wrdat ldi r16,' ' rcall lcd_wrdat mov r0,amper0 mov r1,amper1 lsr r1 ror r0 lsr r1 ror r0 rcall ldez_A rjmp Poll_Encoder disp_amper_ist: ;Strom Istwert anzeigen ldi r16,' ' sbrc BitFlag,1 ;Spannung in der Einstellung? ldi r16,'>' rcall lcd_wrdat ldi r16,' ' rcall lcd_wrdat lds r0,AmperIst lds r1,AmperIst+1 rcall ldez_A Poll_Encoder: ;Spannung oder Strom laden? sbrc BitFlag,1 rjmp LoadAmper mov r2,Volt0 mov r3,Volt1 rjmp LoadVolt LoadAmper: mov r2,Amper0 mov r3,Amper1 LoadVolt: lds r18,MaskSrg ;altes Bitmuster laden in r16,encoder_a_pin ;aktuellen Encoderstand holen in r17,encoder_b_pin rol r18 ;alten Stand 2 Bits nach links rol r18 ;für die neuen andi r18,15 ;Rest maskieren bst r16,encoder_a_bit ;neue Bits bld r18,0 ;auf die unteren Stellen bst r17,encoder_b_bit bld r18,1 sts MaskSrg,r18 ;neues Bitmuster speichern ldi r16,0 ;Wert aus der Tabelle holen ldi zh,high(looktab<<1) ldi zl,low(looktab<<1) add zl,r18 adc zh,r16 lds r5,StepTime lds r6,StepTime+1 lpm r16,z tst r16 ;War ein Schritt? breq still ;keine Änderung ;Es ist ein Schritt erfolgt tst r6 ;Hohes Zeitbyte !=0 brne eins ;ganz Lange mov r17,r5 ;Zeit seit letztem Schritt cpi r17,6 ;Schrittgröße festlegen brcc eins cpi r17,2 brcc zehn ldi r17,16 rjmp stepsize zehn: ldi r17,4 rjmp stepsize eins: ldi r17,1 stepsize: tst r16 ;Hoch oder runter? brmi runter ;hoch clr r16 ;Schritt zum Akku addieren add r2,r17 adc r3,r16 mov r16,r3 ;Bereichsprüfung cpi r16,64 brcs schrittfertig ldi r16,255 ;Maximum überschritten mov r2,r16 ldi r16,63 mov r3,r16 rjmp schrittfertig ;fertig runter: clr r16 ;Schritt vom Akku subtrahieren sub r2,r17 sbc r3,r16 brcc schrittfertig clr r2 ;Minimum unterschritten clr r3 rjmp schrittfertig ;fertig schrittfertig: clr r5 ;Pausentimer nullen sts StepTime,r5 sts StepTime+1,r5 rjmp nichtrunter still: ;StepTime hochzählen ldi r16,1 add r5,r16 ldi r16,0 adc r6,r16 brcs still1 sts StepTime,r5 sts StepTime+1,r6 still1: mov r16,r5 cpi r16,0 brne nichtrunter mov r16,r6 cpi r16,5 brne nichtrunter ; Es sind genau 5 Sekunden vergangen ; also Einstellungen sichern!!! rcall i2c_start ldi r16,0x0a0 rcall i2c_wrbyte ldi r16,0 rcall i2c_wrbyte mov r16,Volt0 andi r16,0b11111100 rcall i2c_wrbyte mov r16,Volt1 rcall i2c_wrbyte mov r16,Amper0 andi r16,0b11111100 rcall i2c_wrbyte mov r16,Amper1 rcall i2c_wrbyte mov r16,BitFlag rcall i2c_wrbyte rcall i2c_stop nichtrunter: ;Spannung oder Strom speichern? sbrc BitFlag,1 rjmp StoreAmper mov Volt0,r2 mov Volt1,r3 rjmp StoreVolt StoreAmper: mov Amper0,r2 mov Amper1,r3 StoreVolt: ;Drucktaster auswerten lds r16,PressTime sbis taster_pin,taster_bit rjmp pressed ; Taster ist losgelassen, war er gedrückt? cpi r16,10 brcs release ;zu kurz cpi r16,100 brcs TastKurz ;lange gedrückt ldi r16,1 eor BitFlag,r16 rjmp release TastKurz: ldi r16,2 eor BitFlag,r16 release: clr r16 sts PressTime,r16 rjmp notpressed pressed: ;Taste gedrückt-> Zeit hochzählen inc r16 sts PressTime,r16 notpressed: ;Jetzt die Auswertung mov r0,volt0 mov r1,volt1 lsr r1 ror r0 lsr r1 ror r0 rcall ldez_V sbrs BitFlag,0 rjmp VoltOn clr r0 clr r1 VoltOn: sts ocr1ah,r1 sts ocr1al,r0 mov r0,amper0 mov r1,amper1 lsr r1 ror r0 lsr r1 ror r0 sbrs BitFlag,0 rjmp AmpOn clr r0 clr r1 AmpOn: sts ocr1bh,r1 sts ocr1bl,r0 ;#################################### ;ADU einlesen lds r16,ADCSRA sbrc r16,ADSC ; wenn der ADC fertig ist, wird dieses Bit gelöscht rjmp wait_adc ; Wandlung noch nicht abgeschlossen ; ADC einlesen: lds r16,ADCL lds r17,ADCH ; danach das mittlerweile gesperrte High Byte add adubuf0,r16 ; Messwert aufaddieren adc adubuf1,r17 inc aducount ldi r16,64 cp aducount,r16 brne adc_next lsr adubuf1 ror adubuf0 lsr adubuf1 ror adubuf0 lsr adubuf1 ror adubuf0 lsr adubuf1 ror adubuf0 ;Nächsten Kanal lds r16,admux ldi r17,1 eor r16,r17 sts admux,r16 sbrc r16,0 rjmp StoreVolt1 sts AmperIst,adubuf0 sts AmperIst+1,adubuf1 rjmp StoreAmper1 StoreVolt1: sts VoltIst,adubuf0 sts VoltIst+1,adubuf1 StoreAmper1: clr adubuf0 clr adubuf1 clr aducount adc_next: ; den ADC starten durch setzen des adsc-bits ldi r16,(1<