QiangLi matrix RGM Q6.6Eco + Atmega2560

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

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • QiangLi matrix RGM Q6.6Eco + Atmega2560

      Hello!
      On your forum I found code for controlling RGB matrices. Slightly redesigned to control the QiangLi Q6.6Eco matrices together with the Atmega2560 controller.
      Collected a scoreboard in which 12 matrices. 2x6.
      The problem is that the image does not appear immediately, but gradually. The image is gradually displayed from top to bottom. If I increase the value in the timer, the scoreboard starts flickering.
      How do I get information out instantly?
      Thank you in advance!

      Source Code

      1. $regfile = "m2560def.dat"
      2. $crystal = 16000000
      3. $hwstack = 80
      4. $swstack = 80
      5. $framesize = 80
      6. Const Scan = 6
      7. Const Row = 24
      8. Const Scan2 = 6
      9. Const Dy_num_h = 2
      10. Const Dy_num_v = 5
      11. Const Timer0reload = 48
      12. Config Timer0 = Timer , Prescale = 1024
      13. Load Timer0 , Timer0reload
      14. On Ovf0 Display_refresh
      15. Enable Ovf0
      16. Start Timer0
      17. 'PWM ************************************************** *************************
      18. Config Timer1 = Pwm , Pwm = 8 , Compare_b_pwm = Clear_down , Prescale = 1
      19. '************************************************* ******************************
      20. Const R_scan = Scan * Row
      21. Const Scan_1 = Scan * 2
      22. Const Scan_page = Scan - 1
      23. Const Bytes_in_row = Scan * Dy_num_h
      24. Const Row_num = Row * Dy_num_v
      25. Const Row_num1 = Row_num - 1
      26. Const Mem_size = Row_num * Bytes_in_row
      27. Const Mem_size_1 = Mem_size - 1
      28. Const Dy_offset = Dy_num_h * R_scan
      29. Const Channel_offset = Scan_1 * Bytes_in_row
      30. Const Mem_offset_1 = Scan * Bytes_in_row
      31. P_r1 Alias Porta.0 : Config P_r1 = Output
      32. P_g1 Alias Porta.1 : Config P_g1 = Output
      33. P_b1 Alias Porta.2 : Config P_b1 = Output
      34. P_r2 Alias Porta.3 : Config P_r2 = Output
      35. P_g2 Alias Porta.4 : Config P_g2 = Output
      36. P_b2 Alias Porta.5 : Config P_b2 = Output
      37. Dout_port Alias Porta
      38. Const Dout_pin_r1 = Pa0
      39. Const Dout_pin_g1 = Pa1
      40. Const Dout_pin_b1 = Pa2
      41. Const Dout_pin_r2 = Pa3
      42. Const Dout_pin_g2 = Pa4
      43. Const Dout_pin_b2 = Pa5
      44. P_a Alias Porte.5 : Config P_a = Output
      45. P_b Alias Porte.4 : Config P_b = Output
      46. P_c Alias Porte.3 : Config P_c = Output
      47. P_d Alias Portb.7 : Config P_d = Output
      48. P_ckl Alias Portc.6 : Config P_ckl = Output
      49. Shift_clock_port Alias Portc : Const Shift_clock_pin = Pc6
      50. P_lat Alias Porth.4 : Config P_lat = Output
      51. P_oe Alias Portb.6 : Config P_oe = Output
      52. '***
      53. Config Base = 0
      54. Declare Sub Shift6out(byreg R18 As Byte , Byreg R19 As Byte , Byreg R20 As Byte , Byreg R21 As Byte , Byreg R22 As Byte , Byreg R23 As Byte )
      55. Declare Sub Txt_6_8(byval X As Word , Byval Y As Word , Byval Color As Byte)
      56. Dim Memory_red(mem_size) , Memory_green(mem_size) , Memory_blue(mem_size) As Byte
      57. Dim Brightness , Red , Green , Blue , Yellow , Magenta , Cyan , White , Page_counter , Z_0 , Z_1 As Byte
      58. Red = 1 : Green = 2 : Yellow = 3 : Blue = 4 : Magenta = 5 : Cyan = 6 : White = 7
      59. Dim N_1 , Tab_start , Page_offset , B_1 , St_byte_1 , St_byte_2 , St_byte_3 , St_byte_4 As Word
      60. Dim Text As String * 50
      61. Dim F , S As Byte
      62. Enable Interrupts
      63. Gosub Clear_memory
      64. Brightness = 255
      65. Text = "1234567890ABCDEF"
      66. S = 1
      67. For F = 0 To 112 Step 8
      68. Call Txt_6_8(0 , F , S)
      69. S = S + 1
      70. If S = 8 Then S = 1
      71. Next
      72. Do
      73. Loop
      74. End
      75. Display_refresh:
      76. Load Timer0 , Timer0reload
      77. Incr Page_counter
      78. If Page_counter > Scan_page Then
      79. Page_counter = 0
      80. P_c = 1
      81. End If
      82. Page_offset = Page_counter * Bytes_in_row
      83. For Z_0 = 1 To Dy_num_v
      84. St_byte_1 = Mem_offset_1 + Page_offset : St_byte_2 = Page_offset
      85. St_byte_3 = St_byte_1 + Channel_offset : St_byte_4 = St_byte_2 + Channel_offset
      86. For Z_1 = 1 To Dy_num_h
      87. For B_1 = 1 To Scan2
      88. Shift6out Memory_red(st_byte_1) , Memory_green(st_byte_1) , Memory_blue(st_byte_1) , Memory_red(st_byte_3) , Memory_green(st_byte_3) , Memory_blue(st_byte_3)
      89. Incr St_byte_1 : Incr St_byte_3
      90. Next B_1
      91. For B_1 = 1 To Scan2
      92. Shift6out Memory_red(st_byte_2) , Memory_green(st_byte_2) , Memory_blue(st_byte_2) , Memory_red(st_byte_4) , Memory_green(st_byte_4) , Memory_blue(st_byte_4)
      93. Incr St_byte_2 : Incr St_byte_4
      94. Next B_1
      95. Next Z_1
      96. Page_offset = Page_offset + Dy_offset
      97. Next Z_0
      98. Pwm1b = 0
      99. Waitus 40
      100. P_lat = 1 : P_lat = 0
      101. P_a = 1 : P_a = 0
      102. P_c = 0
      103. Pwm1b = Brightness
      104. Return
      105. Sub Shift6out(byreg R18 As Byte , Byreg R19 As Byte , Byreg R20 As Byte , Byreg R21 As Byte , Byreg R22 As Byte , Byreg R23 As Byte)
      106. $asm
      107. LDI r17,8
      108. Loop_shift2out:
      109. in R16, dout_port
      110. BST r18,7
      111. BLD r16,Dout_pin_r1
      112. BST r19,7
      113. bld r16,Dout_pin_g1
      114. BST r20,7
      115. bld r16,Dout_pin_b1
      116. BST r21,7
      117. BLD r16,Dout_pin_r2
      118. BST r22,7
      119. bld r16,Dout_pin_g2
      120. BST r23,7
      121. bld r16,Dout_pin_b2
      122. LSl r18
      123. LSl r19
      124. lsl r20
      125. lsl r21
      126. lsl r22
      127. lsl r23
      128. Out Dout_port , R16
      129. SBI shift_clock_Port, shift_clock_Pin
      130. dec r17
      131. CBI shift_clock_Port, shift_clock_Pin
      132. BRnE loop_shift2out
      133. $end Asm
      134. End Sub
      135. Clear_memory:
      136. For N_1 = 0 To Mem_size_1
      137. Memory_red(n_1) = 0
      138. Memory_green(n_1) = 0
      139. Memory_blue(n_1) = 0
      140. Next N_1
      141. Return
      142. Sub Txt_6_8(byval X As Word , Byval Y As Word , Byval Color As Byte)
      143. Local Col As Word , Mem_byte_num As Word , Max_baseline As Byte , Y1 As Word , X1 As Word
      144. Local Character_column As Byte , Letter_num As Byte , Sign As String * 1 , Bit_num As Byte
      145. Local Font_byte As Byte , Bit_counter As Byte
      146. Max_baseline = Row_num - 8
      147. If Y > Max_baseline Then Y = Max_baseline
      148. Y1 = Row_num1 - Y 'y1 counts from upper row
      149. For Letter_num = 1 To Len(text)
      150. Sign = Mid(text , Letter_num , 1) 'Only one letter
      151. Tab_start = Asc(sign)
      152. Tab_start = Tab_start - 32
      153. Tab_start = Tab_start * 6 'Starting point in the font table
      154. For Character_column = 0 To 5
      155. Bit_num = X Mod 8 : Bit_num = 7 -bit_num 'bit-number of byte
      156. Col = X / 8 'number of byte-column
      157. Mem_byte_num = Y1 * Bytes_in_row
      158. Mem_byte_num = Mem_byte_num + Col
      159. If Mem_byte_num > Mem_size_1 Then Exit Sub 'there is no space, you are ready
      160. X1 = Tab_start + Character_column
      161. Font_byte = Lookup(x1 , Font_6x8)
      162. For Bit_counter = 0 To 7
      163. If Color.0 = 1 Then Memory_red(mem_byte_num).bit_num = Font_byte.bit_counter
      164. If Color.1 = 1 Then Memory_green(mem_byte_num).bit_num = Font_byte.bit_counter
      165. If Color.2 = 1 Then Memory_blue(mem_byte_num).bit_num = Font_byte.bit_counter
      166. Mem_byte_num = Mem_byte_num - Bytes_in_row 'jump one row up
      167. Next Bit_counter
      168. Incr X
      169. Next Character_column
      170. Next Letter_num
      171. End Sub
      172. Font_6x8:
      173. Data 0 , 0 , 0 , 0 , 0 , 0 ' <SPACE>
      174. Data 0 , 0 , 96 , 250 , 96 , 0 ' !
      175. Data 0 , 224 , 192 , 0 , 224 , 192 ' "
      176. Data 0 , 48 , 72 , 72 , 48 , 0 ' #
      177. Data 60 , 66 , 153 , 36 , 66 , 24 ' $
      178. Data 24 , 66 , 36 , 153 , 66 , 60 ' %
      179. Data 0 , 16 , 84 , 84 , 56 , 16 ' &
      180. Data 0 , 0 , 224 , 192 , 0 , 0 ' <ZAP>
      181. Data 48 , 96 , 255 , 255 , 96 , 48 ' (
      182. Data 12 , 6 , 255 , 255 , 6 , 12 ' )
      183. Data 8 , 42 , 28 , 28 , 42 , 8 ' *
      184. Data 8 , 8 , 62 , 8 , 8 , 0 ' +
      185. Data 0 , 0 , 7 , 6 , 0 , 0 ' ,
      186. Data 8 , 8 , 8 , 8 , 8 , 0 ' -
      187. Data 0 , 0 , 3 , 3 , 0 , 0 ' .
      188. Data 2 , 4 , 8 , 16 , 32 , 64 ' /
      189. Data 62 , 69 , 73 , 81 , 62 , 0 ' 0
      190. Data 0 , 33 , 127 , 1 , 0 , 0 ' 1
      191. Data 35 , 69 , 73 , 73 , 49 , 0 ' 2
      192. Data 34 , 73 , 73 , 73 , 54 , 0 ' 3
      193. Data 12 , 20 , 36 , 127 , 4 , 0 ' 4
      194. Data 114 , 81 , 81 , 81 , 78 , 0 ' 5
      195. Data 30 , 41 , 73 , 73 , 6 , 0 ' 6
      196. Data 96 , 71 , 72 , 80 , 96 , 0 ' 7
      197. Data 54 , 73 , 73 , 73 , 54 , 0 ' 8
      198. Data 48 , 73 , 73 , 74 , 60 , 0 ' 9
      199. Data 0 , 0 , 54 , 54 , 0 , 0 ' :
      200. Data 0 , 0 , 55 , 54 , 0 , 0 ' ;
      201. Data 8 , 20 , 34 , 65 , 0 , 0 ' <
      202. Data 36 , 36 , 36 , 36 , 36 , 0 ' =
      203. Data 0 , 65 , 34 , 20 , 8 , 0 ' >
      204. Data 32 , 64 , 77 , 72 , 48 , 0 ' ?
      205. Data 62 , 65 , 93 , 85 , 60 , 0 ' @
      206. Data 63 , 68 , 68 , 68 , 63 , 0 ' A
      207. Data 127 , 73 , 73 , 73 , 54 , 0 ' B
      208. Data 62 , 65 , 65 , 65 , 34 , 0 ' C
      209. Data 127 , 65 , 65 , 65 , 62 , 0 ' D
      210. Data 127 , 73 , 73 , 73 , 65 , 0 ' E
      211. Data 127 , 72 , 72 , 72 , 64 , 0 ' F
      Display All

      QiangLi Q6.6 test1

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

    • Raimond Longer wrote:

      The problem is that the image does not appear immediately, but gradually.
      Das liegt an deinem Algorithmus, wie du die Module ansteuerst.
      So wie ich das sehe, wird das alles nacheinander ausgegeben. Bedingt durch die Code-Laufzeit dauert das eben.

      Um das zu verbessern kannst du die Codelaufzeit verbessern, indem du z.B. den Code effektiver schreibst, sofern möglich, oder zeitkritisches in Assember schreiben.


      Raimond Longer wrote:

      If I increase the value in the timer, the scoreboard starts flickering.
      Deine gesamte Ausgabe ist in der Timer-ISR untergebracht. Diese braucht vermutlich viel Code-Laufzeit.
      Die Timer-Wiederholrate zu erhöhen ergibt nur eine höhere Refresh-Frequenz. Beschleunigt aber nicht die Ausgabe.

      Zwei Dinge können helfen.
      Darüber nachdenken, wie man die Ausgabe, also den Ausgabe-Algorithmus, effektiver machen kann, auch in Punkto gleichzeitige Ausgabe.
      Der 2. Punkt ist die Laufzeit zu reduzieren, z.B. mit Assembler.

      Beides ist natürlich auch davon abhängig, was du schlussendlich darstellen willst.
      Für eine Bilder-Sequenz alá Trickfilm wirst du um Assembler nicht herum kommen.

      Da dies hier ein deutsches Forum ist, habe ich hier auch auf deutsch geantwortet. Du kannst ja auch den Übersetzer nutzen.
      Ein englisches Forum findest du z.B. unter mcselec.com

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

    • Raimond Longer wrote:

      Some code uses assembler. Can you help with code optimization? Translation into assembler.
      Möglicherweise!

      Was man dafür wissen muss, wie diese Module angesteuert werden und wie du diese miteinander verschaltet hast.
      Datenblatt und Schaltplan wäre nützlich.

      Und was du genau ausgeben möchtest und wie oft.
      Nur Textausgabe?
      Was genau willst du erreichen?
    • Ich sehe hier jetzt nur, dass du die Module kaskadiert hast.
      Aber wie sie angesteuert werden ist mir unklar. Hast du da ein Datenblatt?

      Zudem hatte ich gefragt, in welche Richtung das optimiert werden soll.
      Wird nur Text ausgegeben oder Bilder?
      Und die Frage der gleichzeitigen Ausgabe steht noch im Raum.

      Wenn du Fragen nur unzureichend beantwortest, kann ich nicht weiter helfen.
    • There are two latches in my board (one is used: P_lat Alias Porth.4).
      There is an additional HUB-75 connector with another latch P_lat2 Alias Porth.3.
      Can divide the connection of matrices, for example, vertically?
      Files

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

    • Raimond Longer wrote:

      Can divide the connection of matrices, for example, vertically?
      Ich weiß im Moment nicht mal welche Pins an dem Modul wie anzusteuern sind.

      Ich weiß nur, dass dies seriell passiert über den Clock.

      Mir ist auch unklar, was es mit den Pins Line A bis Lines E auf sich hat.

      Bei den Pins R1 und R2 kann ich mir vorstellen, dass die für Rot stehen mit den Bitwertigkeiten. Also 2 Bit je Farbe.

      Beim verzweifelten Versuch, deinen Kommentarlosen Code zu verstehen, sehe ich aber, dass du umständlich Bitbänging in dem Shift-Out machst.
      Ich vermute, du drehst dir den Font da irgend wie so zurecht, dass das auf die Matrix passt.

      Da geht natürlich viel Zeit verloren.

      Besser wäre, den Font gleich so zu machen, dass er für die Matrix direkt zu verwenden ist.

      Ein Layout nützt mir da nichts, um den Code zu optimieren. Ich brauche etwas um die Funktion der RGB-Matrix zu verstehen.

      Was das gleichzeitige Anzeigen angeht, würde ich so vorgehen (wenn du das nicht schon machst:
      Die ausgabedaten, so wie sie in die Matrix zu schieben ist, im RAM 1:1 vorzubereiten.
      Dann das ganze RAM in die Matrix takten und mit Latch 1x übernehmen. Damit sollte die Änderung auf einen schlag sichtbar werden.
    • Das Bild kommt sofort, wenn du es vorher aufbauen lässt:
      Zeile 19 Stop Timer0 (gestartet wurde er schon bei der Config timer0....)
      Zeile 79 Gosub Clear_Memory (ist unnötig, da der beim Neustart immer leer ist.)
      Zeile 91 Start timer0 (denn hier ist das Bild fertig)

      Die Bildausgabe benötigt 93% Cpu, da bleibt nicht viel Zeit Text in den Speicher zu schreiben. Wie groß darf die Timer0reload werden ohne das das Bild flackert. (Kinder fragen)

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

    • In this case, setting and starting the timer does not matter, since the main program will be in a loop (Do Loop End)
      Without flickering:
      Dyspl = "1x1" - Const Timer0reload = 18
      Dyspl = "1x2" - Const Timer0reload = 18
      Dyspl = "1x3" - Const Timer0reload = 22
      Dyspl = "1x4" - Const Timer0reload = 26
      Dyspl = "1x5" - Const Timer0reload = 30
      Dyspl = "1x6" - Const Timer0reload = 34
      Dyspl = "1x7" - Const Timer0reload = 37
      Dyspl = "1x8" - Const Timer0reload = 40
      Dyspl = "2x1" - Const Timer0reload = 25
      Dyspl = "2x2" - Const Timer0reload = 30
      Dyspl = "2x3" - Const Timer0reload = 40
      Dyspl = "2x4" - Const Timer0reload = 46
      Dyspl = "2x5" - Const Timer0reload = 48
      Dyspl = "2x6" - Const Timer0reload = 56
      Dyspl = "3x1" - Const Timer0reload = 25
      Dyspl = "3x2" - Const Timer0reload = 48
      Dyspl = "3x3" - Const Timer0reload = 50
      Dyspl = "4x1" - Const Timer0reload = 25
      Dyspl = "4x2" - Const Timer0reload = 30
      Dyspl = "5x1" - Const Timer0reload = 30
      Dyspl = "5x2" - Const Timer0reload = 35
      Dyspl = "6x1" - Const Timer0reload = 30
      Dyspl = "7x1" - Const Timer0reload = 30
      Dyspl = "8x1" - Const Timer0reload = 30
      Dyspl = "9x1" - Const Timer0reload = 32
      Dyspl = "10x1" - Const Timer0reload = 36
    • Raimond Longer wrote:

      starting the timer does not matter
      Doch, weil er die Bildberechung stark ausbremst. Es an zu zeigen benötigt ca 20 ms. Wird es vorher aufgebaut (ohne Timer)braucht das auch nur 250ms und keine 5 Sekunden (Video)
      Sollen später schnelle Bildwechsel erforderlich sein wird ein zweite Bildspeicher gebraucht. Er zeigt solange das alte bis das neue fertig ist, dann sieht niemand den Aufbau

      Raimond Longer wrote:

      Without flickering:
      Das sind die kleinsten Timer0reload? Was sind die größten? Je größer desto mehr Zeit hat die Cpu ein Bild auf zu bauen/ ums schneller ist das neue fertig.

      Wie werden sie eingesetzt? Laufschrift? Wiederholend oder endlos? Verschiedene Zusammenstellungen?
    • Mit 2 "spielt " er aber bei 12 ist seine "Lastgrenze" fast erreicht. Der Ausgabecode ist schon ziemlich schnell. Der lässt sich nur noch wenig (ca 10%) beschleunigen. Da bringt ein größerer Timer0reload mehr.
      Das Video war mit 48(?) und brauchte 5 Sekunden. Mit Timer0reload 56 braucht es 2 Sekunden?

      Statische Bilder oder Text könnten vorher berechnet werden und könnten dann schnell in den Bildspeicher geschrieben werden. Leider hat er nicht genug ram für einen zweiten Bildspeicher. Wie kommen die da rein (Usart?, Spi?) Oder werden sie mit gebrannt? Dann könnten fertig bearbeitet in den Flash. Superschnell, aber für jede Konstellation müssen sie extra vorbereitet werden. Wenn er sie selber umrechnen muß braucht er mehr Speicher. Spi Ram?

      Wie schnell muß es werden?
      Hier eine gepimte Display_refresh:

      Source Code

      1. Display_refresh:
      2. Load Timer0 , Timer0reload
      3. Incr Page_counter
      4. If Page_counter > Scan_page Then
      5. Page_counter = 0
      6. P_c = 1
      7. End If
      8. Page_offset = Page_counter * Bytes_in_row
      9. For Z_0 = 1 To Dy_num_v
      10. St_byte_1 = Mem_offset_1 + Page_offset : St_byte_2 = Page_offset
      11. St_byte_3 = St_byte_1 + Channel_offset : St_byte_4 = St_byte_2 + Channel_offset
      12. For Z_1 = 1 To Dy_num_h
      13. For B_1 = 1 To Scan2
      14. Shift6out Memory_red(st_byte_1) , Memory_green(st_byte_1) , Memory_blue(st_byte_1) , Memory_red(st_byte_3) , Memory_green(st_byte_3) , Memory_blue(st_byte_3)
      15. 'Incr St_byte_1 : Incr St_byte_3 '38
      16. $asm
      17. Loadadr St_byte_1 , X
      18. ld r16,x+
      19. subi r16,255
      20. sts {St_byte_1},r16
      21. brne +4
      22. ld r16,x
      23. inc r16
      24. st x,r16
      25. Loadadr St_byte_3 , X
      26. ld r16,x+
      27. subi r16,255
      28. sts {St_byte_3},r16
      29. brne +4
      30. ld r16,x
      31. inc r16
      32. st x,r16
      33. $end Asm
      34. Next B_1
      35. For B_1 = 1 To Scan2
      36. Shift6out Memory_red(st_byte_2) , Memory_green(st_byte_2) , Memory_blue(st_byte_2) , Memory_red(st_byte_4) , Memory_green(st_byte_4) , Memory_blue(st_byte_4)
      37. 'Incr St_byte_2 : Incr St_byte_4
      38. $asm
      39. Loadadr St_byte_2 , X
      40. ld r16,x+
      41. subi r16,255
      42. sts {St_byte_2},r16
      43. brne +4
      44. ld r16,x
      45. inc r16
      46. st x,r16
      47. Loadadr St_byte_4 , X
      48. ld r16,x+
      49. subi r16,255
      50. sts {St_byte_4},r16
      51. brne +4
      52. ld r16,x
      53. inc r16
      54. st x,r16
      55. $end Asm '18
      56. Next B_1
      57. Next Z_1
      58. Page_offset = Page_offset + Dy_offset
      59. Next Z_0
      60. Pwm1b = 0
      61. Waitus 40
      62. P_lat = 1 : P_lat = 0
      63. P_a = 1 : P_a = 0
      64. P_c = 0
      65. Return
      Display All
      Die sollte auch mit Timer0reload 48 ca 2Sekunden brauchen. Im besten Fall bekomme ich noch eine Verdopplung hin, aber dann wäre es immer noch eine Sekunde.
      Ps Das 'Brightness = 255' habe ich raus genommen, das steht besser vor/in der Main oder im Clear_memory. Dieses ließ sich besser beschleunigen ( ca 6x)

      Source Code

      1. Clear_memory:
      2. 'Brightness = 0 '?
      3. Loadadr Memory_red , X
      4. Gosub Memclr
      5. Loadadr Memory_green , X
      6. Gosub Memclr
      7. Loadadr Memory_blue , X
      8. Gosub Memclr
      9. 'Brightness = 255 '?
      10. Return '# 17841 (1,1ms)
      11. Memclr:
      12. R16 = Mem_size
      13. R17 = High(mem_size)
      14. !clr r0
      15. !st x+,r0
      16. !dec r16
      17. !Brne -2
      18. !dec r17
      19. !brne -5
      20. Return
      Display All


      An der 'Txt_6_8' habe ich noch nichts geändert, da ich keine Chance habe das zu testen, zumal die ja auch für alle Konstellationen arbeiten muß.
      Wird für den Ticker auch Font_6x8 genutzt? Geht der immer nur bis "F" ? Werden Font genutzt die weiter gehen als bis 127?
    • Pluto25 wrote:

      Der Ausgabecode ist schon ziemlich schnell. Der lässt sich nur noch wenig (ca 10%) beschleunigen.
      Wenn man die Methodik ändert, kann man noch was rausholen.
      Wenn man, um ein flackerfreies Bild zu erhalten, 50 Hz für ein Vollbild ansetzt, und bei jedem Interrupt immer nur eine ScannLine der 16 ausgibt, benötigt man eine Interrupt-Frequenz von 16*15Hz = 800 Hz.

      Wenn man nun den Bildspeicher so verwendet, dass die Ausgaberoutine (Interrupt) nur noch die Daten vom SRAM 1:1 in die Schieberegister schieben muss. geht es deutlich schneller.

      In einem Byte (Buffer für Matrix) sind dann 2 Pixel gespeichert, nämlich die RGB1 und RGB2 Werte für Matrix-Zeile z.b. 0 und 16, oder Zeile 1 und 17 usw.
      Die Pixel z.B. von einem Font-Zeichen müssen hier dann nicht während der Ausgabe jedesmal gedreht werden. Das spart Zeit.

      Um ein Panel von 64x32 Pixel anzusteuern, benötigt man einen Buffer von 64x32 / 2 = 1024 Byte. Dividiert durch 2 weil man in einem Byte ja 2 Pixel speichert. 2 Bit werden verschenkt.

      Will man ein Zeichen auf der Matrix darstellen, muss man das Zeichen nur einmal umrechnen und in den Bildspeicher (Buffer für Matrix) schreiben.

      Ich habe die Ausgabe-Routinen mal gecodet und im Simulator den Durchlauf einer Scannline mit 64 Pixel ermittelt, also für ein 64x32 Panel. Es waren ca. 900 Takte je Scanline. Da der Interrupt 800x je Sekunde aufgerufen wird, sind das 900x800 = 720000 Takte je Sekunde. Bei 16MHz Takt also 720000 / 16000000 = 0,045 = 4,5 % CPU-Auslastung. Wenn man die 12 Panels kaskadiert, ergibt das eine Auslastung von weniger als 12x 4,5% = 54% CPU-Auslastung. Das liegt am Overhead durch den ISR-Aufruf.

      Es bleiben also mindestens ca. 46% CPU-Leistung für den Rest übrig, also um den Speicher zu beschreiben. Da die Datenbytes im Buffer quasi Pixel-Orientiert sind, lassen sich auch pixelweise Bildverschiebungen realisieren. Der Controller könnte hier aber noch übertaktet werden, was dann auch noch etwas bringen würde.

      Zwei Nachteile hat diese Methode allerdings auch.
      Es ist komplizierter, ein Ascii-Zeichen so im Buffer abzulegen, welches dann auch korrekt auf der Matrix angezeigt wird, und man verschenkt 1 Bit Speicher je Pixel.
      Allerdings muss man nur einmal den Buchstabe richtig in den SRAM schreiben, im Gegensatz zur bisherigen Lösung, wo er bei jeder Ausgabe umgerechnet wird.

      Die Speicher-Verschwendung kann man auch eliminieren, indem man 4 Module Parallel ansteuert. So würden dann anstelle von 6 Bit je 2 Matrix-Pixel, x4 = 24 Bit für 8 Pixel parallel ergeben, was schön in drei Byte passt. Speicher wäre ausgenutzt. Das ganze müsste folglich aus einer Anzahl von Einzel-Panelen bestehen, die ein Vielfaches von 4 sind.

      Wie man es dreht und wendet, bleibt immer die Berechnung der zu setzenden Pixel im Buffer, je nachdem, wie die Module verschaltet sind.
      Aber das ist auch nur Mathematik, wenn die Panel-Verschaltung klar definiert ist.

      Noch ein paar Tips zur Verbesserung der Performance.
      • Die Werte für RGB1 und RGB2 1:1 an einem Port ausgeben, ohne vorheriges Bitbanging, weil die Pins anders beschaltet sind.
      • Die Werte für Scanline (Pins A, B, C, D) auch in eine sinnvolle Reihenfolge bringen und auf einen Port legen, damit auch hier ein Bitbangig entfallen kann.
      • Zugriffe auf Ports wie PortH, die außerhalb des IO-Bereichs von 0-63 bzw. hex bis $3F sind (siehe Register), benötigen mehr Takte, weil sie nicht mit IN oder OUT angesprochen werden können.
      Ich habe in meinem Code diese Dinge berücksichtigt.
      Allerdings fehlen da noch Routinen, zur Ausgabe von Punken oder Zeichen. Da ich kein Matrix-Modul zur Hand habe und die Buffer-Beschreibung von der Kaskadierung und Anordnung der Panels abhängt, habe ich darauf verzichtet.

      Für eine Ausgabe also erst mal statisch in den Buffer was reinschreiben.

      Der Code ist ungetestet, da kein Panel verfügbar.

      Ach und es ist ein Projekt aus 3 Dateien.
      Also in Bascom im Menü Datei > Project > Open auswählen und die Datei "Matrix_64x32.prj" auswählen.
      Es wird dann alles geladen.

      Die Pinbelegung ist anders als bei Raimond!
      Files

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