Sparrow/T13 Oszilloskop

Die folgende Anwendung stellt ein einfaches Oszilloskop dar. Die berechtigte Frage ist nun: Woher kommt der freie Port für die Spannungsmessung? Das Nokia Display verfügt über 5 Steuerleitungen (LCD_RESET, LCD_DC, LCD_SDIN, LCD_SCLK, LCD_SCE). LCD_SCE (Chip Select) kann eingespart werden (dauerhaft auf GND legen) und somit wird ein Port frei für die Spannungsmessung per ADC. Auch die Resetleitung könnte eingespart werden (dauerhaft auf VCC legen) allerdings kam es dabei zu Problemen. Der Reset wird nicht immer sauber durchgeführt. Als Notlösung aber durchaus machbar.
Sparrow NF-Oszilloskop
NokiaLCD API für den Sparrow
Mit dem massiven Anstieg an Codezeilen habe ich mich endlich dazu entschlossen den verwendeten Code in mehrere Dateien bzw. APIs aufzuteilen. Bisher gibt es zwei dieser Dateien die sich mit den folgenden Versuchen weiterentwickeln dürfen:
math - mathematische Funktionen und einfachste Integer Arithmetik
nokiaLCD - eine API zur Ansteuerung des Nokia5110 LCD (PCD8544)
Der aktuelle Code soll zum Experimentieren einladen. Die Spannungsmessung und Darstellung auf dem Display ist nicht ausgelagert und kann so einfach editiert werden.
Messparameter ändern/anpassen (höhere Frequenzen)
Über das Register ADMUX lässt sich der Teiler für den ADC einstellen. Ist das alles noch immer zu langsam kann über die Fuses oder per Software der Clock-Teiler angepasst werden.
Und was genau passiert in den APIs?
Hierzu die Quellcodelistings zu den beiden Dateien "math" und "nokiaLCD".
;math and integer arithmetic

;shiftDiv [input r16, 17] [output r16]
shiftDiv:
        lsr     r16
        dec     r17
        brne    shiftDiv
        ret

;mod [input r16, r17] [output r16]
mod:
        sub     r16, r17
        brpl    mod
        add     r16, r17
        ret
;Nokia 5110 LCD API

;initLCD
initLCD:
    ldi r16, 0b00000000
    out PORTB, r16
    sbi DDRB, LCD_RESET
    sbi DDRB, LCD_DC
    sbi DDRB, LCD_SDIN
    sbi DDRB, LCD_SCLK
    sbi PORTB, LCD_RESET
    ldi r30, LOW(init_lcd*2)
    ldi r31, HIGH(init_lcd*2)
    ldi r19, 10
    rcall writeBytes
    sbi PORTB, LCD_DC
    ret

;writeBytes [input Offset r30:r31, lenght r19]
writeBytes:
    dec r19
    brmi writeBytes1
    lpm r16, Z+
    rcall writeByte
    rjmp writeBytes
writeBytes1:
    ret

;writeByte [input r16]
writeByte:
    ldi r17, 0x08
writeByte1:
    sbi PORTB, LCD_SDIN
    sbrs r16, 0x07
    cbi PORTB, LCD_SDIN
    sbi PORTB, LCD_SCLK
    cbi PORTB, LCD_SCLK
    lsl r16
    dec r17
    brne writeByte1
    ret

;init sequence
init_lcd:
.db 0x21, 0xD0, 0x04, 0x13, 0xBC, 0x20, 0x08, 0x0C
.db 0x80, 0x40


Links und Referenzen: