Forum: Mikrocontroller und Digitale Elektronik Bekomme 7Seg nicht ans leuchten mit ICM7218A


von Thorsten S. (thorstenst)


Lesenswert?

Hallo, ich habe

- Atmega8-16PU
- ICM7218A (Intersil)
- 7Seg Anzeige (gem. Anode)

Die Datenblätter gibt es hier:
Intersil= 
http://www.intersil.com/content/dam/Intersil/documents/fn31/fn3159.pdf

Maxim (sollte gleich sein?) = 
http://datasheets.maximintegrated.com/en/ds/ICM7218-ICM7228.pdf

Kurz zur Belegung:

ATM = ATMEGA8
ICM = ICM7218

ATM PD7  --> ICM PIN9  (MODE)
ATM PD6  --> ICM PIN6  (ID5-!Decode)
ATM PD5  --> ICM PIN7  (ID7-DataComing)
ATM PD4  --> ICM PIN10 (ID4-!Shutdown)
ATM PD3  --> ICM PIN13 (ID2)
ATM PD2  --> ICM PIN12 (ID0)
ATM PD1  --> ICM PIN13 (ID3)
ATM PC0  --> ICM PIN5  (ID6)

Dazu habe ich mir nun folgenden Code überlegt wie ich es aus dem
Datenblatt rausgelesen habe.
Für mich zur Vereinfachung erstmal in Bitschreibweise.
1
#ifndef F_CPU
2
#define F_CPU 16000000UL // 16 MHz
3
#endif
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
int main(void)
9
{
10
  DDRB = 0b00000001;  // PB0 = Output
11
  DDRC = 0b00000001;  // PC0 = Output
12
  DDRD = 0b11111111;  // ALL PortD = Output
13
  
14
    while(1)
15
    {
16
    PORTB = 0b00000001; // LED - ON
17
    
18
    PORTD = 0b10000000;  // Mode = High 
19
    PORTD = 0b11000000; // No decode        
20
    PORTD = 0b11100000; // DataComing
21
            
22
    PORTD = 0b11100000; // pin 1 - 3 = 0 = Digit1
23
    
24
    PORTD = 0b00000000; // Mode = Low   
25
    
26
    PORTC = 0b00000001; // SegA aktiv
27
        
28
    _delay_ms(500);
29
    
30
    PORTB = 0b00000000; // LED - OFF
31
      
32
    _delay_ms(500);    
33
    
34
    }
35
}

Habe ich da vlt. etwas falsch verstanden, wäre der Code
überhaupt richtig?

Die LED habe ich nur, damit ich sehe, dass der Atmega8 auch etwas tut ;) 
(und die blinkt fröhlich vor sich hin).

Aber das Segment A der Anzeige möchte nicht leuchten.

Schon mal vielen Dank!

Gruß
 Thorsten

von Joerg L. (Firma: 100nF 0603 X7R) (joergl)


Lesenswert?

Im Datenblatt ist von einer /Write-Leitung die Rede, Pin 8.
Datenblatt "Figure 9". Diese finde ich bei Dir nicht.

von Düsendieb (Gast)


Lesenswert?

auf Seite 6 im Datenblatt gibt es ein Timing Diagramm. In Deinem 
Programm werden die einzelnen einfach nur für ein paar µs angelegt. 
Überlege mal wie lange der µc für die einzelnen Schritte braucht.

von Thorsten S. (thorstenst)


Lesenswert?

Guten Morgen,

habe das mit dem Write auch gesehen, aber so gelesen, dass ich den nur 
bräuchte wenn ich mit Code-B oder HEX arbeiten möchte. Werde mir dass 
dann aber mal genauer ansehen.

@Düsendieb: Hab mir das grad mal angeschaut. Ist das richtig das meine 
Befehle mit 62,5 Nanosekunden abgearbeitet werden bei 16MHz?
(1/16000000) / 10^-9 = 62,5 ?

Kann ich dann die Befehle entsprechend mit der Delay funktion einfach 
verzögern? Mode Hold braucht z.B. 150 ns.

(Alles was schneller als eine 1/2 sec. ist kann ich nicht mehr greifen 
:D)

Gruß
 Thorsten

von Karl H. (kbuchegg)


Lesenswert?

> Kann ich dann die Befehle entsprechend mit der Delay funktion einfach
> verzögern? Mode Hold braucht z.B. 150 ns.

Was kommt raus, wenn du den Lichtschalter auf 'ein' stellst, dann 2 
Stunden Däumchen drehst und danach den Lichtschalter wieder auf 'aus'.

Genau. Ein 2 Stunden langer Lichtpuls.


Und noch ein Tip.
Bei derartigen ICs ist es so, dass du zwar gewisse Mindestzeiten 
einhalten musst, es aber keine Maxima gibt. D.h. du kannst deine Pulse 
so lange verzögern wie du willst. Das ist zb dann ganz besonders 
praktisch, wenn du irgendwelche 'Messmittel' wie zb LED an die Leitungen 
hängst, die dir ganz zwanglos anzeigen, welche Leitungen du in deinem 
Programm in welcher Reihenfolge mit welchem Pegel ansprichst.

>
> (Alles was schneller als eine 1/2 sec. ist kann ich nicht mehr greifen
> :D)

Darum hat Gott auch die Mathematik erfunden. Sowas kann man rechnen.

von Karl H. (kbuchegg)


Lesenswert?

>
1
>     PORTD = 0b10000000;  // Mode = High 
2
>     PORTD = 0b11000000; // No decode        
3
>     PORTD = 0b11100000; // DataComing
4
>             
5
>     PORTD = 0b11100000; // pin 1 - 3 = 0 = Digit1
6
>     
7
>     PORTD = 0b00000000; // Mode = Low   
8
>     
9
>     PORTC = 0b00000001; // SegA aktiv
10
>


Tus nicht!
Schreibs nicht so, sondern verwende Bitnamen Schreibweise so wie der 
Rest der Welt. Die wissen schon warum.


1
#define PIN_MODE   PD7
2
#define PIN_DECODE PD6
3
...
4
...
5
6
7
   PORTD |= (1 << PIN_MODE);
8
   PORTD |= (1 << PIN_DECODE);



Bit setzen
1
     register |= ( 1 << Pin );
Bit löschen
1
     register &= ~( 1 << Pin );


Löschen: Bitmanipulation

von Thorsten S. (thorstenst)


Lesenswert?

Hallo Karl-Heinz danke für die Antworten,
dann hoffe ich mal das es dann funktioniert.

Mit der Bitmanipulation hab ich mir das schon angesehen, hatte es auch 
erst so geschrieben nur ohne die defines, für mich war jetzt die 
Binärschreibweise ersteinmal klarer für den Anfang ;).

Werde dann aber auf die Schreibweise umstellen und nochmal versuchen.

Dankö.

von Thorsten S. (thorstenst)


Lesenswert?

So ich hab es jetzt nochmal stundenlang versucht und im Datenblatt 
nachgeschaut.

Mein Code sieht nun so aus:
1
#ifndef F_CPU
2
#define F_CPU 16000000UL // 16 MHz
3
#endif
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
int main(void)
9
{
10
  #define LED          PB0
11
  
12
  #define PIN_MODE     PB1    // ICM PIN9
13
  #define PIN_WRITE    PC0    // ICM PIN8    H=Input Not Loaded, L=Input Loaded
14
  
15
  #define  PIN_ID5_DECODE    PD5    // ICM PIN6    Mode=High => [H=No decode, L=Decode]  
16
  #define PIN_ID6_DECODING   PD6    // ICM PIN5    Mode=High => [H=HEX-Decoding, L=CODE B Decoding]
17
  #define PIN_ID7_DATACOMING PD7    // ICM PIN7    Mode=High => [H=DataComing, L=No Data Coming (ControlWord)]
18
  
19
  /*
20
    ----------------------
21
    NO DECODE - INPUT DATA
22
    ----------------------
23
    
24
    =============================================================
25
    ID7    ID6    ID5    ID4    ID3    ID2    ID1    ID0
26
    -------------------------------------------------------------
27
    !D.P    a      b      c      e      g      f      d
28
    =============================================================
29
  */    
30
  
31
  DDRB |= ((1 << DDB0) || (1<< DDB0));  
32
  DDRC |= (1 << DDC0);  
33
  DDRD |= (0xFF);  
34
  
35
    while(1)
36
    {        
37
    PORTB |= (1 << LED);
38
            
39
    PORTC |= (1 << PIN_WRITE);
40
        
41
    _delay_ms(500);
42
    
43
    PORTB |= (1 << PIN_MODE);
44
    PORTD |= ((1 << PIN_ID5_DECODE) | (1 << PIN_ID7_DATACOMING));
45
    
46
    _delay_ms(200);
47
    
48
    PORTC &= ~(1 << PIN_WRITE);
49
    
50
    _delay_ms(200);
51
    
52
    PORTC |= (1 << PIN_WRITE);
53
    
54
    _delay_ms(200);
55
    
56
    PORTB &= ~(1 << PIN_MODE);
57
    
58
    _delay_ms(200);
59
    
60
    for(int k = 0; k<8; k++)  // 8 Write Data Pulses
61
    {
62
      PORTD |= (1 << PIN_ID6_DECODING); // SEGMENT A => ON           
63
                          
64
      _delay_ms(100);
65
      
66
      PORTC &= ~(1 << PIN_WRITE);
67
    
68
      _delay_ms(100);
69
      
70
      PORTC |= (1 << PIN_WRITE);    
71
      
72
      _delay_ms(100);              
73
    }
74
    
75
    PORTD &= ~(1 << PIN_ID7_DATACOMING);
76
                               
77
    _delay_ms(100);              
78
            
79
    PORTB &= ~(1 << LED);
80
      
81
    _delay_ms(500);    
82
    
83
    }
84
}

Aber Segment A leuchtet immer noch nicht :(.
Ist denn aber der Code nun so richtig? Oder hab ich da immer noch was
falsch verstanden?

Gruß
 Thorsten

von Thorsten S. (thorstenst)


Lesenswert?

Hallo hat keiner mehr einen Rat für mich :(

Ich habe nochmals versucht anstatt der Bitmanipulations-Schreibweise die 
Binärschreibweise zu benutzten. Dabei ist mir lediglich aufgefallen, 
wenn ich für ca. 5 sec. die Spannung wegnehme und wieder anschalte, 
leuchtet das Segment A kurz auf, das war es dann aber auch schon wieder.

Gruß
 Thorsten

von Thorsten S. (thorstenst)


Lesenswert?

Soo vielen Dank Jungs, dass ihr mich habt warten lassen ^^ (ist ernst 
und nicht böse)

Ich habe mir als Debug-Möglichkeit einfach mal 4 LEDs an MODE, WRITE, 
DATA COMING und DECODE gehangen. Und siehe da! MODE ging nie an!

Also nochmals gründlich den Code "studiert" und siehe da falsche Zeile 
gefunden:
1
 DDRB |= ((1 << DDB0) || (1<< DDB0));

sollte so heißen:
1
 DDRB |= ((1 << DDB0) | (1<< DDB1));

Einmal hab ich ein C# Oder (||) verwendet ^^ und dann nochmal DDB0 
anstatt DDB1 wo auch MODE dranhängt grrrr.

Gruß
 Thorsten

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.