; ********************************************************************* ; ATmega8 FM-Radio mit LM7001, 7-Segment, EEPROM ; ********************************************************************* .include "m8def.inc" ; ========================= ; === Pin-Definitionen ==== ; ========================= .equ LM_EN = PORTD5 ; Enable LM7001 .equ LM_SIN = PORTD3 ; Data .equ LM_SCK = PORTD4 ; Clock .equ SIN = PORTD3 ; Shift SIN .equ SCK = PORTD4 ; Shift SCK .equ RCK = PORTD6 ; Shift Latch .equ ZIFA = PORTD0 ; 74LS139 A0 .equ ZIFB = PORTD1 ; 74LS139 A1 ; Tasten .equ BTN_UP = PINB0 .equ BTN_DOWN = PINB1 .equ BTN_SAVE = PINB2 ; ========================= ; === Register ============ ; ========================= .def freqL = r24 .def freqH = r25 .def XH = r26 .def XL = r27 .def YH = r28 .def YL = r29 .def ZH = r30 .def ZL = r31 .def temp = r16 .def temp2 = r17 .def dig0 = r20 .def dig1 = r21 .def dig2 = r22 .def dig3 = r23 ; ========================= ; === Reset-Vektor ======== ; ========================= .cseg .org 0x0000 rjmp RESET ; ========================= ; === 7-Segment Tabelle === ; ========================= SEG_TABLE: .db 0b00111111 ; 0 .db 0b00000110 ; 1 .db 0b01011011 ; 2 .db 0b01001111 ; 3 .db 0b01100110 ; 4 .db 0b01101101 ; 5 .db 0b01111101 ; 6 .db 0b00000111 ; 7 .db 0b01111111 ; 8 .db 0b01101111 ; 9 ; ========================= ; === RESET =============== ; ========================= RESET: ; Stack ldi temp, low(RAMEND) out SPL, temp ; Ports ldi temp, 0xFF out DDRD, temp ldi temp, 0x00 out DDRB, temp ; Tasten als Input ; EEPROM lesen rcall EEPROM_Read ; Wenn EEPROM leer ? 100 MHz cpi freqL, 0xFF breq Set_Default rjmp MAIN_LOOP Set_Default: ldi freqL, low(1000) ; 100.0 MHz ldi freqH, high(1000) ; ========================= ; === Main Loop =========== ; ========================= MAIN_LOOP: ; Tasten prüfen sbis PINB, BTN_UP rcall Up sbis PINB, BTN_DOWN rcall Down sbis PINB, BTN_SAVE rcall EEPROM_Write ; Frequenz zum LM7001 rcall LM7001_SEND ; Umrechnung & BCD rcall Umrechnung ; Anzeige rcall Display rjmp MAIN_LOOP ; ========================= ; === Up/Down ============ ; ========================= Up: subi freqL, low(-1) sbci freqH, high(-1) ret Down: subi freqL, 1 sbci freqH, 0 ret ; ========================= ; === EEPROM ============== ; ========================= EEPROM_Read: ldi temp, 0 out EEARL, temp out EEARH, temp sbi EECR, EERE in freqL, EEDR ldi temp, 1 out EEARL, temp sbi EECR, EERE in freqH, EEDR ret EEPROM_Write: ; Byte 0 ldi temp, 0 out EEARL, temp out EEDR, freqL sbi EECR, EEMWE sbi EECR, EEWE ; Byte 1 ldi temp, 1 out EEARL, temp out EEDR, freqH sbi EECR, EEMWE sbi EECR, EEWE ret ; ========================= ; === LM7001 senden ======= ; ========================= LM7001_SEND: sbi PORTD, LM_EN mov temp, freqL rcall ShiftOut mov temp, freqH rcall ShiftOut ldi temp, 128 rcall ShiftOut cbi PORTD, LM_EN ret ShiftOut: ldi temp2, 8 ShiftOutLoop: rol temp brcs SOne cbi PORTD, LM_SIN rjmp SClk SOne: sbi PORTD, LM_SIN SClk: sbi PORTD, LM_SCK cbi PORTD, LM_SCK dec temp2 brne ShiftOutLoop ret ; ========================= ; === Umrechnung ========== ; ========================= Umrechnung: ; Beispiel: ADC-Wert simuliert mit freqL:H ; ? Hier eigene Skalierung (z.B. wie dein Beispiel) ; Kopiere freqL:H ? X mov XL, freqL mov XH, freqH ; Simpler Dummy: Frequenz direkt ? 4 Ziffern ; Echte Umrechnung siehe dein Algorithmus ; Einer rcall Div10 mov dig0, XL ; Zehner mov XL, XH clr XH rcall Div10 mov dig1, XL ; Hunderter mov XL, XH clr XH rcall Div10 mov dig2, XL ; Tausender mov dig3, XH ret Div10: ldi temp, 10 clr temp2 Div10_Loop: cp XL, temp brlo Div10_Done sub XL, temp inc temp2 rjmp Div10_Loop Div10_Done: mov XH, temp2 ret ; ========================= ; === Anzeige ============= ; ========================= Display: ; Dig3 (ZIFA=0,ZIFB=0) cbi PORTD, ZIFA cbi PORTD, ZIFB mov temp, dig3 rcall ShowDigit ; Dig2 (ZIFA=1,ZIFB=0) sbi PORTD, ZIFA cbi PORTD, ZIFB mov temp, dig2 rcall ShowDigit ; Dig1 (ZIFA=0,ZIFB=1) cbi PORTD, ZIFA sbi PORTD, ZIFB mov temp, dig1 rcall ShowDigit ; Dig0 (ZIFA=1,ZIFB=1) sbi PORTD, ZIFA sbi PORTD, ZIFB mov temp, dig0 rcall ShowDigit ret ShowDigit: lsl temp ldi ZL, low(SEG_TABLE * 2) ldi ZH, high(SEG_TABLE * 2) add ZL, temp adc ZH, r1 lpm temp, Z ; Schiebe raus ldi temp2, 8 Shift_1: rol temp brcs Bit1 cbi PORTD, SIN rjmp BitClk Bit1: sbi PORTD, SIN BitClk: sbi PORTD, SCK cbi PORTD, SCK dec temp2 brne Shift_1 ; Latch sbi PORTD, RCK cbi PORTD, RCK ret ; ========================= ; === Ende ================ ; =========================