- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 10

Thema: Analogport auslesen, und Wert ausgeben (seriell)

  1. #1

    Analogport auslesen, und Wert ausgeben (seriell)

    Anzeige

    Praxistest und DIY Projekte
    Hallo allerseits,

    habe gerade ein einfaches Programm entworfen, das das Analogsignal (wird über poti auf Pin C 0 [Atmega8 ADC0] 0-5V) eingelesen. Es soll nach beendigung der ADC-Conversion also nach auslösen des Interrupts, über die Serielle Schnittstelle ausgegeben werden. Leider kommt nur Gullasch am Hyperterminal an. Denke ich habe irgendeinen Denkfehler drin, da das Gullasch sich beim Drehen des Potis verändert.

    Achtung: Das ich ADLAR gesetzt habe war nur ein Versuch, dachte mal schauen was passiert wenn er die bits auf die andere seite schiebt, das resultat war: Andere ASCII Zeichen am Hyperterminal die sich beim Drehen des Potis verändern.

    Hier der Code meines Programms:


    Code:
    .include "m8def.inc"
    
    // aus dem UARTprogramm
    .def temp = r16
    .equ CLOCK = 3686400
    .equ BAUD = 9600
    .equ UBRRVAL = CLOCK/(BAUD*16)-1
    
    
    // aus dem ADC-prog
    .def ad_value = r17
    .org 0x000
    
    	rjmp	init	;1   POWER ON RESET
    	reti		;2   Int0-Interrupt
    	reti		;3   Int1-Interrupt
    	reti		;4   TC2 Compare Match
    	reti		;5   TC2 Overflow
    	reti		;6   TC1 Capture
    	reti		;7   TC1 Compare Match A
    	reti		;8   TC1 Compare Match B
    	reti		;9   TC1 Overflow
    	reti		;10  TC0 Overflow
    	reti		;11  SPI, STC Serial Transfer Complete
    	reti		;12  UART Rx Complete
    	reti		;13  UART Data Register Empty
    	reti		;14  UART Tx Complete
    	rjmp ad_vector;15  ADC Conversion Complete
    	reti		;16  EEPROM Ready
    	reti		;17  Analog Comparator
    	reti		;18  TWI (I²C) Serial Interface
    	reti		;19  Store Program Memory Ready
    
    init:
            ; Stackpointer initialisieren
            ldi temp, LOW(RAMEND)
            out SPL, temp
            ldi temp, HIGH(RAMEND)
            out SPH, temp
    
            ; Baudrate einstellen
            ldi temp, LOW(UBRRVAL)
            out UBRRL, temp
            ldi temp, HIGH(UBRRVAL)
            out UBRRH, temp
    
            ; Frame-Format: 8 Bit
            ldi temp, (1<<URSEL)|(3<<UCSZ0)
            out UCSRC, temp
    
            sbi UCSRB,TXEN    ;TX aktivieren
    
    
    ;ADC initailisieren
    
    cbi ADMUX, MUX0
    cbi ADMUX, MUX1
    cbi ADMUX, MUX2
    cbi ADMUX, MUX3
    sbi ADMUX, ADLAR
    cbi ADMUX, REFS0
    cbi ADMUX, REFS1
    
    ;ADC interrupt anschalten
    
    sbi ADCSR, ADIE
    
    ;Prescaler auf 16 setzen
    
    cbi ADCSR,ADPS0
    cbi ADCSR,ADPS1
    cbi ADCSR,ADPS2
    
    ;AD Converter anschalten
    
    sbi ADCSR,ADEN
    
    ;global interrupts aktivieren
    
    sei
    
    ;erste Wandlung auslösen
    
    sbi ADCSR, ADSC
    
    ;Hauptprogramm
    
    main:
    nop
    nop
    nop
    
    
    rjmp main
    
    
    ad_vector:
    
    in temp,adch
    sbi adcsr,adsc
    sei
    rjmp serout
    ret
    
    
    
    serout:
            sbis UCSRA,UDRE                   ; Warten bis UDR für das nächste
                                              ; Byte bereit ist
            rjmp serout
            out UDR, temp
            ret                               ; zurück zum Hauptprogramm

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    O weh,
    mal abgesehen, von der Art, wie Du Deine ADC_ready routine betrittst und verläßt und der Art, wie Du den ADC Wert ausließt fällt mir auf, daß Du den adch Wert direkt an den UART schickst( na ja über den temp)
    Das geht aber nicht so, wenn Du die Werte im Terminal ablesen willst.
    Du mußt den Wert ja noch irgendwie nach ASCII umrechnen, irgendwo habe ich schon Beispiele dafür hier gepostet, mal sehen, ob ich die noch finde.

    Gruß Sebastian

    Edit:

    schau mal hier mein Post von 7 Uhr 17 alles was unter berechne: steht, wandelt Dir eine 16 Bit Zahl in ASCII Kodierte Zahlen um.

  3. #3

    Danke für die Tips

    Danke für die Tips, hab mir so was in der Art schon gedacht.
    Wie meinst du das, mit der Routine und mit dem Übergeben, wie mach ich das besser? Bin noch total am Anfang und kann gute Tips immer brauchen.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Naja,

    1. Man soll beim betreten der ISR den SREG sichern.
    2. Beim verlassen wiederherstellen, weißt Du überhaupt wann sie verlassen wird?
    3. ADC Auslesen ADCL und ADCH sollen beide ausgelesen werden, auch wenn Du den Wert der in ADCL steht eventuell nicht brauchst.
    4. Der Sprung aus der ISR nach serout:, das kann man irgendwie eleganter machen...
    überleg mal, Du schaltest die Interrupts wieder ein, dann springst Du nach serout:, die Rücksprungadresse von dem Interrupt liegt aber noch auf dem Stack, je nachdem wie lange serout: braucht tritt eventuell ein neuer Interrupt, obwohl, der alte noch nicht abgearbeitet ist, also wieder Rücksprungadresse auf den Stack, und so weiter, irgendwann knallt es, und die Bits laufen aus dem AVR auf die Platine raus.

    Schau Dir mein Programm an, ich will nicht sagen, daß ich es perfekt geschrieben habe, aber so ist es mal schöner, also im Interrupt, ein Flag setzen, daß die Wandlung fertig ist, in der Hauptschleife, regelmäßig den Flag überprüfen, und wenn gesetzt, dann Ausgabe über den UART(davor noch was umrechnen) und zum Schluß den Flag wieder löschen.

    Hier in Forum haben wir mal ein riesen Thread gemacht hmmm, such mal nach Assembler für anfänger, oder so, da sind paar brauchbare Sachen drin.

    wenn noch was unklar ist, dann einfach fragen.

    Gruß Sebastian

  5. #5
    Das mit dem Serout ist mir klar, das kann man leicht besser lösen.
    Ich habe jetzt mal, aus purer Faulheit heraus, anstatt mit Hyperterm mit diesem Programm gearbeitet:

    HTerm 0.6.1 beta, das zeigt Binär, ASCII, HEX und Dezimal an, ist echt geschickt und man spart sich die Umwandlung, so lange man sie nicht braucht.

    1. Man soll beim betreten der ISR den SREG sichern.
    2. Beim verlassen wiederherstellen, weißt Du überhaupt wann sie verlassen wird?
    3. ADC Auslesen ADCL und ADCH sollen beide ausgelesen werden, auch wenn Du den Wert der in ADCL steht eventuell nicht brauchst.

    Zu 1 und 2, das kannst du mir gerne mal näher erleutern, davon habe ich keine Ahnung.
    Zu 3. Hab mir mal gerade das Datenblatt zur Hand genommen, daraus bin ich jetzt nicht wirklich schlau geworden.

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    HTerm 0.6.1 beta, das zeigt Binär, ASCII, HEX und Dezimal an
    Ja das ist natürlich die einfachste Lösung.

    Zu 1 und 2, das kannst du mir gerne mal näher erleutern, davon habe ich keine Ahnung.
    Was möchtest Du erklärt haben? Warum sichern, oder wie sichern, oder die Bedeutung von SREG ?

    schau Dir diese
    Seite an... da haben wir so das eine oder andere zu SREG geschrieben.

    When an ADC conversion is complete, the result is found in these two registers. If differential
    channels are used, the result is presented in two’s complement form.
    When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently,
    if the result is left adjusted and no more than 8-bit precision is required, it is
    sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.
    Das meinte ich, wobei bei ADLAR ist es wieder mal egal...

    Gruß Sebastian

  7. #7
    Also ich lese davor einfach ADCL aus, ob ich das brauche oder nicht, scheint ja egal zu sein. Sollte es aber machen, da er sonst keine neue Wandlung startet.

    Ich hab mal ne kleine frage: Wie kann ich realisieren das eine LED an einem bestimmtem Punkt an geht. bzw bei 100. Es gibt zwar größer kleiner befehle aber die beziehen sich meines erachtens nur auf die verschiedenen Flags, oder sehe ich das falsch?!...

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Ja Flags des SREG Registers.

    z.B.

    2 Register z.B. R16 R17

    cp R17,R16
    brcs machwas
    sonst:
    ...
    ...
    machwas:

    Es wird nach machwas gesprungen, wenn Carrybit gesetzt ist, sonst wird weiter unter sonst: gemacht, Carry ist dann gesetzt, wenn R16 größer als R17 ist.

    Ich empfehle Dir AVR Studio, und kleine Spielchen mit cp cpi cpc sub add inc dec, dabei den SREG beobachten...

    Gruß Sebastian

  9. #9
    Danke, das hat mir geholfen. Jetzt hab ich die Befehle verstanden. Wusste net das das Bit immer im SREG gesetzt wird, dann ist das ganze natürlich logisch.

    Wie lese ich die ADC-Ports am besten aus, wenn ich mehrere benutzen will?! .....

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Schonmal was von ADMUX Register gehört ?

    Gruß Sebaastian

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen