2 Stellige 7 Segment Anzeige

OP #3641696
Lesenswert?

Hallo,

Ich würde gerne eine 2 stellige Anzeige mit 2 7 Segment Anzeigen 
programmien.

Sie soll von 00 - 99 hochzählen. Die Schaltung läuft im 
Multiplexbetrieb.

Wie kann ich die 100 Zahlen auf die codierung der Anzeige bringen ohne 
für jede einzelne zahl eine eigene Funktion zu schreiben ?

Programmiert wird auf einem MSP430G2553.


Danke euch schon mal
Gast #3641714
Lesenswert?

In dem du die 2 Ziffern einzeln behandelst.

char ziffer[]={0x7D,0x30,0x6D,0x79,0x33,0x5D,0x5F,0x70,0x7B,0x7B};

void main(void)
{
   DDRB=DDRD=0xFF;
   while(1) for(n=0;n<100;n++)
  {
    PORTB=ziffer[n%10];
    PORTD=ziffer[n/10];
    _delay_ms(1000);
  }
}

Ist also nicht wirklich schwer, aber der Lernweg bis dahin noch weit.
OP #3641795
Lesenswert?

Danke euch schon mal.

Hab das auch soweit erreicht, nur stehe ich vor dem Problem es Sinnvoll 
auf die Anzeige zu übertragen.

Wenn ich von 0-9 hochzähle , möchte ich dass auf der Zehnerstelle immer 
eine 0 steht , also 00, 01, 02,03, usw. Ich schaffe es nur nicht dass 
die Zehnerstelle, also die 0 steht und nur die Einerstelle aktualisiert 
wird.
Bei mir läuft es total schnell durch und man kann auch erkennen dass die 
Zahlen immer kurz ausgehen.

Also bleibt noch die Frage wie ich es umsetzen kann dass zb 9 Sekunden 
hoch gezählt werden ohne dass eine der Beiden stellen immer aus ist.


Gruß
#3641834
Lesenswert?

Robert I. schrieb:
> Bei mir läuft es total schnell durch und man kann auch erkennen dass die
> Zahlen immer kurz ausgehen.
Zeig mal den Code. Kann es sein, dass du mit irgendwelchen Delays das 
Multiplexen unterbrichst?

> Also bleibt noch die Frage wie ich es umsetzen kann dass zb 9 Sekunden
> hoch gezählt werden ohne dass eine der Beiden stellen immer aus ist.
1
PORTB=ziffer[n%10];
2
if(ziffer>9)
3
  PORTD=ziffer[n/10];
4
else
5
  PORTD=0x00;
#3641956
Lesenswert?

Für ein 4-stelliges 7-Segment sieht es als Code für AVR so aus:
1
// cathode pins for digit selection
2
volatile static uint8_t digit[4]={
3
    0b00000100,
4
    0b00001000,
5
    0b00010000,
6
    0b00100000 };
7

8
// 'databse' of digits
9
volatile static uint8_t lightup[10]={
10
    0b00111111,  // 0
11
    0b00000110,  // 1
12
    0b01011011,  // 2
13
    0b01001111,  // 3
14
    0b01100110,  // 4
15
    0b01101101,  // 5
16
    0b01111101,  // 6
17
    0b00000111,  // 7
18
    0b01111111,  // 8
19
    0b01101111 };  // 9
20

21
  int tempdigit;  // dissect and show the number
22
  for (int8_t count=3; count>=0; count--) {
23
    tempdigit=temp % 10;
24
       PORTD &= ~(digit[count]);  // select digit
25
       PORTC |= (lightup[tempdigit] & numbitmaska);
26
       PORTD |= (lightup[tempdigit] & numbitmaskd);
27
       if (!(showyear) & !(showdate) & !(showvcc) & !(showtemp) & (count==1) & toggle) PORTD |= 0x80;  // set dot
28
       if (showdate & ((count==1)|(count==3))) PORTD |= 0x80;  // set dot
29
       if (showvcc & (count==0)) PORTD |= 0x80;  // set dot
30
       if (showtemp & (count==1)) PORTD |= 0x80;  // set dot
31
       temp /= 10;
32
    PORTC &= ~(numbitmaska);  // Set all pins A0-A5 HIGH
33
    PORTD &= ~(numbitmaskd);  // Set D2-D5 and D6+D7 HIGH
34
    PORTD |= digbitmask;  // deselect digit
35
  }

Die Schleife musst du auf zwei Durchläufe reduzieren, die if-Bedingungen 
zur Aktivierung des Dezimalpunkts kannst du löschen. Die Funktion unter 
den Arrays läuft bei mir im Timer-Interrupt, einmal pro Millisekunde.
OP #3642191
Lesenswert?

Bei mir funktionierts es jetzt.

Hab es geschafft dass die Anzeige von 00 bis 99 zählt. Vllt nicht sehr 
elegalnt und effektiv gelöst aber es geht.

Ist es normal dass ich immer einen leichten Schatten habe? Also wenn ich 
Zb die Zahl 19 ausgebe habe ich in der Anzeige für den 1er einen 
leichten Schatten vom 9er drinnen?
OP #3642216
Lesenswert?

Ja das denke ich mir selber auch , nur ich wollte keinen Code aus dem 
Internet nehmen und den nur einfügen, ich will solche sachen selber 
lösen.

Ich weiss halt nicht ob man es auf dem Foto erkennen kann, da sollte 
eigentlich 16 stehen, mit dem Auge erkennt man es zwar besser aber ihr 
könnt euch sicher denken um was es geht.
Angehängte Dateien:
#3642261
Lesenswert?

Robert I. schrieb:
> Die Schaltung läuft im
> Multiplexbetrieb.

Multiplex benötigt zwingend einen Timerinterrupt, alles andere ist 
Quatsch.

Nur wenige Uneinsichtige versuchen es mit einem Delay im Main zu 
erzwingen, was nur doppelte Arbeit bedeutet.
Auch als Anfänger muß niemand in die Sackgasse hineinfahren, er darf 
auch gleich den richtigen Weg nehmen.
OP #3642416
Lesenswert?

Ja gut ich habs ohne Interrupt gemacht da ich da noch nicht so 
durchblicke.

Sieht so bei mir aus :
1
#include <msp430.h> 
2
/*
3
 * Developer : XXXXXXXXXXXXXX
4
 * Software : 2 Digit on 7 Segment Displays counting from 00 to 99
5
 * Version : v2
6
 * Date : 04.May.2014
7
 *
8
 */
9

10

11

12
#define Display  P1OUT
13
#define NULL  0x3F
14
#define ONE    0x0C
15
#define TWO    0x5B
16
#define THREE  0x5E
17
#define FOUR  0x6C
18
#define FIVE  0x76
19
#define SIX    0x77
20
#define SEVEN  0x1C
21
#define EIGHT  0xFF
22
#define NINE  0xFE
23

24
#define Digit1  P2OUT = 0x01
25
#define Digit2  P2OUT = 0x02
26

27

28

29

30
int InputNumber = 0;
31
int FirstNumber = 0;  //Unit Position
32
int SecondNumber = 0;  //Tens
33
int DelayCounter = 0;
34
int Digit1AcitveNumber = 0;
35
int Digit2AcitveNumber = 0;
36

37

38

39
int main(void)
40
{
41
    WDTCTL = WDTPW | WDTHOLD;  // Stop watchdog timer
42
  
43
    P1DIR = 0xFF;  //P1 --> Output
44
    P2DIR = 0x03;  //P2.0 + P2.1 --> Output
45
    P2OUT = 0;
46

47
    while(1)
48
    {
49
    for(InputNumber=InputNumber;InputNumber<100;InputNumber++)
50
    {
51
      FirstNumber = InputNumber % 10;
52
      SecondNumber = InputNumber / 10;
53
      switch(FirstNumber)
54
      {
55
        case 0:  Digit1AcitveNumber = NULL;
56
        break;
57
        case 1:  Digit1AcitveNumber = ONE;
58
        break;
59
        case 2:  Digit1AcitveNumber = TWO;
60
        break;
61
        case 3:  Digit1AcitveNumber = THREE;
62
        break;
63
        case 4:  Digit1AcitveNumber = FOUR;
64
        break;
65
        case 5:  Digit1AcitveNumber = FIVE;
66
        break;
67
        case 6:  Digit1AcitveNumber = SIX;
68
        break;
69
        case 7:  Digit1AcitveNumber = SEVEN;
70
        break;
71
        case 8:  Digit1AcitveNumber = EIGHT;
72
        break;
73
        case 9:  Digit1AcitveNumber = NINE;
74
        break;
75
      }
76
      switch(SecondNumber)
77
      {
78
        case 0:  Digit2AcitveNumber = NULL;
79
        break;
80
        case 1:  Digit2AcitveNumber = ONE;
81
        break;
82
        case 2:  Digit2AcitveNumber = TWO;
83
        break;
84
        case 3:  Digit2AcitveNumber = THREE;
85
        break;
86
        case 4:  Digit2AcitveNumber = FOUR;
87
        break;
88
        case 5:  Digit2AcitveNumber = FIVE;
89
        break;
90
        case 6:  Digit2AcitveNumber = SIX;
91
        break;
92
        case 7:  Digit2AcitveNumber = SEVEN;
93
        break;
94
        case 8:  Digit2AcitveNumber = EIGHT;
95
        break;
96
        case 9:  Digit2AcitveNumber = NINE;
97
        break;
98
      }
99
      DelayCounter = 0;
100
      while(DelayCounter<500)
101
      {
102
        Display = Digit1AcitveNumber;
103
        Digit1;
104
        _delay_cycles(1000);
105
        Display = Digit2AcitveNumber;
106
        Digit2;
107
        _delay_cycles(1000);
108
        DelayCounter++;
109
      }
110
    }
111
    int i = 0;
112
    for(i=0;i<1000;i++)
113
    {
114
      P2OUT = 0x03;
115
      P1OUT = 0xFF;
116

117
    }
118
    InputNumber = 0;
119

120

121
    }
122
}


Vllt kann mir ja mal jemand zeigen wie es effektiver und kürzer mithilfe 
von Interrupts wird.

Danke euch !!
Gast #3643607
Lesenswert?

Robert I. schrieb:
> Vllt kann mir ja mal jemand zeigen wie es effektiver und kürzer mithilfe
> von Interrupts wird.

Der code wird auch deutlich kürzer, wenn du ein array statt der case 
structure für die digits nehmen würdest...

Ausserdem fände ich es logischer die Zehnerstelle "Digit1" und die 
Einerstelle "Digit2" zu nennen...

1
const unsigned char digit_port_data[10] = { 
2
  0x3F, // 0
3
  0x0C, // 1
4
  0x5B, // 2
5
  0x5E, // 3
6
  0x6C, // 4
7
  0x76, // 5
8
  0x77, // 6
9
  0x1C, // 7
10
  0xFF, // 8
11
  0xFE  // 9
12
};
13

14

15
()
16

17
Digit1AcitveNumber = digit_port_data[InputNumber / 10];
18
Digit2AcitveNumber = digit_port_data[InputNumber % 10];

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