Forum: Mikrocontroller und Digitale Elektronik SPI VFD-Display OKIC1937-01


von Andi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche seit einiger Zeit ein VFD- Display aus einem Geldspieler 
anzusteuern. Leider bisher ohne Erfolg....

Ich verwende einen ATMega8 (16MHz), auf der Displayplatine ist ein 
OKIC1937-01 Treiberbaustein. So wie ich das Datenblatt verstanden habe 
werden die beiden SPI- Leitungen (SCK,MOSI) genutzt um das Display 
anzusteuern.

Zum Starten des Treibers wird ein Impuls an Pin POR erwartet (bei mir 
PB1), danach kann mittels SPI das Display "konfiguriert" werden. Als 
erstes schicke ich die Anzahl der Segmente (bei mir 16), danach wähle 
ich das Segment aus, dass angesteuert werden soll (bei mir als Beispiel 
16), dann setze ich die Beleuchtung auf 50% und schicke dann 
beispielhaft ein A raus.

Leider tut sich auf dem Display nichts. Kann mir jemand helfen?
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <avr/delay.h>
6
7
8
#ifndef F_CPU
9
#define F_CPU 16000000UL
10
#endif
11
12
void SPI_MasterInit(void)
13
{
14
  /*Set MMOSI, SS and SCK output */
15
  DDRB = (1<<DDB3) | (1<<DDB5)| (1<<DDB2);
16
  /*Enable SPI, Master, set clock rate fck/32 --> 500kHz */
17
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPI2X) |(1<<SPR1);
18
  
19
}
20
21
void SPI_MasterTransmit(char cData)
22
{
23
  /* Start Transmission */
24
  SPDR = cData;
25
  /* Wait for transmision complete */
26
  while(!(SPSR & (1<<SPIF)))
27
  return SPDR;
28
  ;
29
}
30
31
32
int main(void)
33
{
34
  SPI_MasterInit();
35
  
36
37
DDRB |=  (1<<PB1);
38
39
/*POR Start- Signal erzeugen*/
40
PORTB &= ~(1<<PB1);
41
_delay_us(1);
42
PORTB |= (1<<PB1);
43
_delay_us(200);
44
PORTB &= ~(1<<PB1);
45
_delay_us(1);
46
47
while(1)
48
{
49
50
51
/* Einstellunge des Displays*/
52
SPI_MasterTransmit(0b10101110);  //Anzahl Digits --> 16
53
SPI_MasterTransmit(0b11000000);   //Nummer Displayeinheit--> 16
54
SPI_MasterTransmit(0b11110111);   //Beleuchtung auf 50%
55
56
57
58
//Schicke A
59
SPI_MasterTransmit(0b00000001);
60
  
61
62
  
63
 }
64
    return 0;
65
}

Das Datenblatt des Controllers habe ich angehängt.

Danke und Gruß Andi

von Dennis R. (dennis_ec) Flattr this


Lesenswert?

Der Controller erwartet zwischen den einzelnen befehlen eine Tbusy zeit 
von 40µS, diese sehe ich in deinem Code nicht.

Wäre möglich das es daran liegt? .

Desweiteren Musst du nicht jedes mal das ding neu Einstellen,

Pack das mal aus der While raus:

SPI_MasterTransmit(0b10101110);  //Anzahl Digits --> 16
SPI_MasterTransmit(0b11000000);   //Nummer Displayeinheit--> 16
SPI_MasterTransmit(0b11110111);   //Beleuchtung auf 50%

und nach jedem befehl 40µS warten damit das Display den Befehl ausführen 
kann, dann sollte es Klappen.

von Andi (Gast)


Lesenswert?

Hallo Dennis,

habe die "Displayeinstellung" aus der while- schleife genommen und 40us 
Pause hinzugefügt. Leider tut sich immer noch nichts....

Gruß Andi

von Dennis R. (dennis_ec) Flattr this


Lesenswert?

Dann versuch doch mal das Übliche :

Takt noch weiter reduzieren vom SPI,
vergrößer die Delay Zeiten nochmal.
Setz Testweiße beim SPI mal :


(1<<CPOL) // Müsste eigentlich gesetzt werden da der Displaycontroller 
auf die fallende Flanke reagiert.


(1<<DORD) //Bin ich mir eigentlich sicher das es auf 0 Stehen muss.

Auch kombinationen damit.

ggf ist dein SPI ja nur Falsch Konfiguriert.

Was du auch mal Testen kannst, der IC selber hat ein Testeingang.

Könntest dir den mal Anschauen und ggf lässt er sich ansteuern, nicht 
das dass Display ein Schlag weg hat.


Edit:

Ich hab knapp 1 Jahr jetzt kein AVR Programmiert daher bin ich mir nicht 
sicher ob es notwendig ist, definier mal SCK und MOSI als 
Ausgang,schaden kann es nicht.
Grüße

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

>  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPI2X) |(1<<SPR1);

Auch wenn das wohl nicht dein Problem ist:
Es gibt kein Bit SPI2X in SPCR.

von Dennis R. (dennis_ec) Flattr this


Lesenswert?

Das hab ich auch übersehen als ichs Datenblatt vom Mega8 offen hatte,

SPI2X ist in SPSR Bit 0

Da SPI2X automatisch beim Compilen durch 0 ersetzt wird, hat er Bit 0 in 
SPCR Gesetzt, das würde heißen der Preteiler war 128 und nicht 32.

Daran sollte es nicht liegen.

Hardware Aufbau ist soweit aber in Ordnung,nicht das dort noch ein 
Schnitzer drinnen ist?

von Andi (Gast)


Lesenswert?

Hallo,

schon mal vielen Dank für die Hilfe.

Ich kam jetzt endlich dazu mein Programm zu korrigieren. Vor dem 
Controller wird noch eine Invertierung des "Start"- Signals gemacht. Ich 
schicke einen Lowimpuls um zu starten und jetzt zeigen sich Buchstaben 
;-).

ABER: Ich schicke A-P, das Display lässt aber jeden 2. Buchstaben weg, 
also A, C, E,...und wiederholt das ganze Ab der 9. Stelle:
"ACEGIKMOACEGIKMO".

Jetzt weis ich nicht warum bzw. was ich noch ändern soll. Was ich auch 
nicht verstehe:

(zufällig hat es mit meinem "Fehler" funktioniert)
Dennis R. schrieb:
> Da SPI2X automatisch beim Compilen durch 0 ersetzt wird, hat er Bit 0 in
> SPCR Gesetzt, das würde heißen der Preteiler war 128 und nicht 32.

Im Datenblatt des Displaycontrollers steht: 392 - 548 kHz. Mit dem 
Teiler von 128 komme ich auf eine Frequenz von 125kHz. Es funktioniert 
auch NUR mit dieser Frequenz, habe alle Teiler durchprobiert.????????

Wenn mir jemand helfen könnte wäre es super.

Danke und Gruß Andi

Anbei noch der Code:
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/delay.h>
6
7
8
#ifndef F_CPU
9
#define F_CPU 16000000UL
10
#endif
11
12
void SPI_MasterInit(void)
13
{
14
  /*Set MMOSI, SS and SCK output */
15
  DDRB = (1<<DDB3) | (1<<DDB5)| (1<<DDB2);
16
  /*Enable SPI, Master, set clock rate fck/128 --> 125kHz */
17
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); 
18
      
19
}
20
21
void SPI_MasterTransmit(char cData)
22
{
23
  /* Start Transmission */
24
  SPDR = cData;
25
  /* Wait for transmision complete */
26
  while(!(SPSR & (1<<SPIF)))
27
  return SPDR;
28
}
29
30
31
int main(void)
32
{
33
34
SPI_MasterInit();
35
36
DDRB |=  (1<<PB1);
37
38
PORTB |= (1<<PB1); 
39
_delay_ms(500);
40
_delay_ms(500);
41
42
/*POR Start- Signal erzeugen*/
43
PORTB &= ~(1<<PB1); 
44
_delay_us(200);
45
PORTB |= (1<<PB1); 
46
_delay_ms(1);
47
48
49
/* Einstellunge des Displays*/
50
SPI_MasterTransmit(0b10101111);  //Nummer Displayeinheit --> 1
51
_delay_us(40);
52
SPI_MasterTransmit(0b11000001);   //Anzahl Digits --> 16
53
_delay_us(40);
54
SPI_MasterTransmit(0b11110111);   //Beleuchtung auf 50%
55
_delay_ms(500);
56
57
while(1)
58
{
59
60
//Schicke A
61
SPI_MasterTransmit(0b00000001);
62
_delay_us(40);
63
//Schicke B
64
SPI_MasterTransmit(0b00000010);
65
_delay_us(40);  
66
//Schicke C
67
SPI_MasterTransmit(0b00000011);
68
_delay_us(40);
69
//Schicke D
70
71
//zur besseren Übersicht fürs Forum habe ich hier die restlichen Buchstaben gelöscht........in meinem Code ist es drin ;-)
72
73
//Schicke O
74
SPI_MasterTransmit(0b00001111);
75
_delay_us(40);
76
//Schicke P
77
SPI_MasterTransmit(0b00010000);
78
_delay_us(40);  
79
  
80
 }
81
    return 0;
82
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.