PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SDA5708-24 display mit atmega8



robocat
02.02.2009, 14:36
hallo ihr lieben,
eigentlich steht schon alles wissenswerte über dieses display auf der seite vom verehrten Grautier http://www.grautier.com/grautier/index.php?/archives/63-Nokia-DBOX-1-Display-SDA-5708-24.html und auf http://www.sbprojects.com/knowledge/footprints/sda5708.htm, was fehlt, ist höchstens noch ein bisschen c code dazu. vielleicht hilft es ja mal jemandem.

für die pinbelegung siehe die genannten seiten, die 4 leitungen DATA, LOAD, SDCLK und RESET kommen an 4 pins des atmega. ich habe in meinen codebeispielen PC2-PC5 (also port c) verwendet, ist aber nicht schwer, diese leitungen auf andere pins/ports zu verteilen.

der folgende code initialisiert dann das display und schaltet alle leds des ersten segments ein:


#include<avr/io.h>

#define PORT PORTC
#define DDR DDRC

#define RESET PC2
#define SDCLK PC3
#define DATA PC4
#define LOAD PC5

void delay(void)
{
for(int i=0;i<100;i++)
{
asm("NOP");
}
}

void transmitBit(unsigned char bit)
{
// das aktuelle bit an DATA anlegen
if(bit==1)PORT|=(1<<DATA);
else PORT&=~(1<<DATA);

// SDCLK kurz auf high, bissl warten
PORT|=(1<<SDCLK);
delay();

// dann wieder low
PORT&=~(1<<SDCLK);
delay();

}

void transmitByte(unsigned char byte)
{
// load auf low
PORT&=~(1<<LOAD);

// nun die 8 bit des bytes übertragen
for (int x=0; x<=7;x++)
{
unsigned char bit=(byte>>x)&1;
transmitBit(bit);
}

// load wieder auf high
PORT|=(1<<LOAD);
}

int main(void)
{
// ausgänge konfigurieren
DDR=(1<<RESET)|(1<<SDCLK)|(1<<DATA)|(1<<LOAD);

// reset leitung auf high (kein aktiver reset mehr)
PORT|=(1<<RESET);

// kurz warten, wahrscheinlich nicht mal nötig
delay();

// initialisierung
transmitByte(0b11000000);
// addressregister = 1stes segment
transmitByte(0b10100000);
// nun die daten, die 5x7 leds sind damit alle aktiv
transmitByte(0b00011111);
transmitByte(0b00011111);
transmitByte(0b00011111);
transmitByte(0b00011111);
transmitByte(0b00011111);
transmitByte(0b00011111);
transmitByte(0b00011111);

while(1);

return 0;
}

nun möchte man gerne text auf dem display ausgeben. um nicht selber einen font basteln zu müssen, habe ich den von http://www.microsyl.com/nokialcd/nokialcd.html verwendet. allerdings sind da die daten spaltenweise im array, wir bräuchten sie für das SDA5708 aber zeilenweise. mit ein bisschen bitschubserei ist das aber kein problem:


#include<avr/io.h>

#define PORT PORTC
#define DDR DDRC

#define RESET PC2
#define SDCLK PC3
#define DATA PC4
#define LOAD PC5

static const unsigned char FontLookup [][5] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp
{ 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
{ 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
{ 0xc4, 0xc8, 0x10, 0x26, 0x46 }, // %
{ 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
{ 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
{ 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
{ 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
{ 0x14, 0x08, 0x3E, 0x08, 0x14 }, // *
{ 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +
{ 0x00, 0x00, 0x50, 0x30, 0x00 }, // ,
{ 0x10, 0x10, 0x10, 0x10, 0x10 }, // -
{ 0x00, 0x60, 0x60, 0x00, 0x00 }, // .
{ 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
{ 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0
{ 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1
{ 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
{ 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3
{ 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4
{ 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
{ 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6
{ 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
{ 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
{ 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9
{ 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
{ 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
{ 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
{ 0x32, 0x49, 0x59, 0x51, 0x3E }, // @
{ 0x7E, 0x11, 0x11, 0x11, 0x7E }, // A
{ 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B
{ 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C
{ 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D
{ 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E
{ 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F
{ 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G
{ 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H
{ 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I
{ 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J
{ 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K
{ 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L
{ 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M
{ 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N
{ 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O
{ 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P
{ 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q
{ 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R
{ 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
{ 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T
{ 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U
{ 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V
{ 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
{ 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
{ 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [
{ 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55
{ 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]
{ 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
{ 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
{ 0x00, 0x01, 0x02, 0x04, 0x00 }, // '
{ 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
{ 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b
{ 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
{ 0x38, 0x44, 0x44, 0x48, 0x7F }, // d
{ 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
{ 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f
{ 0x0C, 0x52, 0x52, 0x52, 0x3E }, // g
{ 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h
{ 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i
{ 0x20, 0x40, 0x44, 0x3D, 0x00 }, // j
{ 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k
{ 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l
{ 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m
{ 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n
{ 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
{ 0x7C, 0x14, 0x14, 0x14, 0x08 }, // p
{ 0x08, 0x14, 0x14, 0x18, 0x7C }, // q
{ 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r
{ 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
{ 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t
{ 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u
{ 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v
{ 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w
{ 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
{ 0x0C, 0x50, 0x50, 0x50, 0x3C }, // y
{ 0x44, 0x64, 0x54, 0x4C, 0x44 } // z
};

void delay(void)
{
for(int i=0;i<100;i++)
{
asm("NOP");
}
}

void transmitBit(unsigned char bit)
{
if(bit==1)PORT|=(1<<DATA);
else PORT&=~(1<<DATA);

PORT|=(1<<SDCLK);
delay();
PORT&=~(1<<SDCLK);
delay();

}

void transmitByte(unsigned char byte)
{
PORT&=~(1<<LOAD);

for (int x=0; x<=7;x++)
{
unsigned char bit=(byte>>x)&1;
transmitBit(bit);
}

PORT|=(1<<LOAD);
}

void print(char *text)
{
unsigned char cursor=0;
char *p=text;

// reset ausführen
PORT&=~(1<<RESET);
delay();
PORT|=(1<<RESET);
delay();

// initialisierung
transmitByte(0b11000000);

while(*p)
{
// aktuelles zeichen
unsigned char ch=*p;

// segment aktivieren (an cursorposition)
unsigned char byte=0b10100000|cursor;
transmitByte(byte);

// wenn das aktuelle zeichen kein anzeigbares zeichen ist
if ( (ch < 0x20) || (ch > 0x7b) )
{
// Convert to a printable character.
ch = 92;
}

// nun umrechnen und ans display senden (7 zeilen)
for(unsigned char i=0;i<7;i++)
{
byte=0;
for(unsigned char j=0;j<5;j++)
{
byte|=((FontLookup[ch-32][j]>>i)&1)<<(4-j);
}
transmitByte(byte);
}

// cursor um eine stelle nach vorne
cursor++;
if(cursor>7)cursor=0;

// nächster buchstabe
p++;
}

}

int main(void)
{
DDR=(1<<RESET)|(1<<SDCLK)|(1<<DATA)|(1<<LOAD);

print("TEST!\0");

while(1);

return 0;
}

http://katze.dead-men.de/SDA5708-24.jpg

die funktion delay() wartet übrigens sehr grosszügig. da liesse sich noch entschieden was beschleunigen. so sollte es aber auch problemlos auf einem atmega mit 16MHz lauffähig sein.

gruesse von der katz

theborg
02.02.2009, 20:45
Hi feine sache find ich gut die timings stehen auch recht genau auf der sbprojekt seite alerdinks sind diese schon recht harig