.NOLIST .INCLUDE "tn2313def.inc" ; Befehlsliste des ATMega328P .LIST .def temp1 = r16 .def temp2 = r19 .def temp3 = r20 .def temp4 = r17 .def PROGW = r21 .def epdata = r22 .def zero = r18 .def freqL = r23 ; niederwertige 8 Bit der Frequenz vom LM7001 .def freqH = r24 ; höherwertige 8 Bit der Frequenz vom LM7001 .equ SCHIEBE_DDR = DDRD .equ SCHIEBE_PORT = PORTD .equ ZIFA = 0 .equ ZIFB = 1 .equ SIN = 3 .equ SCK = 4 .equ LME = 5 .equ RCK = 6 ; Konstanten .equ FREQ_MIN = 977 ; minimale Frequenz (87,5 + 10,7 MHz) .equ FREQ_MAX = 1187 ; maximale Frequenz (109 + 10,7 MHz) .equ FREQ_STEP = 1 ; Frequenz-Schrittweite (100 kHz) .equ EEPROM_ADRESSE = 0x00 ; Startadresse des Programmspeichers im EEPROM .DSEG .ORG 0X60 .CSEG .ORG $0000 rjmp Main ; Reset vector reti ; Int vector 1 nop reti ; Int vector 2 nop reti ; Int vector 3 nop reti ; Int vector 4 nop reti ; Int vector 5 nop reti ; Int vector 6 nop reti ; Int vector 7 nop reti ; Int vector 8 nop reti ; Int vector 9 nop reti ; Int vector 10 nop reti ; Int vector 11 nop reti ; Int vector 12 nop reti ; Int vector 13 nop reti ; Int vector 14 nop reti ; Int vector 15 nop reti ; Int vector 16 nop reti ; Int vector 17 nop reti ; Int vector 18 nop reti ; Int vector 19 nop reti ; Int vector 20 nop reti ; Int vector 21 nop reti ; Int vector 22 nop reti ; Int vector 23 nop reti ; Int vector 24 nop reti ; Int vector 25 nop main: ; Init stack ldi r16, RAMEND ; Init LSB stack out SPL,r16 ldi r16,0x00 ; AUSGANG Port B out DDRB,r16 ldi r16,0xff ; AUSGANG Port D out DDRD,r16 ; Überprüfe, ob EEPROM leer ist (z.B. 0xFF) cpi freqL, 0xFF breq eeprom_leer cpi freqH, 0xFF breq eeprom_leer rjmp loop ; EEPROM ist nicht leer eeprom_leer: ; Standardwert 87,5 MHz (entsprechend FREQ_MIN) in freqH:freqL laden ldi freqL, low(FREQ_MIN) ldi freqH, high(FREQ_MIN) ; Standardwert in EEPROM speichern in temp1, PINB andi temp1, 0xF0 mov ZL, temp1 mov ZH, temp1 mov R16, freqL rcall EEPROM_write inc ZL mov R16, freqH rcall EEPROM_write rjmp loop loop: sbis PINB, 0 rcall freq_down sbis PINB, 1 rcall freq_up sbis PINB, 2 rcall Sender_speichern rcall DISPLAY in temp1, PINB andi temp1, 0xF0 cp temp1, PROGW breq Sender_holen rjmp loop Sender_speichern: ; EEPROM-Nutzung ; Frequenz in freqH:freqL speichern ldi temp1, 255 rcall Schiebe rcall SchiebeOut sbis PINB, 2 rjmp Sender_speichern rcall WarteDIS mov ZL, temp1 mov ZH, temp1 mov PROGW, temp1 ; freqL schreiben mov R16, freqL rcall EEPROM_write ; freqH schreiben inc ZL ; Adresse für freqH mov R16, freqH rcall EEPROM_write ret Sender_holen: ; Frequenz lesen in temp1, PINB andi temp1, 0xF0 mov ZL, temp1 mov ZH, temp1 mov PROGW, temp1 rcall EEPROM_read mov freqL, R16 ; freqH lesen inc ZL ; Adresse für freqH rcall EEPROM_read mov freqH, R16 sbi SCHIEBE_PORT, LME mov temp1, freqL rcall Schiebe mov temp1, freqH rcall Schiebe cbi SCHIEBE_PORT, LME ret EEPROM_read: ; EEPROM-Leseroutine ; Adresse in ZL:ZH, Daten in R16 zurückgegeben ; Warten, bis das EEPROM bereit ist sbic EECR, EEWE rjmp EEPROM_read ; Adresse setzen out EEARL, ZL ; Lesen aktivieren sbi EECR, EERE ; Daten lesen in R16, EEDR ret EEPROM_write: ; EEPROM-Schreibroutine ; Adresse in ZL:ZH, Daten in R16 ; Warten, bis das EEPROM bereit ist sbic EECR, EEWE rjmp EEPROM_write ; Adresse setzen out EEARL, ZL ; Daten setzen out EEDR, R16 ; Schreiben aktivieren sbi EECR, EEMWE sbi EECR, EEWE ret ; Unterprogramm: Frequenz erhöhen freq_up: ; Frequenz um 100 kHz erhöhen ldi temp1, 255 rcall Schiebe rcall SchiebeOut sbis PINB, 1 rjmp freq_up rcall WarteDIS ldi r16, 100 add freqL, r16 ldi r16, 0 adc freqH, r16 ; Überprüfe, ob die Frequenz zu hoch ist ldi r16, low(FREQ_MAX) ldi r17, high(FREQ_MAX) cp freqL, r16 cpc freqH, r17 brlo freq_up_ok ; Frequenz auf FREQ_MAX setzen ldi freqL, low(FREQ_MAX) ldi freqH, high(FREQ_MAX) freq_up_ok: sbi SCHIEBE_PORT, LME mov temp1, freqL rcall Schiebe mov temp1, freqH rcall Schiebe ldi temp1, 0b1000000 rcall Schiebe cbi SCHIEBE_PORT, LME ret ; Unterprogramm: Frequenz erniedrigen freq_down: ; Warte, bis die Taste losgelassen wird freq_down_wait: ldi temp1, 255 rcall Schiebe rcall SchiebeOut sbis PINB, 0 rjmp freq_down_wait rcall WarteDIS ; Frequenz erniedrigen ldi r16, 100 sub freqL, r16 ldi r16, 0 sbc freqH, r16 ; Überprüfe, ob die Frequenz zu niedrig ist cpi freqH, high(FREQ_MIN) brsh freq_down_ok cpi freqL, low(FREQ_MIN) brsh freq_down_ok ; Frequenz auf FREQ_MIN setzen ldi freqL, low(FREQ_MIN) ldi freqH, high(FREQ_MIN) freq_down_ok: sbi SCHIEBE_PORT, LME mov temp1, freqL rcall Schiebe mov temp1, freqH rcall Schiebe rcall Schiebe ldi temp1, 0b1000000 cbi SCHIEBE_PORT, LME ret ; Frequenzanzeige DISPLAY: ; Frequenz berechnen ldi temp3, 0 mov temp2, freqL subi temp2, 87 ; Hunderterstelle cpi temp2, 100 brlo display_zehner subi temp2, 100 inc temp3 display_zehner: ; Zehnerstelle ldi temp4, 0 mov temp1, temp2 rcall div_by_10 mov temp2, temp1 ; Hunderterstelle ldi temp1, 255 rcall Schiebe rcall SchiebeOut rcall WarteDIS sbi SCHIEBE_PORT, ZIFA cbi SCHIEBE_PORT, ZIFB ldi zl, low(digit_table) ldi zh, high(digit_table) add zl, temp3 adc zh, zero lpm temp1, z rcall Schiebe rcall SchiebeOut rcall WarteDIS ; Zehnerstelle ldi temp1, 255 rcall Schiebe rcall SchiebeOut rcall WarteDIS cbi SCHIEBE_PORT, ZIFA sbi SCHIEBE_PORT, ZIFB ldi zl, low(digit_table) ldi zh, high(digit_table) add zl, temp4 adc zh, zero lpm temp1, z rcall Schiebe rcall SchiebeOut rcall WarteDIS ; Einerstelle ldi temp1, 255 rcall Schiebe rcall SchiebeOut rcall WarteDIS sbi SCHIEBE_PORT, ZIFA sbi SCHIEBE_PORT, ZIFB ldi zl, low(digit_table) ldi zh, high(digit_table) add zl, temp2 adc zh, zero lpm temp1, z rcall Schiebe rcall SchiebeOut rcall WarteDIS div_by_10: ldi temp4, 0 div_loop: cpi temp1, 10 brlo div_end subi temp1, 10 inc temp4 rjmp div_loop div_end: ret ; Dezimalstelle ldi temp1, 255 rcall Schiebe rcall SchiebeOut rcall WarteDIS cbi SCHIEBE_PORT, ZIFA cbi SCHIEBE_PORT, ZIFB ldi temp1, 0b10000000 ; Dezimalpunkt rcall Schiebe rcall SchiebeOut rcall WarteDIS ret digit_table: .db 0b11000000, 0b11111001, 0b10100100, 0b10110000 .db 0b10011001, 0b10010010, 0b10000010, 0b11111000 .db 0b10000000, 0b10010000 ;----------------------------------------------------------------------------- ; ; Die Ausgabe im Schieberegister in das Ausgaberegister übernehmen ; ; Dazu am RCK Eingang am Schieberegister einen 0-1-0 Puls erzeugen ; SchiebeOut: sbi SCHIEBE_PORT, RCK cbi SCHIEBE_PORT, RCK ret ;----------------------------------------------------------------------------- ; ; 8 Bits aus temp1 an das Schieberegister ausgeben Schiebe: push temp2 ldi temp2, 8 ; 8 Bits müssen ausgegeben werden Schiebe_1: ; ; jeweils das höchstwertige Bit aus temp1 ins Carry-Flag schieben ; Je nach Zustand des Carry-Flags wird die Datenleitung entsprechend ; gesetzt oder gelöscht ; rol temp1 ; MSB -> Carry brcs Schiebe_One ; Carry gesetzt? -> weiter bei Schiebe_One cbi SCHIEBE_PORT, SIN ; Eine 0 ausgeben rjmp Schiebe_Clock ; und Sprung zur Clock Puls Generierung Schiebe_One: sbi SCHIEBE_PORT, SIN ; Eine 1 ausgeben ; ; einen Impuls an SCK zur Übernahme des Bits nachschieben ; Schiebe_Clock: sbi SCHIEBE_PORT, SCK ; Clock-Ausgang auf 1 ... cbi SCHIEBE_PORT, SCK ; und wieder zurück auf 0 dec temp2 ; Anzahl der ausgegebenen Bits runterzählen brne Schiebe_1 ; Wenn noch keine 8 Bits ausgegeben -> Schleife bilden pop temp2 ret WarteDIS: ldi R16, $1F WGLOOP0: ldi R17, $AB WGLOOP1: dec R17 brne WGLOOP1 dec R16 brne WGLOOP0 ldi R16, $01 WGLOOP2: dec R16 brne WGLOOP2 ret STBY: ldi R16, $24 WGLOOPA: ldi R17, $BC WGLOOPB: ldi R18, $C4 WGLOOPC: dec R18 brne WGLOOPC dec R17 brne WGLOOPB dec R16 brne WGLOOPA ldi R16, $01 WGLOOPD: dec R16 brne WGLOOPD ret