-         

+ Antworten
Ergebnis 1 bis 10 von 10

Thema: Zwei AD im Hintergrund.

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.09.2005
    Beiträge
    276

    Zwei AD im Hintergrund.

    Anzeige

    Bis vor 12 Wochen konnte ich kein Bascom und nun stehe ich vor einem kleinen Problem/Aufgabe?

    Ich schrieb sonst für die C-Control Main Unit 2.0 in Basic ++ , aber durch Lieferprobleme der CC ,schwang ich auf Mega 32 um und habe auch Pingleiche Module entwickelt.

    Erstmal Auszug des Codes:
    Code:
    $regfile = "m32def.dat"
    '$framesize = 32
    '$swstack = 32
    '$hwstack = 32
    
    $crystal = 16000000
    $baud = 9600
    
    
    Config Lcd = 20 * 2
    
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.6 , Rs = Portb.5
    
    Config Adc = Single , Prescaler = 32 , Reference = Avcc     'Prescaler = Auto '32'
    
    
    Declare Sub Ad_wandlertest()
    
    Const A_ad = 0
    Const B_ad = 1
    
    Dim A As Word
    Dim B As Word
    
    '-------------------------------------------------------------------------------
      Initlcd
      Cls
      Waitms 100
      Start Adc
    '-------------------------------------------------------------------------------
    Do
      Call AD_wandlertest()                                    
      Locate 1,1 
      LCD "A : ",A
      Locate 2,1
      LCD "B : ",B
    Loop
    '---------------------------------------------------------------------------------
    Sub Ad_wandlertest()
      A = Getadc(x_ad)
      B = Getadc(y_ad)
    End Sub
    '----------------------------------------------------------------------------------
    Das ist nur ein Auszug von z.Z. ca 16 K.

    Nun meine Frage :
    Kann ich im Hintergrund die AD's einlesen lassen ohne Call und in A,B schreiben lassen?

    Das jenes per IRQ geht ist mir klar, bei einem.
    Aber zwei im Hintergrung?

    Erspare ich mir viele CPU Takte AD abwarten damit ..... ?

    könnte bitte jemand dahingehend den Code editieren ?

    lg Gento

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    18.08.2005
    Ort
    Steiermark
    Alter
    44
    Beiträge
    12
    Hallo Gento,

    auf den ersten Blick: Um Prozessortakte und Speicherplatz zu sparen, lass die Sub-Programme weg. Hab jetzt keine Zeit, um darauf näher einzugehen, man möge mir verzeihen. Ach ja, was macht die Laserei? In Deinen Code sehe ich "x_ad" und "y_ad", also sieht doch sehr nach Laser aus. Erzähle doch genau Dein Vorhaben und Deine (Echt)Zeitanforderung, dann kann Dir sicher besser geholfen werden.

    Gruß
    Günter (ich kenne Dich nicht persönlich, bin aber auch ein Laserfreak)

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    30.04.2004
    Ort
    Gronau
    Beiträge
    155
    @Gento,

    Du könntest einen Timer-IRQ laufen lassen, der bspw. jede
    Sekunde aufgerufen wird und dann die ADC's ausliest oder
    besser noch nur ein Bit-Flag setzt, welches Du dann in Deiner
    Main-Loop auswertest (Flag gesetzt = ADC's auslesen).
    Gruß: - Reinhard -

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.09.2005
    Beiträge
    276
    Ich hatte eher im Bereich 0,1 milli Sek gedacht die paare einlesen.

    @RHS

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.09.2004
    Ort
    Düsseldorf
    Beiträge
    3.948
    Du kannst die ADC's manuell bedienen.
    also über ihre Regtister und per IRQ dann einlesen.

    Das hat den Vorteil daß das Programm nicht groß warten muß da ja erst am Ende des Wandlungsvorganges die beiden Registerpaare kurz übertragen werden.

    sieht nach mehr Code aus aber ist unterm Strich nur etwas Tipparbeit
    Gruß
    Ratber

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    30.04.2004
    Ort
    Gronau
    Beiträge
    155
    @Gento,

    mit der Sekunde war ja nur ein Beispiel.

    Letztendlich bestimmt ja auch Dein sonstiges Programm,
    wie lange Du Zeit hast. Allerdings sind 0,1 ms = 100 µs
    schon ziemlich häufig, so das Du Dich am besten an Ratber's
    Vorschlag orientierst um Wartezeiten möglichst zu minimieren.
    Gruß: - Reinhard -

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.09.2004
    Ort
    Düsseldorf
    Beiträge
    3.948
    Ja,da bin ich mir auch nicht sicher gewesen ob er "Alle 100µS Einlesen" oder "Innerhalb von 100µS Einlesen" meint.


    Bei ersterem macht sich die Zeitersparnis natürlich stark bemerkbar da je jeder Takt zählt.
    Gruß
    Ratber

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.09.2005
    Beiträge
    276
    Precaler 32 = 0,105 mSek für je eine a + b AD-Wandlung

    Das habe ich ermittelt wenn ich Call AD_wandlertest() ständig nur aufrufe.
    Die Werte sind sehr Constant dabei.

    Frage a) Kann ich die AD im Hintergrund laufen lassen ohne das er zuviel CPU Takte verbraucht. 2-5 K je Sekunde würden auch reichen.

    Frage b) Da ich noch nicht lange Bascom mache könnte jemand ein Beispiel mit 2 AD im Hintergrund einlesen texten ?

    Danke
    &
    Gruß Gento

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.09.2004
    Ort
    Düsseldorf
    Beiträge
    3.948
    Zu "A":

    Der AD-Wandler arbeitet im Grunde eh die meiste Zeit im Hintergrund.
    Er bekommt seinen takt,der aus dem Systemtakt abgeleitet wird, und wandelt eigentständig.

    Nur für den Start der Wandlung und das ablesen des Ergebnisses muß man zugreifen.

    Bascom würde mit Getadc natürklich schön brav warten bis er fertig ist.
    Wenn due dazu noch mit "Single Conversion" arbeitest dann dauerts so ziemlich am längsten da Bascom von anfang bis ende der Conversion wartet.

    Wie gesagt kannst du es besser machen indem du ihn rechtzeitig startest (Conversionsbit im Steureregister setzen) und dir dann irgendwann das Ergebnis aus beiden Registern ausliest.
    Dazwischen kann deine Soft machen was se will.

    Um es nochmal zu verdeutlichen:

    Du = Meister mit 2 Aufgaben.
    1. Beleuchtungsstärke im Raum Messen.
    2. Protokollieren der Werte.
    Dir zur Seite steht ein Lehrling der das Luxmeter in der Hand hält.

    Methode 1. (Bascom standard mit Getadc):
    ===========================
    1u haust den Azubi an "Messwert bitte".
    2:Er schaut nach
    3:Er sagt dir den Wert.
    4u schreibst auf
    5: Goto 1

    Wärend Punkt 2 mußt du warten bis er gemessen hat.

    Methode 2. (Verfeinert)
    ==================
    Der Azubi misst ständig neu und sagt auch immer den Wert an.
    Dein Programm verkürzt sich auf .

    1: Du kannst sofort den letzten Wert aufschreiben den der Azubi genannt hat.
    2: Goto 1



    Ich hoffe mal das war deutlicher.




    Zu "B" :

    Das Thema hatten wir schonmal vor einigen Monaten und da war auch ein schönes Beispiel dabei.
    Such mal danach hier in "Programierung in Bascom"

    Wenn de nix findest dann muß ich das mal raussuchen.
    Gruß
    Ratber

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.12.2004
    Alter
    63
    Beiträge
    277
    Hallöchen,

    also direkt über die Register zu gehen, ist natürlich möglich und auch ganz hübsch und man hat die höchstmögliche Kontrolle, allerdings auch nicht flotter als Bascom im FREE Modus:

    Code:
    '$regfile = "m8def.dat"
    $regfile = "m168def.dat"
    '$regfile = "m32def.dat"
    $crystal = 7372800
    '$crystal = 14745600
    '$crystal = 16000000
    
    $baud = 9600
    
    $hwstack = 64
    $swstack = 64
    $framesize = 64
    
    $lib "mcsbyteint.lbx"
    Config Adc = Free , Prescaler = Auto
    Config Pind.3 = Output
    
    Dim Value0 As Word
    Dim Value1 As Word
    '-------------------------------------------------------------------------------
    nop
    nop
    nop
    nop
    nop
    Start Adc
    
    Do
    Set Portd.3                                  'ggf. für Oszi-überwachung
    Value0 = Getadc(0)
    Value1 = Getadc(1)
    Reset Portd.3
    Loop
    nop
    nop
    nop
    nop
    End
    
    'Im FREE Modus (ADC triggert sich ständig selbst) ------------------------------
    '
    'kurz und knackig, allerdings werden u.U. Werte mehrmals gelesen...
    
    '+0000005a : 9170007a Lds R23 , 0x007a Load Direct From Data Space
    '+0000005C:   6870        ORI     R23,0x80         Logical OR with immediate
    '+0000005D:   9370007A    STS     0x007A,R23       Store direct to data space
    '
    '
    '+0000005F:   9A5B        SBI     0x0B,3           Set bit in I/O register
    '+00000060:   E080        LDI     R24,0x00         Load immediate
    '+00000061:   9380007C    STS     0x007C,R24       Store direct to data space
    '+00000063:   91800078    LDS     R24,0x0078       Load direct from data space
    '+00000065:   91900079    LDS     R25,0x0079       Load direct from data space
    '+00000067:   E0AF        LDI     R26,0x0F         Load immediate
    '+00000068:   E0B1        LDI     R27,0x01         Load immediate
    '+00000069:   938D        ST      X+,R24           Store indirect and postincr
    '+0000006A:   939C        ST      X,R25            Store indirect
    '+0000006B:   E081        LDI     R24,0x01         Load immediate
    '+0000006C:   9380007C    STS     0x007C,R24       Store direct to data space
    '+0000006E:   91800078    LDS     R24,0x0078       Load direct from data space
    '+00000070:   91900079    LDS     R25,0x0079       Load direct from data space
    '+00000072:   E1A1        LDI     R26,0x11         Load immediate
    '+00000073:   E0B1        LDI     R27,0x01         Load immediate
    '+00000074:   938D        ST      X+,R24           Store indirect and postincr
    '+00000075:   939C        ST      X,R25            Store indirect
    '+00000076:   985B        CBI     0x0B,3           Clear bit in I/O register
    '+00000077:   940C005F    JMP     0x0000005F       Jump
    
    
    
    'Im SINGLE Modus --------------------------------------------------------------
    'Hier wird's dann lang und umständlich, dafür ist aber das Ergebnis garantiert
    'richtig.
    
    
    '+0000005A:   9170007A    LDS     R23,0x007A       Load direct from data space
    '+0000005C:   6870        ORI     R23,0x80         Logical OR with immediate
    '+0000005D:   9370007A    STS     0x007A,R23       Store direct to data space
    '+0000005F:   9A5B        SBI     0x0B,3           Set bit in I/O register
    '+00000060:   E080        LDI     R24,0x00         Load immediate
    '+00000061:   9380007C    STS     0x007C,R24       Store direct to data space
    '+00000063:   940E0084    CALL    0x00000084       Call subroutine
    '+00000065:   E0AF        LDI     R26,0x0F         Load immediate
    '+00000066:   E0B1        LDI     R27,0x01         Load immediate
    '+00000067:   938D        ST      X+,R24           Store indirect and postincr
    '+00000068:   939C        ST      X,R25            Store indirect
    '+00000069:   E081        LDI     R24,0x01         Load immediate
    '+0000006A:   9380007C    STS     0x007C,R24       Store direct to data space
    '+0000006C:   940E0084    CALL    0x00000084       Call subroutine
    '+0000006E:   E1A1        LDI     R26,0x11         Load immediate
    '+0000006F:   E0B1        LDI     R27,0x01         Load immediate
    '+00000070:   938D        ST      X+,R24           Store indirect and postincr
    '+00000071:   939C        ST      X,R25            Store indirect
    '+00000072:   985B        CBI     0x0B,3           Clear bit in I/O register
    '+00000073:   940C005F    JMP     0x0000005F       Jump
    '+00000075:   0000        NOP                      No operation
    '+00000076:   0000        NOP                      No operation
    '+00000077:   0000        NOP                      No operation
    '+00000078:   0000        NOP                      No operation
    '+00000079:   94F8        CLI                      Global Interrupt Disable
    '+0000007A:   CFFF        RJMP    PC-0x0000        Relative jump
    '+0000007B:   9731        SBIW    R30,0x01         Subtract immediate from word
    '+0000007C:   F7F1        BRNE    PC-0x01          Branch if not equal
    '+0000007D:   9508        RET                      Subroutine return
    '+0000007E:   9468        SET                      Set T in SREG
    '+0000007F:   F862        BLD     R6,2             Bit load from T to register
    '+00000080:   9508        RET                      Subroutine return
    '+00000081:   94E8        CLT                      Clear T in SREG
    '+00000082:   F862        BLD     R6,2             Bit load from T to register
    '+00000083:   9508        RET                      Subroutine return
    '+00000084:   9180007A    LDS     R24,0x007A       Load direct from data space
    '+00000086:   6C80        ORI     R24,0xC0         Logical OR with immediate
    '+00000087:   9380007A    STS     0x007A,R24       Store direct to data space
    '+00000089:   9180007A    LDS     R24,0x007A       Load direct from data space
    '+0000008B:   FD86        SBRC    R24,6            Skip if bit in register clear
    '+0000008C:   CFFC        RJMP    PC-0x0003        Relative jump
    '+0000008D:   91800078    LDS     R24,0x0078       Load direct from data space
    '+0000008F:   91900079    LDS     R25,0x0079       Load direct from data space
    '+00000091:   9508        RET                      Subroutine return
    '+00000092:   0078        ???                      Data or unknown opcode
    '+00000093:   91900079    LDS     R25,0x0079       Load direct from data space
    '+00000095:   9508        RET                      Subroutine return
    An den NOPS bitte nicht stören, die sind nur drin, damit ich die richtige Stelle im Disassembler schnell finde.

    Kommt man mit 8 Bit Auflösung aus, kann das nochmal deutlich flotter werden (Leftadjust wählen und nur ADCH auslesen). Im FREE-Modus kommt man auf max ~ 15kHz Abtastrate, mit 8Bit pi mal Daumen auf max. ~ 22 kHz.

    Grüße
    Henrik

+ Antworten

Berechtigungen

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