Videosignalgenerator, 16bit-Programmierung

OP #2780240
Lesenswert?

liebes Forum,

ich wollte spaßeshalber ein BAS-Videosignal auf meinem Attiny2313 
erzeugen.
Da ein Bild aus 625 Zeilen besteht ist der Counter für die 
Zeilenschleife mehr als 8 Bit groß. Deshalb muss ich wohl mit 16 bit 
rechnen was ich im nachfolgenden codeschnipsel wohl versucht habe.

Das Problem ist nun das nur das Bildsynchronsignal ausgegeben wird 
(messung mit Oszilloskop). Ich denke das der Fehler in meiner 16bit 
rechnerei liegt, weis aber nicht woran genau.

danke schonmal für schlaue Antworten :-)


1
sei                    ;  Interrupts allg. erlauben
2

3
  clr Zeilelow
4
  clr Zeilehigh
5

6
  Zeilenschleife:
7

8
    cbi PORTD, 0          ; Zeilensynchronsignal 4,7us
9
    clr Temp1
10
    ZSyncSchleife:
11
    NOP
12
    inc Temp1
13
    cpi Temp1, 9
14
    brlo ZSyncSchleife
15
    sbi PORTD, 0          ; Zeilensync ende
16

17
    clr Temp1            ; vordere Schwarzschulter 5,8us
18
    VorSwSchleife:
19
    NOP
20
    inc Temp1
21
    cpi Temp1, 11
22
    brlo VorSwSchleife
23

24
                ; Helligkeitssignale (416 Zyklen = 720 pix)
25

26
    clr Temp1            ; hintere Schwarzschulter 1,5us
27
    HinSwSchleife:
28
    NOP
29
    inc Temp1
30
    cpi Temp1, 3
31
    brlo HinSwSchleife
32

33
    ldi Temp1, 1          ; inkrementiere Zeile
34
    ldi Temp2, 0
35
    add Zeilelow, Temp1
36
    adc Zeilehigh, Temp2
37

38
  ldi Temp1, 0b01110001        ; Prüfe ob schon 625. Zeile
39
  ldi Temp2, 0b00000010
40
  cp Zeilelow, Temp1
41
  cpc Zeilehigh, Temp2
42
  brlo Zeilenschleife
43

44

45
  clr BildSync
Gast #2780662
Lesenswert?

Hi

> Deshalb muss ich wohl mit 16 bit
>rechnen was ich im nachfolgenden codeschnipsel wohl versucht habe.

Aber warum so kompliziert? Wenn du zum Zählen Registerpaare ab r24 
benutzt können AVRs auch direkt 16Bit zählen
1
  ldi r24,Low(625)
2
  ldi r25,High(625)
3

4
  Zeilenschleife:
5

6
    ......
7
    
8
    brlo HinSwSchleife
9

10
    sbiw r25:r24,1
11
    brne Zeilenschleife
12

13
  clr BildSync

Und mit rückwärts Zählen ersparst du die die ganzen Vergleiche.

MfG Spess
OP #2780785
Lesenswert?

@ Spess 53:

eines versteh ich allerdings nicht, sbiw zieht von r25,r24 immer 1 ab.
Aber es wird nicht mit 0 verglichen. Woher weis dann brne welche 
register oder konstanten "not equal" sind?

  " sbiw r25:r24,1
    brne Zeilenschleife"

@ R. T. Firefly:

ein ganzes bild teilt sich ja in 2 halbbilder auf um das flimmern zu 
reduzieren > 1.halbbild jede gerade Zeile, 2.halbbild (vom gleichen 
bild) jede ungerade Zeile.

aber bevor ich das programmiere muss ich noch an meiner hardware 
basteln. ich hab da so meine probleme mit der kapazität von den 
dioden...
OP #2789844
Lesenswert?

ich hab jezt geschafft ein sauberes bildsignal zu erzeugen (schwarz 
weiße streifen). Jetzt überleg ich gerade wie ich ein richtiges Bild, 
gespeichert in einem array, erzeugen kann. Der attiny2313 mit 20MHz ist 
dazu zu langsam. Selbst wenn er schnell genug wäre, wäre er komplett 
damit beschäftigt das videosignal zu erzeugen. Eigentlich soll dieser ja 
auch nur das Bild bearbeiten (Rechtecke oder Buchstaben zeichnen). Das 
Videosignal soll hardwaremäßig gemacht werden: Oszillator > 
inkrementiert Zähler > setzt die adressleitung von externem Speicher > 
Ausgang ist das signal.
Das Problem ist nun: Wie soll das Bild vom Mikrocontroller in den 
externen Speicher kommen, ohne das die Videosignalerzeugung unterbrochen 
wird.

ich bräuchte quasi einen Speicher (4kbyte) der gleichzeitig beschrieben 
und gelesen werden kann. Mit einem Ausgang und einem Eingang und jeweils 
die Adresseingänge. Gibt es sowas, oder hat noch wer eine andere idee?
#2789852
Lesenswert?

@M. M. (blackcow)

>weiße streifen). Jetzt überleg ich gerade wie ich ein richtiges Bild,
>gespeichert in einem array, erzeugen kann.

So wie die Leute, die das vor dir getan haben.

> Der attiny2313 mit 20MHz ist
>dazu zu langsam.

Nein.

> Selbst wenn er schnell genug wäre, wäre er komplett
>damit beschäftigt das videosignal zu erzeugen.

Fast.

>Das Problem ist nun: Wie soll das Bild vom Mikrocontroller in den
>externen Speicher kommen, ohne das die Videosignalerzeugung unterbrochen
>wird.

Beitrag "AVR ASCII Video Terminal  - 40 x 25  - BAS Signal"

Und wenn du mal RICHTIG blass werden willst, schua dir das an. DER 
HAMMER!!!

http://www.linusakesson.net/scene/craft/
Gast #2792845
Lesenswert?

Hi

>kann man programmieren das der 16-bit timer 1 bei OCR1A einen Interrupt
>auslöst, weiterzählt, bei OCR1B einen Interrupt auslöst und hier erst
>zurücksetzt?

Umgedreht ginge es einfacher.

MfG Spess
OP #2792852
Lesenswert?

wie umgedreht? also ich will nach einer Zeit(Zählerstand) einen 
Interrupt haben, und nach einem noch höheren Zählerstand wieder einen. 
Ich lese grade das datenblatt und glaube das hierfür irgendein pwm-modus 
geeignet wäre, aber welcher, und wie funktioniert er?
OP #2795637
Lesenswert?

im debugmodus wird diese schleife ewig wiederholt! warum?




1
    loopZeilenfinder:
2
    cpi rTemp2, LOW(14+1)
3
    ldi rTemp4, HIGH(14+1)
4
    cpc rTemp1, rTemp4
5
    brlo Y_Pointersetzen
6
    ldi rTemp4, 6
7
    add rTemp3, rTemp4
8
    ldi rTemp4, LOW(14)
9
    sub rTemp1, rTemp4
10
    ldi rTemp4, HIGH(14)
11
    sbc rTemp1, rTemp4
12
    rjmp loopZeilenfinder

Hab ich das vll falsch verstanden?:

--------------------------------
|  z.B. r24     |  z.B. r25    |
--------------------------------
|   Low-byte    |  High-byte   |
--------------------------------
|  16-Bit Schreibweise für 1:  |
|  0000.0000    |  0000.0001   |
--------------------------------
OP #2795807
Lesenswert?

Ich komme einfach nicht weiter! das folgende programm soll ein 
videosignal aus dem im SRAM gespeichertem bild erzeugen. Aber an PORTB 
kommt nur schwachsinn raus! Ein Schwachsinnsgenerator! auch PORTB, Bit 4 
ist manchmal Angesteuert, obwohl das laut dem folgendem Code gar nicht 
sein kann, weil ich noch kein Bild in den SRAM gespeichert hab!

Kann mal bitte, bitte wer den code anschauen?




1
.include "tn2313def.inc"          ; Definitionsdatei für Attiny2313 Einbinden
2

3
                      ; Interruptvektoren setzen
4
.org 0x000                  ; > bei Reset
5
  rjmp Reset
6
.org OC1Aaddr                ; > bei Timercompare 1A
7
  rjmp Verteiler
8
.org OC1Baddr                ; > bei Timercompare 1B
9
  rjmp Vergleichswert_B
10

11
Reset:                    ; Start bei Reset
12

13
  .def rTemp1 = r16            ; Variablen festlegen
14
  .def rTemp2 = r17
15
  .def rTemp3 = r18
16
  .def rTemp4 = r19
17
  .def rPhase1Lo = r24
18
  .def rPhase1Hi = r25
19
  .def rPhaseHalbbild = r21
20

21
  .dseg
22
  Bildspeicher:    .BYTE 120      ; Bildspeicher deklarieren und reservieren 
23
  .cseg
24

25
    ldi     YL, LOW(Bildspeicher)       ; Low-Byte der Adresse erster Bildpunkt in Y-Pointer
26
    ldi     YH, HIGH(Bildspeicher)       ; High-Byte der Adresse erster Bildpunkt in Y-Pointer
27

28
  clr rTemp1                ; Variablen Resetten
29
  clr rTemp2
30
  clr rTemp3
31
  clr rTemp4
32
  ldi rPhase1Lo, 1
33
  clr rPhase1Hi
34
  ldi rPhaseHalbbild, 5
35
  
36
  ldi rTemp1, RAMEND              ; Stackpointer initialisieren
37
    out SPL, rTemp1
38

39
   ldi rTemp1, 0x00              ; Ein- und Ausgänge Konfigurieren 1 > Ausgang
40
    out DDRA, r16
41
  ldi rTemp1, 0b00011000
42
    out DDRB, r16
43
  ldi rTemp1, 0x00
44
    out DDRD, r16
45

46
  ldi rTemp1, 0xFF              ; Pullup-Widerstände Einschalten (Eingänge)
47
    out PORTA, r16
48
  ldi rTemp1, 0b11100111            ; Ausgänge erstmal ausschalten
49
    out PORTB, r16
50
  ldi rTemp1, 0xFF
51
    out PORTD, r16
52

53
                      
54
  ldi rTemp1, (1<<WGM12)|(1<<CS10)      ; Timer 1 konfigurieren: Zähler bei Comparematch OCR1A rücksetzen + Vorteiler 1
55
    out TCCR1B, r16
56

57
    ldi rTemp1, high( 20 )        ; Vergleichswert 1 für Timer setzen (provisorisch)
58
        out OCR1BH, rTemp1
59
        ldi rTemp1, low( 20 )
60
        out OCR1BL, rTemp1
61

62
    ldi  rTemp1, high( 50 )        ; Vergleichswert 2 für Timer setzen (delay bis zum ersten Bild 8ms)
63
    out OCR1AH, rTemp1
64
    ldi rTemp1, low( 50 )
65
    out OCR1AL, rTemp1
66

67
    ldi     ZL, LOW(Phase_A)         ; Low-Byte der Adresse erster Phase in Z-Pointer
68
    ldi     ZH, HIGH(Phase_A)         ; High-Byte der Adresse erster Phase in Z-Pointer
69

70
    ldi rTemp1, (1<<OCIE1A)|(1<<OCIE1B)    ; Interrupt bei Vergleichswert 1+2 erlauben
71
        out TIMSK, rTemp1
72

73

74

75
Main:                    ; Hauptprogramm
76

77
  sei                    ;  Interrupts allg. erlauben
78

79

80

81

82
rjmp Main
83

84

85

86
  Vergleichswert_B:
87

88
    cbi PORTB, 3              ; Signal 0,0 V
89

90
  reti
91

92
  Verteiler:
93

94
  ijmp                    ; nach Adresse von Z-Pointer springen
95

96

97
  Phase_A:                  ; 6 oder 5 Vortrabanten---------------------------------------------------------------------------------------------
98

99
    sbi PORTB, 3              ; Signal 0,3 V
100

101
    ldi rTemp1, 0              ; Timer1 rücksetzen
102
    out TCNT1H, rTemp1
103
    out TCNT1L, rTemp1 
104

105
    inc rPhaseHalbbild
106
    cp rPhase1Lo, rPhaseHalbbild        ; bei nächstem Interrupt Phase B
107
    dec rPhaseHalbbild
108
    brlo Weiter_Phase_A
109
    clr rPhase1Lo
110

111
    ldi     ZL, LOW(Phase_B)         ; Low-Byte der Adresse nächster Phase in Z-Pointer
112
    ldi     ZH, HIGH(Phase_B)         ; High-Byte der Adresse nächster Phase in Z-Pointer
113

114
    Weiter_Phase_A:
115
    inc rPhase1Lo
116

117
        ldi rTemp1, high( 237 - 1 )        ; Vergleichswert 1 für Timer setzen (29,65us)
118
        out OCR1BH, rTemp1
119
        ldi rTemp1, low( 237 - 1 )
120
        out OCR1BL, rTemp1
121

122
    ldi  rTemp1, high( 256 - 1 )        ; Vergleichswert 2 für Timer setzen (32us)
123
    out OCR1AH, rTemp1
124
    ldi rTemp1, low( 256 - 1 )
125
    out OCR1AL, rTemp1
126

127
  reti
128

129
  Phase_B:                  ; 5 Synchronimpulse------------------------------------------------------------------------------------------------------
130

131
    sbi PORTB, 3              ; Signal 0,3 V
132

133
    ldi rTemp1, 0              ; Timer1 rücksetzen
134
    out TCNT1H, rTemp1
135
    out TCNT1L, rTemp1
136

137
    cpi rPhase1Lo, 5
138
    brlo Weiter_Phase_B
139
    clr rPhase1Lo
140

141
    ldi     ZL, LOW(Phase_C)         ; Low-Byte der Adresse nächster Phase in Z-Pointer
142
    ldi     ZH, HIGH(Phase_C)         ; High-Byte der Adresse nächster Phase in Z-Pointer
143

144
    Weiter_Phase_B:
145
    inc rPhase1Lo
146

147
    ldi rTemp1, high( 38 - 1 )        ; Vergleichswert 1 für Timer setzen (4,7us)
148
        out OCR1BH, rTemp1
149
        ldi rTemp1, low( 38 - 1 )
150
        out OCR1BL, rTemp1
151

152
  reti
153

154
  Phase_C:                  ; 5 oder 4 Nachtrabanten-------------------------------------------------------------------------------------------------
155

156
    sbi PORTB, 3              ; Signal 0,3 V
157
    
158
    ldi rTemp1, 0              ; Timer1 rücksetzen
159
    out TCNT1H, rTemp1
160
    out TCNT1L, rTemp1 
161

162
    cp rPhase1Lo, rPhaseHalbbild        ; bei nächstem Interrupt Phase D
163
    brlo Weiter_Phase_C
164
    clr rPhase1Lo
165

166
    ldi     ZL, LOW(Phase_D)         ; Low-Byte der Adresse nächster Phase in Z-Pointer
167
    ldi     ZH, HIGH(Phase_D)         ; High-Byte der Adresse nächster Phase in Z-Pointer
168

169
    Weiter_Phase_C:
170
    inc rPhase1Lo
171

172
        ldi rTemp1, high( 237 - 1 )        ; Vergleichswert 1 für Timer setzen (29,65us)
173
        out OCR1BH, rTemp1
174
        ldi rTemp1, low( 237 - 1 )
175
        out OCR1BL, rTemp1
176

177
  reti
178

179
  Phase_D:                  ; 13 Schwarzzeilen------------------------------------------------------------------------------------------------------
180

181
    sbi PORTB, 3              ; Signal 0,3 V
182
    
183
    ldi rTemp1, 0              ; Timer1 rücksetzen
184
    out TCNT1H, rTemp1
185
    out TCNT1L, rTemp1 
186

187
    cpi rPhase1Lo, 13              ; bei nächstem Interrupt Phase E
188
    brlo Weiter_Phase_D
189
    clr rPhase1Lo
190

191
    ldi     ZL, LOW(Phase_E)         ; Low-Byte der Adresse nächster Phase in Z-Pointer
192
    ldi     ZH, HIGH(Phase_E)         ; High-Byte der Adresse nächster Phase in Z-Pointer
193

194
    Weiter_Phase_D:
195
    inc rPhase1Lo
196

197
        ldi rTemp1, high( 416 - 1 )        ; Vergleichswert 1 für Timer setzen (52us)
198
        out OCR1BH, rTemp1
199
        ldi rTemp1, low( 416 - 1 )
200
        out OCR1BL, rTemp1
201
    
202
    ldi  rTemp1, high( 512 - 1 )        ; Vergleichswert 2 für Timer setzen (64us)
203
    out OCR1AH, rTemp1
204
    ldi rTemp1, low( 512 - 1 )
205
    out OCR1AL, rTemp1
206

207
  reti
208

209
  Phase_E:                  ; Bildinformationen-------------------------------------------------------------------------------------------
210

211
    sbi PORTB, 3              ; Signal 0,3 V
212
    
213
    ldi rTemp1, 0              ; Timer1 rücksetzen
214
    out TCNT1H, rTemp1
215
    out TCNT1L, rTemp1 
216

217
    cpi rPhase1Lo, LOW(280)              ; bei nächstem Interrupt Phase F
218
    ldi rTemp4, HIGH(280)
219
    cpc rPhase1Hi, rTemp4
220
    brsh Nachste_Adresse
221
    NOP
222
    NOP
223
    rjmp Weiter_Phase_E
224

225
    Nachste_Adresse:
226
    clr rPhase1Hi
227
    clr rPhase1Lo
228

229
    ldi rTemp1, 0b00000001          ; Toggle rPhaseHalbbild zwischen 4 und 5
230
    eor rPhaseHalbbild, rTemp1
231

232
    ldi     ZL, LOW(Phase_F)         ; Low-Byte der Adresse nächster Phase in Z-Pointer
233
    ldi     ZH, HIGH(Phase_F)         ; High-Byte der Adresse nächster Phase in Z-Pointer
234

235
    Weiter_Phase_E:
236

237
    adiw rPhase1Hi:rPhase1Lo, 1
238

239
      ldi     rTemp1, ((46/2)-15)            ; loop0: hintere Schwarzschulter (5,8 us)
240
    loop0:
241
    NOP
242
    dec     rTemp1              ; Schleifenzähler um 1 verringern, dabei wird das Zero Flag beeinflusst
243
    brne    loop0              ; wenn rTemp1 noch nicht 0 geworden ist -> Schleife wiederholen 
244

245

246
    ; setze y-pointer auf (rPhase1#280#/14)*6
247
    mov rTemp1, rPhase1Hi
248
    mov rTemp2, rPhase1Lo
249
    clr rTemp3            ; Variable für Y-Pointer
250

251
    loopZeilenfinder:
252
    cpi rTemp2, LOW(14+1)
253
    ldi rTemp4, HIGH(14+1)
254
    cpc rTemp1, rTemp4
255
    brlo Y_Pointersetzen
256
    ldi rTemp4, 6
257
    add rTemp3, rTemp4
258

259
    ldi rTemp4, LOW(14)
260
    sub rTemp2, rTemp4
261
    ldi rTemp4, HIGH(14)
262
    sbc rTemp1, rTemp4
263

264
    rjmp loopZeilenfinder
265

266

267
    Y_Pointersetzen:
268
    ldi rTemp1, LOW(Bildspeicher)
269
    ldi rTemp2, HIGH(Bildspeicher)
270
    
271
    add rTemp1, rTemp3
272
    clr rTemp3
273
    adc rTemp2, rTemp3
274

275
    mov     YL, rTemp1       ; Low-Byte der Adresse erster Bildpunkt in Y-Pointer
276
    mov     YH, rTemp3       ; High-Byte der Adresse erster Bildpunkt in Y-Pointer
277

278

279

280

281
    ldi rTemp2, 0b00011000          ; And werte laden
282

283
    ldi rTemp3, 6
284
    loop24Pixel:              ; Zeilenwerte ausgeben 24 Pixel / 4 Pixel pro Byte
285

286
    ld rTemp1, Y              ; Byte 1 Pixel 1
287
    lsr rTemp1
288
    lsr rTemp1
289
    lsr rTemp1
290
    and rTemp1, rTemp2
291
    out PORTB, rTemp1
292

293
    ld rTemp1, Y              ; Byte 1 Pixel 2
294
    lsr rTemp1
295
    NOP
296
    NOP
297
    and rTemp1, rTemp2
298
    out PORTB, rTemp1
299

300
    ld rTemp1, Y              ; Byte 1 Pixel 3
301
    lsl rTemp1
302
    NOP
303
    NOP
304
    and rTemp1, rTemp2
305
    out PORTB, rTemp1
306
    
307
    ld rTemp1, Y+              ; Byte 1 Pixel 4
308
    lsl rTemp1
309
    lsl rTemp1    
310
    lsl rTemp1
311
    and rTemp1, rTemp2
312
    out PORTB, rTemp1
313

314
    dec     rTemp3              ; Schleifenzähler um 1 verringern, dabei wird das Zero Flag beeinflusst
315
    brne    loop24Pixel            ; wenn rTemp3 noch nicht 0 geworden ist -> Schleife wiederholen 
316

317

318
    sbiw YH:YL,6      ; Y-Pointer auf ausgangswert setzen
319

320

321
    sbi PORTB, 3              ; Signalausgang auf 0,3V setzen
322
    cbi PORTB, 4
323

324
  reti
325

326
  Phase_F:                  ; 12 Schwarzzeilen------------------------------------------------------------------------------------------------------
327

328
    sbi PORTB, 3              ; Signal 0,3 V
329
    
330
    ldi rTemp1, 0              ; Timer1 rücksetzen
331
    out TCNT1H, rTemp1
332
    out TCNT1L, rTemp1 
333

334
    cpi rPhase1Lo, 12              ; bei nächstem Interrupt Phase A
335
    brlo Weiter_Phase_F
336
    clr rPhase1Lo
337

338
    ldi     ZL, LOW(Phase_A)         ; Low-Byte der Adresse nächster Phase in Z-Pointer
339
    ldi     ZH, HIGH(Phase_A)         ; High-Byte der Adresse nächster Phase in Z-Pointer
340

341
    Weiter_Phase_F:
342
    inc rPhase1Lo
343

344
  reti
Gast #2797001
Lesenswert?

M. M. schrieb:
> a ein Bild aus 625 Zeilen besteht ist der Counter für die
> Zeilenschleife mehr als 8 Bit groß. Deshalb muss ich wohl mit 16 bit
> rechnen was ich im nachfolgenden codeschnipsel wohl versucht habe.

Nicht zwingend. Du kannst auch die 8-Bit Counter Überläufe zählen.
Inwieweit das Sinn ergibt, ist eine andere Frage.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren