Rs 232 Empfang ohne HW-Usart mit Int

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

    • Rs 232 Empfang ohne HW-Usart mit Int

      Hallo,
      nach vergeblichen Versuchen die Usi zum Empfang zu nutzen (zu lansam/aufwändig)) hier eine reine Software Lösung:

      Source Code

      1. $regfile = "attiny84.dat"
      2. $crystal = 8000000
      3. $hwstack = 64
      4. $swstack = 64
      5. $framesize = 64
      6. Config Base = 0
      7. '$sim
      8. Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Portb.1 , Rs = Portb.0
      9. Config Lcd = 16 * 2 'R/W pin muss auf Gnd liegen
      10. Initlcd
      11. Cursor Off Noblink
      12. Cls
      13. Dim Uinbuf(32) As Byte
      14. Dim Uinstr As String * 32 At Uinbuf Overlay
      15. Dim Uein As Byte , Uneu As Byte , Uwait As Byte , Uw2 As Byte
      16. Dim A As Byte
      17. 'Baud 256 128 115 57,6 56 38,2 28,8 19,2 14,4 9,6 4,8 2,4 1,2
      18. '8Mhz 6/2 15 17 37 38 57 77 117 157 238 - - -
      19. '4Mhz - 7/0 7 17 18 27 37 57 77 117 238 - -
      20. '2Mhz - U/Uw2 - 7 7 12 17 37 37 57 117 238 -
      21. '1Mhz - - - - - - 7 12 17 27 57 117 238
      22. Uwait = 238 '9600 Baud
      23. Uw2 = Uwait
      24. Dim Temp As Byte , Tempi As Integer , Tempw As Word , Tempstr As String * 6
      25. Dim Templ As Byte At Tempw Overlay
      26. Dim Temph As Byte At Tempw + 1 Overlay
      27. Uinstr = "Hallo, hier Tiny"
      28. On Pcint0 P_isr Nosave
      29. Pcmsk0 = $40 'Nur a.6
      30. Gimsk = $10 'Nur PCint0 (0-7)
      31. Ddra = $bf 'A6-RX =input
      32. Enable Interrupts
      33. 'Deflcdchar 0 , 32 , 14 , 17 , 17 , 32 , 17 , 17 , 14 'Zur 0 Byte darstellung
      34. Do
      35. Locate 1 , 1
      36. Lcd "Empfangen:"
      37. Lcd Uein
      38. Lcd " "
      39. Lowerline
      40. Lcd Uinstr
      41. If Uneu = 1 Then 'Zeile empfangen
      42. If Uein < 16 Then ' An Lcd anpassen
      43. For A = 0 To Uein
      44. Lcd Uinbuf(a)
      45. Next
      46. Do
      47. Lcd ""
      48. Incr A
      49. Loop Until A >= 16
      50. Uneu = 0
      51. Uein = 0
      52. Else
      53. For A = 0 To 15
      54. Lcd Uinbuf(a)
      55. Next
      56. End If
      57. Wait 2
      58. End If
      59. Loop
      60. End
      61. P_isr: '55 7µs / 2 nosave
      62. !Sbic pina,6 '2 if a.6=0 überspringe nächsten Befehl
      63. !jmp Ist1 ' gehe zum ende
      64. !PUSH r16 '2 verwendete Register sichern
      65. !IN r16,sreg '1
      66. !PUSH r16 '2
      67. !PUSH r17 '2 Uein
      68. !PUSH r24 '2 RxByte
      69. !PUSH r26 '2
      70. !PUSH r27 '2 # 17
      71. Gimsk = 0 '2 pcint stop
      72. !set '1 T=1 für Bitset r24
      73. !clr r24 '1 leeren da nur 1 gefüllt wird
      74. !lds r16,{Uw2} '2 #23 hole Uw2
      75. !ldi r17,255 '1
      76. Lop0:
      77. !inc r17 '1
      78. !cpse r16,r17 '1
      79. !jmp lop0 '2
      80. !Sbic pina,6 '2
      81. !bld r24,0 '1
      82. !lds r16,{Uwait}
      83. !ldi r17,255 '1
      84. Lop1:
      85. !inc r17 '1
      86. !cpse r16,r17 '1
      87. !jmp lop1 '2
      88. !Sbic pina,6 '2
      89. !bld r24,1 '1 #5/6 ub=0 10ub=1
      90. !ldi r17,255 '1
      91. Lop2:
      92. !inc r17 '1
      93. !cpse r16,r17 '1
      94. !jmp lop2 '2
      95. !Sbic pina,6 '2
      96. !bld r24,2 '1
      97. !ldi r17,255 '1
      98. Lop3:
      99. !inc r17 '1
      100. !cpse r16,r17 '1
      101. !jmp lop3 '2
      102. !Sbic pina,6 '2
      103. !bld r24,3 '1
      104. !ldi r17,255 '1
      105. Lop4:
      106. !inc r17 '1
      107. !cpse r16,r17 '1
      108. !jmp lop4 '2
      109. !Sbic pina,6 '2
      110. !bld r24,4 '1
      111. !ldi r17,255 '1
      112. Lop5:
      113. !inc r17 '1
      114. !cpse r16,r17 '1
      115. !jmp lop5 '2
      116. !Sbic pina,6 '2
      117. !bld r24,5 '1
      118. !ldi r17,255 '1
      119. Lop6:
      120. !inc r17 '1
      121. !cpse r16,r17 '1
      122. !jmp lop6 '2
      123. !Sbic pina,6 '2
      124. !bld r24,6 '1
      125. !ldi r17,255 '1
      126. Lop7:
      127. !inc r17 '1
      128. !cpse r16,r17 '1
      129. !jmp lop7 '2
      130. !Sbic pina,6 '2
      131. !bld r24,7 '1
      132. !lds r17,{uein} '2
      133. Loadadr Uinbuf , X '2 Array Adresse holen
      134. !add r26,r17 '1 index addieren
      135. !ST x,r24 '2 RxByte speichern
      136. !CPI r17,31 '1 Vergleiche mit 31
      137. !BRsh ISR_1 '2 Wenn >= zu Isr:1
      138. !inc r17 '1 incr r17 (Uein)
      139. !STS {uein},r17 '2
      140. Isr_1:
      141. !CPI r24,10 '1 lf empfangen?
      142. !BRne ISR_3 '2 wenn nicht weiter zu isr3
      143. !ldi r16,1 '1
      144. !STS {uneu},r16 '2 uneu=1
      145. Isr_3:
      146. Gimsk = $10 '2 'pcint frei
      147. !POP r27 ' verwendete Register wieder herstellen
      148. !POP r26
      149. !POP r24
      150. !POP r17
      151. !POP r16
      152. !OUT SREG,r16
      153. !POP r16
      154. Ist1: '# 10 wenn 1
      155. Return
      Display All
    • Hallo Pluto25,
      vielen Dank für das Einstellen dieses Codes.
      Allerdings versuche ich jetzt schon seit einiger Zeit, eine sinnvolle Anzeige zu bekommen.
      Funktioniert der Code bei dir so, wie er ist?
      Da ich keinen Tiny84 zur Hand habe, wollte ich einen M88p verwenden.
      Eigentlich muss ich also nur einige Stellen ändern, die Controller spezifisch sind.
      In der LCD Anzeige steht nach dem Senden einer 1<LF> auch Empfangen:2.
      In der zweiten Zeile wird das "Ha" von Hallo wird durch zwei Leerzeichen ersetzt.
      Kannst du dir das erklären?

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

    • Rx_rdy:

      U = Udr
      If Ring = 1 Then Print Chr(u);
      Inbuf(ein) = U
      Incr Ein
      #if _sim = 1
      If U = 13 Then
      #else
      If U = 10 Then
      Decr Ein
      #endif
      Neu = 1
      Decr Ein
      If Ring = 1 Then Print
      Else
      If Ein >= 31 Then Ein = 0
      End If
      Return
      Das Display kann nur Ascii (und 0) (ist auskommentiert), die anderen wie 1 oder 10=lf werden durch Leerzeichen oder "Hyoyglyohen" dargestellt.
      So funktionierte er. Ich hab ihn noch ein wenig verkleinert und das Uw2 herausgenimmen:

      Source Code

      1. $regfile = "attiny84.dat"
      2. $crystal = 8000000
      3. $hwstack = 64
      4. $swstack = 64
      5. $framesize = 64
      6. Config Base = 0
      7. '$sim
      8. Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Portb.1 , Rs = Portb.0
      9. Config Lcd = 16 * 2 'R/W pin muss auf Gnd liegen
      10. Initlcd
      11. Cursor Off Noblink
      12. Cls
      13. Dim Uinbuf(32) As Byte ',Dummy as byte (nötig falls uinstr <uinbuf)
      14. Dim Uinstr As String * 32 At Uinbuf Overlay
      15. Dim Uein As Byte , Uneu As Byte , Uwait As Byte , Uw2 As Byte
      16. Dim A As Byte
      17. Dim Bgut As Byte , B2gut As Byte
      18. 'Baud 256 128 115 57,6 56 38,2 28,8 19,2 14,4 9,6 4,8 2,4 -
      19. '8Mhz 5 14 16 36 37 56 76 116 156 237 - - -
      20. '4Mhz - 5 6 16 17 26 36 56 76 116 237 - -
      21. '2Mhz - - - 6 6 12 16 56 36 56 116 237 -
      22. '1Mhz - - - - - - 6 11 16 26 56 116 237
      23. Uwait = 237 '9600 Baud
      24. Dim Temp As Byte , Tempi As Integer , Tempw As Word , Tempstr As String * 6
      25. Dim Templ As Byte At Tempw Overlay
      26. Dim Temph As Byte At Tempw + 1 Overlay
      27. Uinstr = "Hallo, hier Tiny"
      28. On Pcint0 P_isr Nosave
      29. Pcmsk0 = $40 'Nur a.6
      30. Gimsk = $10 'Nur PCint0 (0-7)
      31. Ddra = $bf 'A6-RX =input
      32. Enable Interrupts
      33. 'Deflcdchar 0 , 32 , 14 , 17 , 17 , 32 , 17 , 17 , 14 'Zur 0 Byte darstellung
      34. Do
      35. Locate 1 , 1
      36. Lcd "Empfangen:"
      37. Lcd Uein
      38. Lcd " "
      39. Lowerline
      40. Lcd Uinstr
      41. If Uneu = 1 Then
      42. If Uein < 16 Then
      43. For A = 0 To Uein
      44. Lcd Uinbuf(a)
      45. Next
      46. Do
      47. Lcd ""
      48. Incr A
      49. Loop Until A >= 16
      50. Uneu = 0
      51. Uein = 0
      52. Else
      53. For A = 0 To 15
      54. Lcd Uinbuf(a)
      55. Next
      56. End If
      57. wait 2
      58. End If
      59. Loop
      60. End
      61. P_isr: '55 7µs / 2 nosave
      62. !Sbic pina,6 '2 if a.6=0 überspringe nächsten Befehl
      63. !jmp Ist1 ' gehe zum ende
      64. !PUSH r16 '2 verwendete Register sichern
      65. !IN r16,sreg '1
      66. !PUSH r16 '2
      67. !PUSH r17 '2 Uein
      68. !PUSH r24 '2 RxByte
      69. !PUSH r26 '2
      70. !PUSH r27 '2 # 17
      71. Gimsk = 0 '2 pcint stop
      72. !set '1 T=1 für Bitset r24
      73. !clr r24 '1 leeren da nur 1 gefüllt wird
      74. !lds r16,{Uwait} '2 hole Uwait
      75. !ldi r26,8 '1 #3
      76. Lopx:
      77. !LSr r24 '1
      78. !dec r26 '1
      79. !ldi r17,255 '1
      80. Lop0:
      81. !inc r17 '1
      82. !cpse r16,r17 '1 /2
      83. !jmp lop0 '2
      84. !Sbic pina,6 '2
      85. !bld r24,7 '1 #5/6 b=0 10b=1
      86. !cpi r26,0 '1
      87. !brne lopx '2/1 #10/11
      88. !lds r17,{uein} '2
      89. Loadadr Uinbuf , X '2 Array Adresse holen
      90. !add r26,r17 '1 index addieren
      91. !ST x,r24 '2 RxByte speichern
      92. !CPI r17,31 '1 Vergleiche mit 32
      93. !BRsh ISR_1 '2 Wenn >= zu Isr:1
      94. !inc r17 '1 incr r17 (Uein)
      95. !STS {uein},r17 '2
      96. Isr_1:
      97. !CPI r24,10 '1 lf empfangen?
      98. !BRne ISR_3 '2 wenn nicht weiter zu isr3
      99. !ldi r16,1 '1
      100. !STS {uneu},r16 '2 uneu=1
      101. !inc r26
      102. !clr r16
      103. !st x,r16 ' nullbyte für Uinstr
      104. Isr_3:
      105. Gimsk = $10 '2 'pcint frei
      106. !POP r27 ' verwendete Register wieder herstellen
      107. !POP r26
      108. !POP r24
      109. !POP r17
      110. !POP r16
      111. !OUT SREG,r16
      112. !POP r16
      113. Ist1: '# 10 wenn 1
      114. Return
      Display All
      Dieser hat noch keine längere Überprüfung hinter sich,ließ sich aber in allen Bereichen ansprechen.

      Nimmt er auch keine größeren Texte?


      PS Der M88 hat einen richtigen HW Uart da war das eine Bascom lösung:

      Rx_rdy:
      U = Udr
      If Ring = 1 Then Print Chr(u);
      Inbuf(ein) = U
      Incr Ein
      #if _sim = 1
      If U = 13 Then
      #else
      If U = 10 Then
      Decr Ein
      #endif
      Neu = 1
      Decr Ein
      If Ring = 1 Then Print
      Else
      If Ein >= 31 Then Ein = 0
      End If
      Return

      Ein zweites mal Code einfügen (</>) geht nicht??

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

    • Ist schon klar, dass der M88 das auch in HW könnte. Ich will es später in einen Tiny13A packen.

      Wenn ich den Text "test<LF>" eingebe, kommen kryptische Zeichen raus. Laut HD44780 Zeichentabelle die Hex Codes B4, A5, B3, B4.
      Ich habe dann mal einen Pin getoggelt direkt bevor der Eingangspin gelesen wird. Das sieht dann so aus:
      scan1.png
      Deutlich sieht man, dass der 8. Toggle nach dem 8.Bit kommt, also dort, wo das Stoipp-Bit ist.
      Und wenn man die Bits rückwärts abzählt passt das auch genau mit den Hex Codes überein.

      Wie kommst du eigentlich auf die 237 für 9600 Baud? Ich hätte jetzt so gedacht:
      8.000.000 / 9600 / 4 ~ 208, bei 4 Takten pro Schleifendurchlauf.
      Eigentlich müsstest du doch versuchen, auf die Mitte jedes Bits zu kommen. Dazu wäre am Anfang eine Schleife mit der halben Bit-Zeit nötig.
      Und danach jeweils die 208 oder vielleicht lieber 207 Zyklen, weil ja auch noch ein püaar andere Befehle ausgeführt werden.
      Sehe ich das richtig?

      Warum disablest du eigentlich den PCINT in der ISR? Da sind doch sowieso alle Ints abgeschaltet.
      Während der Abarbeitung des Bytes treten aber weitere Pagelwechsel auf, sodass das PCINT Flag gesetzt wird. Das solltest du vor verlasen der ISR löschen.

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

    • Guenther wrote:

      Und danach jeweils die 208 oder vielleicht lieber 207 Zyklen
      Den Gedanken hatte ich auch jedoch :
      Es gab dort je ca 40 Treffer Kombinationen die funktionierten. unter anderem auch eine wo Uwait=Ub2.
      Da jedes Byte neu syschonisiert wird schien es unwichtig die Mitte zu treffen. Selbst die 256k arbeiten mit 6/2 genauso wie mit 5/5 und dort hätte ich in jedem Fall Fehler erwachtet.
      Leider scheint die "calibrated RC Clock" nicht so calibratet zu sein
      Ich hab hier einen M8 mit 1Mhz der eine 25 anstelle 26 benötigt um 9600 zu verstehen