Grundsatzfrage zu AD-Wandler in Freerunnung Mode mit mehreren Kanälen

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

    • Den einzigen Fehler sehe ich bei 16Mhz 57k6 . Macht bei über 2000 Zeichen 0,05%. Damit könnte ich gut schlafen Irgendwann haut immer mal was dazwischen Da helfen selbst abgeglichene Präzisionsquarze nicht gegen.
      Mit 16Mhz macht er bei 57k5 2,1% bzw -0,8 % Fehler in der Ausgabe was der Empfänger ganz locker tollerieren sollte.
      Korr: Jetzt zähle ich vier Fehler. Vermutlich ist der Empfänger etwas langsam dann sollten 115k2 gut gehen.
    • RS232 wird pro Zeichen mit dem Startbit synchronisiert. Die max. tolerierte Abweichung in der Bitrate ergibt sich aus der Anzahl der Bits pro Zeichen (bei 8N1 10 Bit, Start-, Stop- und 8 Datenbits), beim letzten Bit muss die akkumulierte Abweichung < 50% sein, da die Bits in der Mitte abgetastet werden, also darf die Baudrate <5% variieren.
    • daher die Vermutung des "pigeligen" Empfängers.
      @Mitch ich hab Dein Asm versucht umzusetzten und die Baud auf 4800 gedrosselt .Jetzt sind die Fehler erträglich ohne das der Int gestoppt werden muß. Kanal 0 geht so auch:

      Source Code

      1. $regfile = "attiny13a.dat"
      2. $crystal = 9600000
      3. $hwstack = 8
      4. $swstack = 16
      5. $framesize = 16
      6. Config Base = 0
      7. Open "COMb.1:4800,8,n,1,inverted" For Output As #1
      8. Dim Ia As Byte ' , a As Byte
      9. Dim Temp0 As Word , Temp1 As Word , Temp2 As Word , Temp3 As Word , Tempw As Word
      10. 'Dim Wert0 As Word , Wert1 As Word , Wert2 As Word , Wert3 As Word
      11. 'Dim Templ As Byte At Tempw Overlay
      12. 'Dim Temph As Byte At Tempw + 1 Overlay
      13. Config Adc = Free , Prescaler = Auto , Reference = Avcc
      14. On Adc Adc_isr Nosave
      15. Enable Adc
      16. Enable Interrupts
      17. Do
      18. 'Disable Interrupts 'damit der SW-Uart keinen Quatsch ausgibt
      19. 'Wert0 = Temp0 : Wert1 = Temp1 : Wert2 = Temp2 : Wert3 = Temp3:
      20. Print #1 , "K0:" ; Temp0 ; ",K1:" ; Temp1 ; ",K2:" ; Temp2 ; ",K3:" ; Temp3 'Wert0 ; ",K1 " ; Wert1 ; ",K2, " ; Wert2 ; ",K3 " ; Wert3
      21. 'Enable Interrupts
      22. Waitms 100
      23. Loop
      24. End
      25. '(Adc_isr:
      26. Templ = Adcl
      27. Temph = Adch
      28. Select Case Ia
      29. Case Is = 0
      30. Temp3 = Tempw
      31. Case Is = 1
      32. Temp0 = Tempw
      33. Case Is = 2
      34. Temp1 = Tempw
      35. Case Is = 3
      36. Temp2 = Tempw
      37. End Select
      38. Incr Ia
      39. If Ia >= 4 Then Ia = 0
      40. Admux = Ia 'Ref=Vcc
      41. Return
      42. ')
      43. Adc_isr:
      44. !PUSH r16 ' verwendete Register sichern
      45. !IN r16,sreg
      46. !PUSH r16
      47. !PUSH r17
      48. !PUSH r24
      49. !PUSH r25
      50. !IN r24,ADCL ' ADC-Wert einlesen
      51. !IN r25,ADCH
      52. !LDS r16,{iA} ' Kanal-Nr lesen
      53. !CPI r16,0
      54. !BREQ ISR_ADC_0 ' Sprung bei Kanal=0
      55. !CPI r16,1
      56. !BREQ ISR_ADC_1 ' Sprung bei Kanal=1
      57. !CPI r16,2
      58. !BREQ ISR_ADC_2 ' Sprung bei Kanal=2
      59. !CPI r16,3
      60. !BREQ ISR_ADC_3 ' Sprung bei Kanal=3
      61. !RJMP ISR_ADC_EXIT
      62. Isr_adc_0: ' Kanal 0 lesen
      63. !STS {temp3 + 0},r24
      64. !STS {temp3 + 1},r25
      65. !RJMP ISR_ADC_EXIT
      66. Isr_adc_1: ' Kanal 1 lesen
      67. !STS {temp0 + 0},r24
      68. !STS {temp0 + 1},r25
      69. !RJMP ISR_ADC_EXIT
      70. !ISR_ADC_2: ' Kanal 2 lesen
      71. !STS {temp1 + 0},r24
      72. !STS {temp1 + 1},r25
      73. !RJMP ISR_ADC_EXIT
      74. Isr_adc_3: ' Kanal 3 lesen
      75. !STS {temp2 + 0},r24
      76. !STS {temp2 + 1},r25
      77. Isr_adc_exit:
      78. !INC r16 ' Kanal +1
      79. !CPI r16,4 ' Prüfen, ob letzter Kanal
      80. !SBIC SREG,1 ' Z-Flag
      81. !CLR r16 ' Kanal auf 0 setzen
      82. !STS {ia},r16
      83. !OUT ADMUX,r16
      84. !POP r25 ' verwendete Register wieder herstellen
      85. !POP r24
      86. !POP r17
      87. !POP r16
      88. !OUT SREG,r16
      89. !POP r16
      90. Return
      Display All
      Muß r17 gepusht werden?
    • Zitronenfalter wrote:

      Einfach die Dateiendung "LOG" mit "TXT" ersetzen
      Das habe ich ausprobiert und funktioniert gut. Danke für den Tip! Muss ich mir merken.


      Rudi Einstein wrote:

      dieses Tool benutze ich zur Ermittlung einer günstigen BAUDRATEN-QUARZFREQUENZ.
      Mit Bascom-Mitteln kann man die Fehlerrate auch ermitteln (Menü Optionen -> Compiler -> Kommunikation).
      Ist vielleicht nicht so schön wie mit dem Tool, aber ausreichend, um die Fehlerrate zu bestimmen.



      Pluto25 wrote:

      daher die Vermutung des "pigeligen" Empfängers.
      @Mitch ich hab Dein Asm versucht umzusetzten und die Baud auf 4800 gedrosselt .Jetzt sind die Fehler erträglich ohne das der Int gestoppt werden muß. Kanal 0 geht so auch:

      Source Code

      1. $regfile = "attiny13a.dat"
      2. $crystal = 9600000
      3. $hwstack = 8
      4. $swstack = 16
      5. $framesize = 16
      6. Config Base = 0
      7. Open "COMb.1:4800,8,n,1,inverted" For Output As #1
      8. Dim Ia As Byte ' , a As Byte
      9. Dim Temp0 As Word , Temp1 As Word , Temp2 As Word , Temp3 As Word , Tempw As Word
      10. 'Dim Wert0 As Word , Wert1 As Word , Wert2 As Word , Wert3 As Word
      11. 'Dim Templ As Byte At Tempw Overlay
      12. 'Dim Temph As Byte At Tempw + 1 Overlay
      13. Config Adc = Free , Prescaler = Auto , Reference = Avcc
      14. On Adc Adc_isr Nosave
      15. Enable Adc
      16. Enable Interrupts
      17. Do
      18. 'Disable Interrupts 'damit der SW-Uart keinen Quatsch ausgibt
      19. 'Wert0 = Temp0 : Wert1 = Temp1 : Wert2 = Temp2 : Wert3 = Temp3:
      20. Print #1 , "K0:" ; Temp0 ; ",K1:" ; Temp1 ; ",K2:" ; Temp2 ; ",K3:" ; Temp3 'Wert0 ; ",K1 " ; Wert1 ; ",K2, " ; Wert2 ; ",K3 " ; Wert3
      21. 'Enable Interrupts
      22. Waitms 100
      23. Loop
      24. End
      25. '(Adc_isr:
      26. Templ = Adcl
      27. Temph = Adch
      28. Select Case Ia
      29. Case Is = 0
      30. Temp3 = Tempw
      31. Case Is = 1
      32. Temp0 = Tempw
      33. Case Is = 2
      34. Temp1 = Tempw
      35. Case Is = 3
      36. Temp2 = Tempw
      37. End Select
      38. Incr Ia
      39. If Ia >= 4 Then Ia = 0
      40. Admux = Ia 'Ref=Vcc
      41. Return
      42. ')
      43. Adc_isr:
      44. !PUSH r16 ' verwendete Register sichern
      45. !IN r16,sreg
      46. !PUSH r16
      47. !PUSH r17
      48. !PUSH r24
      49. !PUSH r25
      50. !IN r24,ADCL ' ADC-Wert einlesen
      51. !IN r25,ADCH
      52. !LDS r16,{iA} ' Kanal-Nr lesen
      53. !CPI r16,0
      54. !BREQ ISR_ADC_0 ' Sprung bei Kanal=0
      55. !CPI r16,1
      56. !BREQ ISR_ADC_1 ' Sprung bei Kanal=1
      57. !CPI r16,2
      58. !BREQ ISR_ADC_2 ' Sprung bei Kanal=2
      59. !CPI r16,3
      60. !BREQ ISR_ADC_3 ' Sprung bei Kanal=3
      61. !RJMP ISR_ADC_EXIT
      62. Isr_adc_0: ' Kanal 0 lesen
      63. !STS {temp3 + 0},r24
      64. !STS {temp3 + 1},r25
      65. !RJMP ISR_ADC_EXIT
      66. Isr_adc_1: ' Kanal 1 lesen
      67. !STS {temp0 + 0},r24
      68. !STS {temp0 + 1},r25
      69. !RJMP ISR_ADC_EXIT
      70. !ISR_ADC_2: ' Kanal 2 lesen
      71. !STS {temp1 + 0},r24
      72. !STS {temp1 + 1},r25
      73. !RJMP ISR_ADC_EXIT
      74. Isr_adc_3: ' Kanal 3 lesen
      75. !STS {temp2 + 0},r24
      76. !STS {temp2 + 1},r25
      77. Isr_adc_exit:
      78. !INC r16 ' Kanal +1
      79. !CPI r16,4 ' Prüfen, ob letzter Kanal
      80. !SBIC SREG,1 ' Z-Flag
      81. !CLR r16 ' Kanal auf 0 setzen
      82. !STS {ia},r16
      83. !OUT ADMUX,r16
      84. !POP r25 ' verwendete Register wieder herstellen
      85. !POP r24
      86. !POP r17
      87. !POP r16
      88. !OUT SREG,r16
      89. !POP r16
      90. Return
      Display All
      Muß r17 gepusht werden?

      Hallo Pluto
      Mein letzter Post ist irgendwie nicht Online gegangen. Vielleicht vergessen abzusenden. Da hatte ich bereits Verbesserungen aufgelistet, die zum Ziel führten. Deine Variante ist aber auch schon beachtlich, wenn man bedenkt, dass du mit einem Software-Uart arbeitest.
      So, nun aber kurz zu meinen Verbesserungen
      1. Den offenen RxD habe ich mit einem PullUp versehen. das hat schon mal deutlich Verbesserung bei der Übertragung gebracht. Durch den offenen Eingang hat die Schnittstelle wohl sporadisch immer was eingefangen.
      2. Mit 16MHz Quarz konnte ich die Baudrate nach Änderung (Punkt 1) bis auf 38400 Baud fehlerfrei hochfahren. Bei 57600 Baud gab es dann wieder erste Fehler. (Siehe Logfiles "38400_16MHz" und "57600_16MHz").
      3. Habe dann das Quarz so gewählt, dass die Fehlertoleranz rechnerisch bei 0% liegt. Mit dem nun verwendeten Quarz von 14,7456MHz konnte ich die Baudrate nochmals fehlerfrei auf 57600 Baud steigern. Bringt also in jedem Fall auch was. Zu sehen im Logfile "57600_14.7456"
      Die Baudrate 115200 war wieder Fehlerbehaftet. Ging also nicht mehr.

      Ziel war es aber auch nicht, einen (fehlerfreien) Datenstream per serieller Schnittstelle mit maximaler Baudrate zu erzeugen, der parallel zur Datenerfassung läuft. Vielmehr ging es um den Freerun-Mode.

      Als Anwendung denke ich da eher an Signalaufzeichnung über kurze Dauer (1-2 Sekunden) und dann die Daten weiter zu geben.

      Noch eine Anmerkung zur Fehlerrate.
      Das serielle Signal wird Empfänger seitig üblicherweise mit der 16-fachen Frequenz abgetastet als die Baudrate. D.h. es gibt bei einem Bit bis zu 16 Werte. Ob der Wert dann als 0 oder 1 interpretiert wird entscheidet die Menge übereinstimmender Bits. Sind es mehr Einsen, ist es 1 sind es überwiegend Nullen, ist es 0.

      Eine Fehlerrate von 50% wird vielleicht noch bei einzelnen Zeichen funktionieren. Aber z.B. Zeichenketten mit mehreren Bytes (10 oder 20 Byte) direkt ohne Pause hintereinander weg werden dann nicht mehr gehen.

      Meiner Erfahrung nach sollte man daher bei höheren Baudraten immer ein Quarz nehmen und bei sehr hohen Baudraten oder größeren Datenpaketen sogar auf eins gehen mit möglichst 0% Fehler. Je länger die Übertragung (in Zeichen), desto wichtiger ist es die die Frequenz genau einzuhalten.
      Files
      Kaum macht man es richtig - und schon geht's!