Forum: Mikrocontroller und Digitale Elektronik ADC Programmierung beim Atmega88


von Gerold (Gast)


Lesenswert?

Hallo,

Ich möchte mich ein wenig mit dem Programmieren von AVR´s beschäftigen,
und habe dabei im - AVR-Tutorial: ADC -  ein Problem mit dem Listing.

Ich benutze das AVR Studio 4.13 und besitze den Atmega88.
Habe das Assemblerlisten zum Testen etwas eingekürzt.
Da das Programm für den Atmega8 bestimmt war habe ich
.include "m8def.inc" durch .include "m88def.inc" ersetzt.

Außerdem habe ich schon folgende Zeilen abgeändert,

    ldi     temp1, (1<<REFS0)                   ; Kanal 0, interne 
Referenzspannung 5V
    out     ADMUX, temp1
    ldi     temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
    out     ADCSRA, temp1

ersetzt durch diese
    ldi     temp1, (1<<REFS0)                   ; Kanal 0, interne 
Referenzspannung 5V
    sts     ADMUX, temp1      ;out
    ldi     temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
    sts     ADCSRA, temp1      ;out

Probleme habe ich noch bei folgenden Zeilen

; neuen ADC-Wert lesen  (Schleife - 256 mal)
sample_adc:
    sbi    ADCSRA, ADSC        ; den ADC starten
wait_adc:
    sbic    ADCSRA, ADSC        ; wenn der ADC fertig ist, wird dieses 
Bit gelöscht
    rjmp    wait_adc
;ADC einlesen:
    in      adlow, ADCL         ; immer zuerst LOW Byte lesen
    in      adhigh, ADCH        ; danach das mittlerweile gesperrte High 
Byte
    rjmp sample_adc

Folgende Fehlermeldungen werden noch vom Programm angezeigt:

D:\Eigene Dateien\AVR Dateien\test4_adc\test4_adc.asm(35): error: 
Operand 1 out of range: 0x7a
D:\Eigene Dateien\AVR Dateien\test4_adc\test4_adc.asm(37): error: 
Operand 1 out of range: 0x7a
D:\Eigene Dateien\AVR Dateien\test4_adc\test4_adc.asm(40): error: 
Operand 2 out of range: 0x78
D:\Eigene Dateien\AVR Dateien\test4_adc\test4_adc.asm(41): error: 
Operand 2 out of range: 0x79


Meine Frage welche Befehle muß ich verwenden anstelle  - sbi , sbic , in 
-


Es wäre sehr nett wenn mir da da jemand ein Tip geben könnte.

Mfg Gerold



Das Listing:

.include "m88def.inc"

.def temp1     = r16         ; allgemeines temp Register, zur 
krufristigen Verwendung
.def temp2     = r17         ; Register für 24 Bit Addition, Lowest Byte
.def temp3     = r18         ; Register für 24 Bit Addition, Middle Byte
.def temp4     = r19         ; Register für 24 Bit Addition, Highest 
Byte
.def adlow     = r20         ; Ergebnis vom ADC / Mittelwert der 256 
Messungen
.def adhigh    = r21         ; Ergebnis vom ADC / Mittelwert der 256 
Messungen
.def messungen = r22         ; Schleifenzähler für die Messungen
.def ztausend  = r23         ; Zehntausenderstelle des ADC Wertes
.def tausend   = r24         ; Tausenderstelle des ADC Wertes
.def hundert   = r25         ; Hunderterstelle des ADC Wertes
.def zehner    = r26         ; Zehnerstelle des ADC Wertes
.def zeichen   = r27         ; Zeichen zur Ausgabe auf den UART
.equ F_CPU = 4000000                            ; Systemtakt in Hz
.equ BAUD  = 9600                               ; Baudrate
; hier geht das Programm los
    ldi     temp1, LOW(RAMEND)                  ; Stackpointer 
initialisieren

    out     SPL, temp1
    ldi     temp1, HIGH(RAMEND)
    out     SPH, temp1
; ADC initialisieren: Single Conversion, Vorteiler 128
    ldi     temp1, (1<<REFS0)                   ; Kanal 0, interne 
Referenzspannung 5V

    sts     ADMUX, temp1      ;out
    ldi     temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
    sts     ADCSRA, temp1      ;out

Main:
    clr     temp1
    clr     temp2
    clr     temp3
    clr     temp4
    ldi     messungen, 0        ; 256 Schleifendurchläufe
; neuen ADC-Wert lesen  (Schleife - 256 mal)
sample_adc:
    sbi    ADCSRA, ADSC        ; den ADC starten
wait_adc:
    sbic    ADCSRA, ADSC        ; wenn der ADC fertig ist, wird dieses 
Bit gelöscht
    rjmp    wait_adc
;ADC einlesen:
   in      adlow, ADCL         ; immer zuerst LOW Byte lesen
    in      adhigh, ADCH        ; danach das mittlerweile gesperrte High 
Byte
   rjmp sample_adc

von John S. (linux_80)


Lesenswert?

Hallo,

mit SBI kann man nur Register bis 0x1F ansprechen, beim Mega88 sind die 
ADC Register aber oberhalb davon, deshalb kommt man damit nicht mehr ran 
!
Genauso bei SBIC und IN. IN geht bis IO-Register 0x3F.

Man kann nur über die SRAM-Adresse darauf zugreifen.

von Gerold (Gast)


Lesenswert?

Hallo Tiny 80

Danke für deine Antwort

Hilft mir schon weiter.

Mfg Gerold

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.