MM5450 Treiber mit Atmega8

#1252017
Lesenswert?

Hallo,

Ich hab mir einen MM5450 (Datenblatt: 
http://www.micrel.com/_PDF/mm5450.pdf) gekauft und an meinen Atmega8 
angeschlossen:
An PB0 hängt die Clock-Leitung und an PC0 die Daten-Leitung.
Den "DATA-ENABLE"-Eingang vom MM5450 hab (da er LOW-ACTIVE ist) auf 
Masse gehängt. Die "Brightness-Control" ist über einen 
380-Ohm-Widerstand mit der Vorsorgung (9V) verbunden.
Und zum Testen habe ich mal nur 2 LEDs und zwar an OUTPUT BIT 1 und 2 
des MM5450 über 330-Ohm-Widerstände an 5V-Versorgung angeschlossen.

Mein C Code:
1
#include <avr\io.h>
2
#include <avr\interrupt.h>       
3
#include <avr\signal.h>          
4

5
int n=8;
6
unsigned char z[9]={0,0,0,0,0,0,0,1,1};   // 8 Daten + 1 Startbit (1er)
7

8
// Timer0 Interrupt:
9
ISR(TIMER0_OVF_vect) {    //T0-Overflow ruft IR auf
10

11
if(PB0==0 && n>=0) //d.h. als nächstes kommt eine positive Flanke
12
{
13
 PORTC=z[n];  //Daten
14
 n--;  
15
}
16
else
17
 PORTC=z[0]; //nach 36 Datenbits startet Schieberegister im MM5450
18

19
PORTB ^= (1<<PB0); //CLOCK
20

21
}
22

23
int main(void) {
24
   DDRB = 0xFF;
25
   PORTB=0x00;
26
   DDRC = 0xFF;
27
   sei(); //Interrupts global enable
28
   TCCR0=0x01; //Prescaler /1
29
   TIMSK=0x01; //T0-Interrupt
30
   while(1) {                 
31
   }
32
}

Leider funktioniert aber gar nichts. Die LEDs leuchten einfach nur vor 
sich hin :-(
Was habe ich falsch gemacht?
#1252113
Lesenswert?

Laß dochmal den ganzen Interruptquatsch sein und schreib ne einfache 
Ausgabefunktion.

Anbei mal ein Beispiel für 2  4  7-Segmentanzeigen.
Je ein Treiber-IC steuert 4 Anzeigen und beide ICs sind parallel (Daten 
und Clock vertauscht).
Das geht, da ja erst auf ein Startbit gewartet wird.
D.h. wenn ein IC angesteuert wird, schiebt der andere nur Nullen rein.

Zu Anfang sende ich erstmal 36 Nullbits, damit der Treiber in nem 
definierten Zustand ist.


Peter
Angehängte Dateien:
#1255059
Lesenswert?

Ich habe meinen Code jetzt ohne Interrupts geschrieben. Kann mir jemand 
sagen, ob das so stimmt?
Ich möchte nur die LED am ersten Pin einschalten.
1
#include <avr\io.h>
2
#include <avr\interrupt.h>
3
#include <avr\signal.h>
4

5
int n=36;
6
unsigned char z[36]={0x00,0x00,0x00,0x00,
7
              0x00,0x00,0x00,0x00,
8
              0x00,0x00,0x00,0x00,
9
              0x00,0x00,0x00,0x00,
10
              0x00,0x00,0x00,0x00,
11
              0x00,0x00,0x00,0x00,
12
              0x00,0x00,0x00,0x00,
13
              0x00,0x00,0x00,0x00,
14
              0x00,0x00,0x01,0x01};
15

16
void my_function(void) {
17

18
   do
19
   {
20
     PORTB=0x00;
21
     PORTC=z[n];
22
     PORTB=0x01;
23
     n--;
24
   }while(n>=0);
25
  
26
}
27

28
// ***********************************************************
29
// Main program
30
//
31
int main(void) {
32

33
   while(1) {
34
      my_function();
35
   }
36

37
}
#1255151
Lesenswert?

Ich sehe grad im Datenblatt, der MM5450 ist ja schnarchlahm.
Beim 8051 war das noch nicht kritisch.
Welchen Takt hast Du denn?

Probier mal das hier:
1
#define F_CPU   16e6            // 16MHz
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5

6
//                      Access bits like variables:
7
struct bits {
8
  uint8_t b0:1;
9
  uint8_t b1:1;
10
  uint8_t b2:1;
11
  uint8_t b3:1;
12
  uint8_t b4:1;
13
  uint8_t b5:1;
14
  uint8_t b6:1;
15
  uint8_t b7:1;
16
} __attribute__((__packed__));
17

18
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
19
#define SBIT(x,y)       SBIT_(x,y)
20

21

22
#define DAT             SBIT( PORTC, PC0 )
23
#define DAT_DDR         SBIT( DDRC,  PC0 )
24
#define CLK             SBIT( PORTB, PB0 )
25
#define CLK_DDR         SBIT( DDRB,  PB0 )
26

27

28
void mm5450_wr( uint8_t num, uint8_t val )
29
{
30
  do{
31
    CLK = 0;
32
    DAT = 0;
33
    if( val & 0x01 )            // LSB zuerst
34
      DAT = 1;
35
    val >>= 1;
36
    _delay_us( 1 );             // MM5450 ist schnarchlahm (0,5MHz)
37
    CLK = 1;
38
    _delay_us( 1 );             // MM5450 ist schnarchlahm (0,5MHz)
39
  }while( --num );
40
    CLK = 0;
41
}
42

43
int main( void )
44
{
45
  CLK_DDR = 1;
46
  DAT_DDR = 1;
47
  mm5450_wr( 35, 0 );           // bringe MM5450 in definierten Anfangszustand
48

49
  for(;;){
50
    mm5450_wr( 1, 1 );          // startbit
51
    mm5450_wr( 8, 0xFF );       // Bit 1..8 = ein
52
    mm5450_wr( 8, 0xFF );       // Bit 9..16 = ein
53
    mm5450_wr( 8, 0xFF );       // Bit 17..24 = ein
54
    mm5450_wr( 8, 0xFF );       // Bit 25..32 = ein
55
    mm5450_wr( 3, 0x07 );       // Bit 33..35 = ein
56
    _delay_ms( 1000 );
57

58
    mm5450_wr( 1, 1 );          // startbit
59
    mm5450_wr( 8, 0x00 );       // Bit 1..8 = aus
60
    mm5450_wr( 8, 0x00 );       // Bit 9..16 = aus
61
    mm5450_wr( 8, 0x00 );       // Bit 17..24 = aus
62
    mm5450_wr( 8, 0x00 );       // Bit 25..32 = aus
63
    mm5450_wr( 3, 0x00 );       // Bit 33..35 = aus
64
    _delay_ms( 1000 );
65
  }
66
}


Peter

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