Xmega256A3U ADC im Freerunn Mode

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Xmega256A3U ADC im Freerunn Mode

      Nachdem ich mein Winterprojekt wieder aufgenommen habe, stehe ich aktuell beim Xmega-ADC an und komme auf keinen "grünen Zweig"!
      Grundsätzlich hat alles im Singlemode bereits soweit funktioniert, ich möchte aber meine Messungen im Freerunn-Mode durch Interrupts ausgelöst realisieren.

      Leider ist die Situation aktuell so, daß ich keinen Sample-Durchlauf hinbekomme, da der Interrupt erst gar nicht ausgelöst wird.
      Ich muß 16 Kanäle samplen - hab das aber mal auf ADCA_CH0 beschränkt. Seltsamerweise sehe ich im Simulator in der oberen Auswahlspalte zwar alle möglichen INT vom Xmega aber keinen für ADC_A.
      Der INT vom ADC_B hingegen ist sichtbar, lässt sich aber auch nicht simulieren wenn ich den jeweiligen INT drücke. Der INT von PORT_C (Taster) funktioniert einwandfrei sowohl im SIM als auch in "Real".

      Gibt es irgendwelche Bugs im SIM bezüglich Xmega ADC oder sehe ich den Wald vor lauter Bäume nicht?
      Was passt im Code nicht, daß der ADC-Interrupt nicht kommt?
      Für Anregungen wäre ich sehr dankbar

      Vielen Dank
      LG Walter

      Xmega_ADC_SIM01.jpg

      Source Code

      1. $regfile = "xm256a3def.dat"
      2. $crystal = 16000000 ' oscillator 16MHz
      3. $hwstack = 100 ' für Interrupt-Handler+Gosub
      4. $swstack = 100 ' für Gosub und Variablen
      5. $framesize = 100 ' Wertübergabe von Variablen
      6. $prog &HFF , &HFF , &H00 , &HFF , &H00 , &HFF , &HFF ' Jtag disabled.
      7. 'include the following lib and code, the routines will be replaced since they are a workaround
      8. $lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014
      9. 'first enable the osc of your choice
      10. Config Osc = Disabled , Pllosc = Disabled , Extosc = Enabled , Range = 12mhz_16mhz , Startup = Xtal_256clk , 32khzosc = Disabled , 32mhzosc = Disabled '16MHz
      11. 'configure the systemclock
      12. Config Sysclock = External , Prescalea = 1 , Prescalebc = 1_1 '16MHz
      13. 'Config Interrupts
      14. Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = Enabled 'Enable Lo, Mid und Hi Level Interrupts
      15. Config Com4 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'Portd.6 and Portd.7 an COM4 beim Xmega
      16. Open "COM4:" For Binary As #1
      17. '
      18. '
      19. '
      20. 'ADC-Config für Zellenmessung-------------------------------------------------------------------------------------
      21. '-----------------------------------------------------------------------------------------------------------------
      22. Dim Calibration_word As Word
      23. Dim Calibration_word1 As Word
      24. Dim Adca_byte_0 As Byte At Calibration_word Overlay
      25. Dim Adca_byte_1 As Byte At Calibration_word + 1 Overlay
      26. Dim Adcb_byte_0 As Byte At Calibration_word1 Overlay
      27. Dim Adcb_byte_1 As Byte At Calibration_word1 + 1 Overlay
      28. 'First we read the Calibration bytes form Signature Row (to get the real 12-Bit)
      29. Adca_byte_0 = Readsig(&H20)
      30. Adca_byte_1 = Readsig(&H21)
      31. Adcb_byte_0 = Readsig(&H24)
      32. Adcb_byte_1 = Readsig(&H25)
      33. 'Write factory calibration values to calibration register
      34. Adca_call = Adca_byte_0
      35. Adca_calh = Adca_byte_1
      36. Adcb_call = Adcb_byte_0
      37. Adcb_calh = Adcb_byte_1
      38. Config Porta = Input ' ADCA für Zellenmessung
      39. Config Portb = Input ' ADCB für Zellenmessung
      40. Portcfg_mpcmask = &B11111111 'nachfolgende PINCTRL gilt für alle Pins von PORTA
      41. Porta_pin0ctrl = &B00_000_111 'Digital Input Buffer Disabled for ADC-PortA,
      42. Portcfg_mpcmask = &B11111111 'nachfolgende PINCTRL gilt für alle Pins von PORTB
      43. Portb_pin0ctrl = &B00_000_111 'Digital Input Buffer Disabled for ADC-PortB,
      44. '
      Display All
    • Source Code

      1. 'TASTE4 für ABBRUCH-----------------------------------------------------------------------------------------------
      2. '-----------------------------------------------------------------------------------------------------------------
      3. Config Portc.1 = Input
      4. Portc_pin1ctrl = &B00_011_010 'Pullup für Taste4. Sense on Falling Edge
      5. Portc_int0mask = &B00000010 'PortC1 soll als Interrupt(INT0) dienen
      6. Taste4 Alias Pinc.1 'Taste4 als Input
      7. '
      8. 'Variablen allgemein für ADC-Messung------------------------------------------------------------------------------
      9. '-----------------------------------------------------------------------------------------------------------------
      10. Const Sample_count = 266
      11. Dim Adca_channel_0(sample_count) As Word
      12. Dim Adca_channel_0_sample_count As Word
      13. '
      14. 'Variablen für ADC-Einzelmessung----------------------------------------------------------------------------------
      15. '-----------------------------------------------------------------------------------------------------------------
      16. Dim Adc_einzelzelle(16) As Word
      17. Dim Einzelzelle(16) As Dword
      18. Dim Einzelzell(16) As Word
      19. Dim Einzelz(16) As Single
      20. '
      21. 'Variablen diverse------------------------------------------------------------------------------------------------
      22. '-----------------------------------------------------------------------------------------------------------------
      23. Dim Zelle As Byte
      24. Dim Programmabbruch As Bit '
      25. '
      26. '
      27. 'Interrupt für Programmabbruch Taste4-----------------------------------------------------------------------------
      28. '-----------------------------------------------------------------------------------------------------------------
      29. On Portc_int0 Portc_int0_isr 'Taste4, Portc.1 für Interrupt
      30. Enable Portc_int0 , Hi 'Enable this Interrupt as Hi Level Interrupt
      31. '
      32. 'Interrupt für Adc_A+B -------------------------------------------------------------------------------------------
      33. '-----------------------------------------------------------------------------------------------------------------
      34. On Adca_ch0 Adca_channel_0_ready
      35. Enable Adca_ch0 , Lo
      36. Enable Interrupts
      37. '
      38. '--------------------------- H A U P T P R O G R A M M B E G I N N --------------------------
      39. '-----------------------------------------------------------------------------------------------------------------
      40. '--------------------------- H A U P T P R O G R A M M B E G I N N --------------------------
      41. Do
      42. If Programmabbruch = 1 Then
      43. Goto Ende
      44. End If
      45. Gosub Einzelzellenmessung
      46. Loop
      47. '--------------------------- H A U P T P R O G R A M M E N D E --------------------------------
      48. '-----------------------------------------------------------------------------------------------------------------
      49. '--------------------------- H A U P T P R O G R A M M E N D E --------------------------------
      50. '
      51. '-----------------------------------------------------------------------------------------------------------------
      52. 'SUB_EINZELZELLENMESSUNG------------------------------------------------------------------------------------------
      53. '-----------------------------------------------------------------------------------------------------------------
      54. Einzelzellenmessung:
      55. 'Setup the ADC-A Converter
      56. Config Adca = Free , Convmode = Unsigned , Resolution = 12bit , Dma = Off , _
      57. Reference = Intvcc , Event_mode = None , Prescaler = 32 , Sweep = Ch0 , _
      58. Ch0_gain = 1 , Ch0_inp = Single_ended , _
      59. Ch1_gain = 1 , Ch1_inp = Single_ended , _
      60. Ch2_gain = 1 , Ch2_inp = Single_ended , _
      61. Ch3_gain = 1 , Ch3_inp = Single_ended
      62. ' Nach Start des ADC müssen 24 Taktzyklen für Settlement gewartet werden!!
      63. ' Eingang 0-3 auf PORT A den MUX-Channels zuweisen
      64. Adca_ch0_muxctrl = &B0_0000_000
      65. Do
      66. !nop 'Config Powermode = Idle
      67. Loop Until Adca_channel_0_sample_count = 1 'Loop bis alle 4 Channels ausgelesen
      68. 'Disable ADC A
      69. Reset Adca_ctrla.0
      70. 'Disable ADC B
      71. Reset Adcb_ctrla.0
      72. For Zelle = 10 To 15
      73. Einzelzelle(1) = Adca_channel_0(zelle) + Einzelzelle(1)
      74. Next
      75. Zelle = 0
      76. For Zelle = 0 To 4 'ADC-A+B
      77. Einzelzelle(zelle + 1) = Einzelzelle(zelle + 1) / 256 'Mittelwert
      78. Einzelz(zelle + 1) = Einzelzelle(zelle + 1)
      79. Next
      80. Zelle = 1
      81. For Zelle = 1 To 16 ' Aufsummierten Wert der Einzelzellen löschen
      82. Einzelzelle(zelle) = 0
      83. Next
      84. Return
      85. '
      86. '-----------------------------------------------------------------------------------------------------------------
      87. 'SUB_PROGRAMMABBRUCH----------------------------------------------------------------------------------------------
      88. '-----------------------------------------------------------------------------------------------------------------
      89. Ende:
      90. Print #1 , "-------------------------------------------------------"
      91. Print #1 , "-------------PROGRAMM-ABBRUCH-----------------"
      92. Print #1 , "-------------------------------------------------------"
      93. Set Portf.4
      94. Set Portf.5
      95. Set Portf.6
      96. Reset Tcd0_ctrlb.4
      97. Reset Tcd0_ctrlb.5
      98. Reset Tcd0_ctrlb.6
      99. Programmabbruch = 0
      100. End 'end program
      101. '
      102. '-----------------------------------------------------------------------------------------------------------------
      103. 'SUB_Interrupt_Programmabbruch------------------------------------------------------------------------------------
      104. '-----------------------------------------------------------------------------------------------------------------
      105. Portc_int0_isr:
      106. Programmabbruch = 1
      107. Return
      108. '
      109. '-----------------------------------------------------------------------------------------------------------------
      110. 'ADC_Interrupt_Service_Routine------------------------------------------------------------------------------------
      111. '-----------------------------------------------------------------------------------------------------------------
      112. 'ADCA_Channel 0 conversion complete INTERRUPT SERVICE ROUTINE
      113. Adca_channel_0_ready:
      114. Incr Adca_channel_0_sample_count
      115. Adca_channel_0(adca_channel_0_sample_count) = Adca_ch0_res
      116. Set Adca_intflags.0 'Clear Int Flag CH 0
      117. Return
      Display All
      ich versuche jetzt den Rest vom Code einzufügen wegen den 10000 Zeichen ?(
    • Der zweite Beitrag mit dem Code ist als Zusatz zum ersten Beitrag zu verstehen, da ich die Fehlermeldung mit den 10000 Zeichen bekommen habe - offensichtlich waren es zuviele Codezeilen!
      Mittlerweile habe ich beim Array "Dim Adca_channel_0_sample_count As Byte" gesetzt - jetzt bekomme ich zumindest einen Wert.
      Verstehe aber nicht warum das Word-Format mit dem gleichen Wert wie das Byte-Format nicht funktioniert - das Array hat eine Größe von 266 mit nur einem Sampledurchlauf - das ist natürlich nur für diesen Test so gesetzt, hat sonst mit einem Durchlauf nur mäßig Sinn!
    • hast du nur im Simulator oder mit der Hardware getestet? Ich meide i.A den Simulator.
      Am besten testet man mit einem Atmel ICE, falls man hat. Geht auch mit einem dragon. Ohne sowas hätte ich mit den Xmegas nix hingekriegt.
      Edit: Man muss auch mit Fehlern im dat-file rechnen (hab vor 2 Jahren intensiv mit den Xmegas gearbeitet, jetzt läuft alles).

      The post was edited 1 time, last by elektron ().

    • Im A3Bu dat file waren damals Fehler bzgl. der ADCs. Ich habe mir deshalb ein neues dat-file kreiert (eigentlich sollte das aktuelle dat-file inzwischen funktionieren. Aber wer weiss....

      Hier meine Conf ADCa Zeile:
      Config Adca = Free , Convmode = Signed , Resolution = 12bit , Dma = Ch01 , _
      Reference = Int1v , Prescaler = 32 , Sweep = Ch0 , Event_mode = None , Event_channel = Ch0123 , _
      Ch0_gain = 1 , Ch0_inp = Diffwgain , Mux0 = &H33 ' &B0011_1010 ' &H33 '33=0011_0011 '&B0110_011=x33 diff w gain: adc7 neg=Pin7, pos=ADC6=Pin6

      Ich hatte auch immer wieder die Free-Version von CodevisionAVR zurate gezogen (die funktioniert), und den Programm-Output mit dem von Bascom mittels des In-Circuit-Emulators (ICE) verglichen.

      Übrigens: In Atmelstudio7 (leider ein Dino) gibt's auch einen Simulator, der ohne die Xmega-Hardware läuft.
    • @Michael: Ok, soweit klar - wenns ein größerer Codeschnipsel ist, dann mit Anhang - Danke :)
      @Elektron:
      Ich hab jetzt in meiner Bascom-Version 2.0.7.8 alle xm256xxdef.dats probiert - es fehlt bei den Interrupts im SIM immer das PORTA.
      Leider steht mir keine ICE zur Verfügung, hab nur einen Programmer avrisp mk2!
      Ich mache ja schon seit einer gefühlten Ewigkeit die ADC-Tests für das Sampling von 16 Kanälen, was sich als ziemliche Herausforderung darstellt, da ich beide ADC's benötige und das Sampling auch in einer Zeit <100ms erledigt sein soll, damit in meiner Programmschleife noch ein vernünftiges Display-Update möglich ist.
      Ich hatte auch schon einen relativ stabilen Code im ADC-Singlemode, was aber durch das herkömmliche Werteauslesen und in Arrays packen zeitmäßig grenzwertig ist.

      Bei den unzähligen Versuchen ist mir aber generell aufgefallen, daß die Genauigkeit etwas zu Wünschen übrig läßt,wenn man den einzelnen Kanälen nicht genug Zeit für das Samplen und Konvertieren gibt. Mit den entsprechenden "Waitus" Pausen bekomme ich zwar die Genauigkeit und Ruhe in der Anzeige hin, doch es kostet eben Zeit. Deswegen die Entscheidung Freerunn!
      Habe jetzt auch noch die DMA-Variante dazugenommen, was noch mal neue Baustellen aufgerissen hat :rolleyes:
      Im Moment bekomme ich zwar Werte, die aber nicht stabil sind, kontinuierlich steigen, bei jedem ADC-Start auch divergieren - kurzum Müll! Vermutlich spießt sich die ADC-Ausgabe und das Einlesen ins RAM. Um aber konkrete Fragen stellen zu können muß ich das noch genauer analysieren!

      Vorerst mal Danke!
    • walter_wi wrote:

      Bei den unzähligen Versuchen ist mir aber generell aufgefallen, daß die Genauigkeit etwas zu Wünschen übrig läßt,wenn man den einzelnen Kanälen nicht genug Zeit für das Samplen und Konvertieren gibt.
      Mit Clock=38MHz ist's stabil mit Prescaler = 32.

      Du musst auch den ADC-Eingang ganz niederohmig beschalten. Ich habe glaube ich 1-2K zwischen die Differenzeingänge gelegt (sonst gegen GND).

      Hier meine DMA-Routine:
      Vor jeder DMA-Transaction muss man Config DMA aufzurufen. Sonst geht's nur einmal.
      Im Atmel Studio7 ist wie gesagt ein funktionierender Simulator drin. Man muss das Bascom obj File (glaube dass es so war) im Studio laden.

      Ansonsten schau mal im Bascom Code-Explorer bei den Registervariablen nach, ob da alle angezeigt werden. Alle heisst mit pdf-file vergleichen.
      Ich bin mir ziemlich sicher, dass zumindest bis zu 2.0.7.8er Zeiten noch einige ADC- (kann aber auch DAC gewesen sein) Register im dat file fehlten.

      BASCOM Source Code

      1. Bitwait Aca_status.0 , Set 'AC0 IntFlag
      2. Config Dmach0 = Enabled , Burstlen = 2 , Chanrpt = Enabled , Tci = Hi , Eil = Lo , Singleshot = Enabled , _
      3. Sar = Burst , Sam = Inc , Dar = None , Dam = Inc , Trigger = &H10 , Btc = Sample_countx2 , Repeat = 1 , Sadr = Varptr(adca_ch0_res) , Dadr = Varptr(samples(1))
      4. Set Adca_ctrla.0 'enable adc
      5. Aca_status.0 = 1 'Clear AC0 IntFlag
      6. Bitwait Dma_intflags.0 , Set 'Channel 0 Transaction Interrupt Flag
      7. Set Dma_intflags.0 'Clear the Channel 0 Transaction Complete flag
      8. Reset Adca_ctrla.0
      9. Set Adca_ctrla.1 'flush
      10. Reset Adca_ctrla.0
      Display All