Forum: Mikrocontroller und Digitale Elektronik MAX7219 avr-gcc


von Stefan S. (sschultewolter)


Lesenswert?

Hallo,

meine DOT MATRIX 8x8 Displays CC sind heute gekommen, jedoch habe ich 
noch Probleme mit der Ansteuerung.

Die Anzeige macht leider nichts. Ich nutze hierfür einen Atmega328P mit 
externem 16MHz Quarz.

Ich kann gleich noch die Auswertung vom Logik Level Analyzer 
nachliefern. Muss nur gerade schaun, wo ich den hin verstaut habe.
Edit: 
https://www.dropbox.com/s/lqaut9ek59cvo7o/Screenshot%202014-10-21%2000.21.44.png?dl=0
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
/*
5
8x8 DOT MATRIX CC
6
PIN  13 |  3 |  4 | 10 |  5 | 11 | 15 | 16
7
COL  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8
8
9
PIN  9 | 14 |  8 | 12 |  1 |  7 |  2 |  5
10
ROW  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8
11
*/
12
13
#define MAX7219_DDR      DDRD
14
#define MAX7219_PORT    PORTD
15
16
#define MAX7219_CLK      (1<<PIND4)    // MAX7219.CLK
17
#define MAX7219_LOAD    (1<<PIND3)    // MAX7219.LOAD
18
#define MAX7219_DIN      (1<<PIND2)    // MAX7219.DIN
19
20
#define NUM_MAX7219      1        // Anzahl MAX7219
21
#define MAX7219_BRIGHTNESS  7        // Helligkeit der MAX7219 beim Init
22
23
// Register MAX7219
24
#define MAX7219_NO_OP    0x00
25
#define MAX7219_DIGIT_0    0x01
26
#define MAX7219_DIGIT_1    0x02
27
#define MAX7219_DIGIT_2    0x03
28
#define MAX7219_DIGIT_3    0x04
29
#define MAX7219_DIGIT_4    0x05
30
#define MAX7219_DIGIT_5    0x06
31
#define MAX7219_DIGIT_6    0x07
32
#define MAX7219_DIGIT_7    0x08
33
#define MAX7219_DEC_MODE  0x09
34
#define MAX7219_INTENSITY  0x0A
35
#define MAX7219_SCAN_LIMIT  0x0B
36
#define MAX7219_SHUTDOWN  0x0C
37
#define MAX7219_DISP_TEST  0x0F
38
39
void max7219_init(void);
40
void max7219_fill(uint8_t data);
41
static void max7219_sendByte(uint8_t data);
42
void max7219_send(uint8_t num_max7219, uint8_t reg, uint8_t data);
43
44
int main(void)
45
{
46
  max7219_init();
47
  max7219_fill(0x00);
48
  
49
  while(1)
50
  {
51
    max7219_send(0, MAX7219_DIGIT_0, 0b10000001);
52
    max7219_send(0, MAX7219_DIGIT_1, 0b01000010);
53
    max7219_send(0, MAX7219_DIGIT_2, 0b00100100);
54
    max7219_send(0, MAX7219_DIGIT_3, 0b00011000);
55
    max7219_send(0, MAX7219_DIGIT_4, 0b00011000);
56
    max7219_send(0, MAX7219_DIGIT_5, 0b00100100);
57
    max7219_send(0, MAX7219_DIGIT_6, 0b01000010);
58
    max7219_send(0, MAX7219_DIGIT_7, 0b10000001);
59
    _delay_ms(100);
60
  }
61
}
62
63
void max7219_init(void)
64
{
65
  MAX7219_DDR |= (MAX7219_CLK | MAX7219_LOAD | MAX7219_DIN);
66
67
  MAX7219_PORT |= (MAX7219_LOAD);
68
  MAX7219_PORT &= ~(MAX7219_CLK | MAX7219_DIN);
69
70
  for(uint8_t num_max7219 = 0; num_max7219 < NUM_MAX7219; num_max7219++)
71
  {
72
    max7219_send(num_max7219, MAX7219_SHUTDOWN, 1);
73
    max7219_send(num_max7219, MAX7219_DISP_TEST, 0);
74
    max7219_send(num_max7219, MAX7219_DEC_MODE, 0);
75
    max7219_send(num_max7219, MAX7219_INTENSITY, MAX7219_BRIGHTNESS);
76
    max7219_send(num_max7219, MAX7219_SCAN_LIMIT, 7);
77
  }
78
}
79
80
void max7219_fill(uint8_t data)
81
{
82
  for(uint8_t num_max7219 = 0; num_max7219 < NUM_MAX7219; num_max7219++)
83
  {
84
    for(uint8_t i = 0; i < 8; i++)
85
    max7219_send(num_max7219, MAX7219_DIGIT_0 + i, data);
86
  }
87
}
88
89
static void max7219_sendByte(uint8_t data)
90
{
91
  int8_t j = 0;
92
93
  for(j = 7; j >= 0; j--)
94
  {
95
    MAX7219_PORT &= ~MAX7219_CLK;
96
    
97
    if(data & (1 << j))  MAX7219_PORT |= MAX7219_DIN;
98
    else        MAX7219_PORT &= ~MAX7219_DIN;
99
    
100
    MAX7219_PORT |= MAX7219_CLK;
101
  }
102
}
103
104
void max7219_send(uint8_t num_max7219, uint8_t reg, uint8_t data)
105
{
106
  uint8_t i = 0;
107
108
  if (num_max7219 < NUM_MAX7219)
109
  {
110
    MAX7219_PORT &= ~MAX7219_LOAD;
111
112
    for(i = num_max7219; i < (NUM_MAX7219 - 1); i++)
113
    {
114
      max7219_sendByte(MAX7219_NO_OP);  // NO_OP Register
115
      max7219_sendByte(MAX7219_NO_OP);  // NO_OP Data
116
    }
117
    
118
    max7219_sendByte(reg);
119
    max7219_sendByte(data);
120
121
    for(i = 0; i < num_max7219; i++)
122
    {
123
      max7219_sendByte(MAX7219_NO_OP);  // NO_OP Register
124
      max7219_sendByte(MAX7219_NO_OP);  // NO_OP Data
125
    }
126
127
    MAX7219_PORT |= MAX7219_LOAD;
128
  }
129
}

: Bearbeitet durch User
von g457 (Gast)


Lesenswert?

>    for(i = 0; i < num_max7219; i++)
>    {
>      max7219_sendByte(MAX7219_NO_OP);  // NO_OP Register
>      max7219_sendByte(MAX7219_NO_OP);  // NO_OP Data
>    }

Sicher dass Du hier immer alls mit noop zubügeln willst?

von Karl H. (kbuchegg)


Lesenswert?

Hast du schon mal einfach nur das Display-Test Kommando gesendet?
Damit umgehst du erst mal alle Konfigurationssachen und kannst sicher 
stellen, dass die Matrix auch korrekt angeschlossen ist.
1
Portbits auf Ausgang
2
3
Load auf Low
4
5
Data auf High
6
16 Pulse auf der Clock Leitung (können auch 17 sein, ist nicht tragisch und umgeht erst mal Flankenfehler)
7
8
Load wieder auf High

und alle LED sollten leuchten.

: Bearbeitet durch User
von Stefan S. (sschultewolter)


Lesenswert?

Hallo,

mit folgender Dauerschleife kann ich die einzelnen Reihen nacheinander 
zum leuchten bringen. Leider habe ich zu diesem Thema auch relativ 
wenige Infos gefunden, da unter LED Matrix o.ä. hauptsächlich nur 
normale Multiplexing Lösungen gefunden werden.
1
  while(1)
2
  {
3
    max7219_send(0, MAX7219_DISP_TEST, 1);
4
    _delay_ms(100);  
5
  }


Edit:
Karl-Heinz, meinst du das so?
Da tut sich nichts
1
int main(void)
2
{
3
  //max7219_init();
4
  MAX7219_DDR |= (1 << MAX7219_CLK) | (1 << MAX7219_LOAD) | (1 << MAX7219_DIN);
5
  
6
  MAX7219_PORT &= ~(1 << MAX7219_LOAD);
7
  MAX7219_PORT |= (1 << MAX7219_DIN);
8
  
9
  for(int i = 0; i <= 16; i++)
10
  {
11
    MAX7219_PORT ^= (1 << MAX7219_CLK);
12
    //_delay_ms(1);
13
  }
14
  
15
  MAX7219_PORT |= (1 << MAX7219_LOAD);
16
  
17
  while(1)
18
  {

: Bearbeitet durch User
von Stefan S. (sschultewolter)


Lesenswert?

Hab den Code noch einmal etwas eingekürzt.

Vorab hier die Pegelauswertung
https://www.dropbox.com/s/hodknjfz4wapqpi/Screenshot%202014-10-21%2002.39.25.png?dl=0

Verdrahtung noch einmal geprüft nach diesen Unterlagen
(Einzeln Ansteuern über 1k ohne den MAX7219 ging auch und wurde richtig 
angezeigt)
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
/*
5
8x8 DOT MATRIX CC
6
PIN  13 |  3 |  4 | 10 |  5 | 11 | 15 | 16
7
COL  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8
8
9
PIN  9 | 14 |  8 | 12 |  1 |  7 |  2 |  5
10
ROW  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8
11
*/
12
13
#define MAX7219_DDR      DDRD
14
#define MAX7219_PORT    PORTD
15
16
#define MAX7219_CLK      PIND4    // MAX7219.CLK
17
#define MAX7219_LOAD    PIND3    // MAX7219.LOAD
18
#define MAX7219_DIN      PIND2    // MAX7219.DIN
19
20
#define NUM_MAX7219      1        // Anzahl MAX7219
21
#define MAX7219_BRIGHTNESS  15        // Helligkeit der MAX7219 beim Init
22
23
// Register MAX7219
24
#define MAX7219_NO_OP    0x00
25
#define MAX7219_DIGIT_0    0x01
26
#define MAX7219_DIGIT_1    0x02
27
#define MAX7219_DIGIT_2    0x03
28
#define MAX7219_DIGIT_3    0x04
29
#define MAX7219_DIGIT_4    0x05
30
#define MAX7219_DIGIT_5    0x06
31
#define MAX7219_DIGIT_6    0x07
32
#define MAX7219_DIGIT_7    0x08
33
#define MAX7219_DEC_MODE  0x09
34
#define MAX7219_INTENSITY  0x0A
35
#define MAX7219_SCAN_LIMIT  0x0B
36
#define MAX7219_SHUTDOWN  0x0C
37
#define MAX7219_DISP_TEST  0x0F
38
39
void max7219_init(void);
40
void max7219_clock_out(uint8_t data);
41
void max7219_send(uint8_t num_max7219, uint8_t reg, uint8_t data);
42
void max7219_clear(uint8_t num_max7219);
43
44
int main(void)
45
{
46
  max7219_init();
47
48
  while(1)
49
  {
50
    max7219_send(0, MAX7219_DIGIT_0, 0b10011001);
51
    _delay_ms(20);
52
  }
53
}
54
55
void max7219_init(void)
56
{
57
  MAX7219_DDR |= (1 << MAX7219_CLK) | (1 << MAX7219_LOAD) | (1 << MAX7219_DIN);
58
59
  MAX7219_PORT |= (1 << MAX7219_LOAD);
60
  MAX7219_PORT &= ~((1<< MAX7219_CLK) | (1 << MAX7219_DIN));
61
62
  for(uint8_t num_max7219 = 0; num_max7219 < NUM_MAX7219; num_max7219++)
63
  {
64
    //max7219_send(num_max7219, MAX7219_DISP_TEST, 1);
65
    max7219_send(num_max7219, MAX7219_DEC_MODE, 0);
66
    max7219_send(num_max7219, MAX7219_SCAN_LIMIT, 7);
67
    max7219_send(num_max7219, MAX7219_INTENSITY, MAX7219_BRIGHTNESS);
68
    max7219_clear(num_max7219);
69
    max7219_send(num_max7219, MAX7219_SHUTDOWN, 1); // 1 = wakeup; 0 = shutdown
70
  }
71
}
72
73
void max7219_clock_out(uint8_t data)
74
{
75
  for(uint8_t i = 0; i < 8; i++)
76
  {
77
    // CLK auf LOW setzen
78
    MAX7219_PORT &= ~(1 << MAX7219_CLK);
79
    
80
    if(data & (1 << (7 - i))) MAX7219_PORT |= (1 << MAX7219_DIN);
81
    else MAX7219_PORT &= ~(1 << MAX7219_DIN);
82
    
83
    // CLK auf HIGH setzen, Daten uebernehmen
84
    MAX7219_PORT |= (1 << MAX7219_CLK);
85
  }
86
}
87
88
void max7219_send(uint8_t num_max7219, uint8_t reg, uint8_t data)
89
{
90
  //reg &= 0x0F; / /Obere 4 Bits der Adresse werden nicht gelesen.
91
  
92
  // LOAD auf LOW setzen
93
  MAX7219_PORT &= ~(1 << MAX7219_LOAD);
94
  
95
  max7219_clock_out(reg);
96
  max7219_clock_out(data);
97
  
98
  // LOAD auf HIGH, steigende Flanke uebernimmt Daten in adressiertes Register
99
  MAX7219_PORT |= (1 << MAX7219_LOAD);
100
}
101
102
void max7219_clear(uint8_t num_max7219)
103
{
104
  for(uint8_t i = 1; i < 9; i++) max7219_send(num_max7219, i, 0);
105
}
1
max7219_send(0, MAX7219_DIGIT_0, 0b10011001);
 Bewirkt, das jede Spalte durchlaufen wird einzeln und dabei alle Leds 
innerhalb dieser Spalte angesprochen werden. Irgendwie passt das vorne 
und hinten nicht ;(





EDIT:
Funktioniert. Ich hab bei dem ganzen umstecken irgendwann mal 
zwischenzeitig CLK und LOAD vertauscht. Viel mir gerade beim näheren 
betrachten der Anaylse auf -.-

: Bearbeitet durch User
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.