AVR и графический ЖКИ на KS0108 - HELP WANTED!!!
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено stupid user 07 октября 2003 г. 11:42

Блин, не могу понять в чем проблема с графическим ЖКИ на samsung'овских
контроллерах KS0108... :(( Вместо того, чтобы выводить точку - выводит
в том месте вертикальную черточку, до 8 пикселов в длинну, неравномерно
заполненную точками (причем, почему-то в зависимости от координаты X).
Т.е. вместо точки "." на диплее я вижу что-то вроде "|". Помогите кто-
нибудь понять, в чем косяк??? Вот кусок кода для AVR с используемыми функциями
(точку должна рисовать glcd_dot()).


// LCD data port definition

#define LCD_DATA PORTA
#define LCD_DATA_P PINA
#define LCD_DATA_D DDRA

// LCD control leds definition

#define LCD_CONTROL_LEDS PORTC
#define LCD_CONTROL_LEDS_P PINC
//#define LCD_CONTROL_LEDS_D DDRC
#define LCD_CONTROL_LEDS2 PORTD
#define LCD_CONTROL_LEDS2_P PIND
#define LCD_CONTROL_LEDS2_D DDRD
#define LCD_DI PD7
#define LCD_RW PC7
#define LCD_E PC6
#define LCD_CS1 PC4
#define LCD_CS2 PC3
#define LCD_RST PC2

// other LCD definitions

#define LCD_CMD_CTRL 0
#define LCD_CMD_DATA 1

// LCD Registers

#define X_ADRESS 0xB8 // Adress base for Page 0
#define Y_ADRESS 0x40 // Adress base for Y0
#define START_LINE 0xC0 // Adress base for line 0
#define DISPLAY_ON 0x3F // Turn display on
#define DISPLAY_OFF 0x3E // Turn display off

// General use definitions

#define RIGHT 0
#define LEFT 1
#define BUSY 0x80

// ***
// *** LOCAL FUNCTIONS
// ***

// Tempo for the LCD timing

void e_pause(unsigned long u32Duration) {
unsigned long u32Delay;
for (u32Delay=0; u32Delay return;
}

// Function waits until busy flag is ready

void e_wait(void) {
// setup data port for input
LCD_DATA_D=0x00;
#ifdef LCD_CONTROL_LEDS2_D
setbit(LCD_CONTROL_LEDS2_D,LCD_DI);
#endif
// set command mode
clrbit(LCD_CONTROL_LEDS2,LCD_DI);
#ifdef LCD_CONTROL_LEDS_D
setbit(LCD_CONTROL_LEDS_D,LCD_RW);
setbit(LCD_CONTROL_LEDS_D,LCD_E);
#endif
setbit(LCD_CONTROL_LEDS,LCD_RW); // RW=1
// generate strobe
clrbit(LCD_CONTROL_LEDS,LCD_E);
e_pause(1);
setbit(LCD_CONTROL_LEDS,LCD_E);
// mask the other status bits and test the BUSY bit
while (LCD_DATA&0x7F==BUSY);

return;
}

// Function outputs a single character or command to LCD.
// Entry: char reg - register selector, can be one of two values: LCD_CMD_CTRL or
// LCD_CMD_DATA
// unsigned char data - LCD command (if LCD_CMD_CTRL parameter specified) or
// single character (if LCD_CMD_DATA paremeter specified)

void ks_putdata(char reg, unsigned char data) {
_CLI();
e_wait(); // wait until LCD not busy
// set data mode
#ifdef LCD_CONTROL_LEDS2_D
setbit(LCD_CONTROL_LEDS2_D,LCD_DI);
#endif
// data mode?
if (reg==LCD_CMD_DATA) {
setbit(LCD_CONTROL_LEDS2,LCD_DI); // DI=1 (data)
// instruction mode?
} else {
clrbit(LCD_CONTROL_LEDS2,LCD_DI); // DI=0 (command)
}
// set write mode
#ifdef LCD_CONTROL_LEDS_D
setbit(LCD_CONTROL_LEDS_D,LCD_RW);
setbit(LCD_CONTROL_LEDS_D,LCD_E);
#endif
clrbit(LCD_CONTROL_LEDS,LCD_RW); // RW=0 (write mode)
// generate strobe
setbit(LCD_CONTROL_LEDS,LCD_E);
// write data to LCD
LCD_DATA_D=0xff; // setup data port for output
LCD_DATA=data;
e_pause(2);
clrbit(LCD_CONTROL_LEDS,LCD_E);
_SEI();

return;
}

// Function reads data from LCD
// Entry: char reg - register selector, can be one of two values: LCD_CMD_CTRL or
// LCD_CMD_DATA
// Exit: unsigned char = ks_getdata();

unsigned char ks_getdata(char reg) {
unsigned char data;

_CLI();
// setup data port for input
LCD_DATA_D=0x00;
// set read mode
#ifdef LCD_CONTROL_LEDS_D
setbit(LCD_CONTROL_LEDS_D,LCD_RW);
setbit(LCD_CONTROL_LEDS_D,LCD_E);
#endif
setbit(LCD_CONTROL_LEDS,LCD_RW); // RW=1
// set data mode
#ifdef LCD_CONTROL_LEDS2_D
setbit(LCD_CONTROL_LEDS2_D,LCD_DI);
#endif
// data mode?
if (reg==LCD_CMD_DATA) {
setbit(LCD_CONTROL_LEDS2,LCD_DI); // DI=1 (data)
// instruction mode?
} else {
clrbit(LCD_CONTROL_LEDS2,LCD_DI); // DI=0 (command)
}
// generate strobe
setbit(LCD_CONTROL_LEDS,LCD_E);
e_pause(2);
data=LCD_DATA;
// switch off LCD_E and LDC_RW
clrbit(LCD_CONTROL_LEDS,LCD_E);
clrbit(LCD_CONTROL_LEDS,LCD_RW); // RW=0
// setup data port for output
LCD_DATA_D=0xff;
_SEI();

return data; // return the read data
}

// Routine selects the side of the LCD by selecting one of two chips
// Entry: u8LcdSide = LEFT or RIGHT

void ks_selectchip(unsigned char u8LcdSide) {
// zero strobe
#ifdef LCD_CONTROL_LEDS_D
LCD_CONTROL_LEDS_D|=(bit(LCD_RW)|bit(LCD_E)|bit(LCD_CS1)|bit(LCD_CS2)|bit(LCD_RST));
#endif
clrbit(LCD_CONTROL_LEDS,LCD_E);
// set command mode
#ifdef LCD_CONTROL_LEDS2_D
setbit(LCD_CONTROL_LEDS2_D,LCD_DI);
#endif
clrbit(LCD_CONTROL_LEDS2,LCD_DI);
setbit(LCD_CONTROL_LEDS,LCD_RW); // RW=1 (read mode)
// switch to right?
if(u8LcdSide==RIGHT) {
clrbit(LCD_CONTROL_LEDS,LCD_CS1); // CS1=0, CS2=1
setbit(LCD_CONTROL_LEDS,LCD_CS2);
// switch to left?
} else {
setbit(LCD_CONTROL_LEDS,LCD_CS1); // CS1=1, CS2=0
clrbit(LCD_CONTROL_LEDS,LCD_CS2);
}
ks_putdata(LCD_CMD_CTRL,Y_ADRESS); // set column to 0

return;
}

// ***
// *** GLOBAL FUNCTIONS
// ***

// Routine initializes graphic LCD

void glcd_init(void) {
_CLI();
// set command mode
clrbit(LCD_CONTROL_LEDS2,LCD_DI);
// zero strobe and other control pins
LCD_CONTROL_LEDS&=~(bit(LCD_RST)|bit(LCD_RW)|bit(LCD_E)|bit(LCD_CS1)|bit(LCD_CS2));
#ifdef LCD_CONTROL_LEDS2_D
setbit(LCD_CONTROL_LEDS2_D,LCD_DI);
#endif
#ifdef LCD_CONTROL_LEDS_D
LCD_CONTROL_LEDS_D|=(bit(LCD_RST)|bit(LCD_RW)|bit(LCD_E)|bit(LCD_CS1)|bit(LCD_CS2));
#endif

// initialize instructions/data port
LCD_DATA=0;
LCD_DATA_D=0xff; // setup data port for output

// make pause with LCD_RST high
setbit(LCD_CONTROL_LEDS,LCD_RST);
e_pause(10);
// make pause with LCD_RST low
clrbit(LCD_CONTROL_LEDS,LCD_RST);
e_pause(10);
setbit(LCD_CONTROL_LEDS,LCD_RST);
_SEI();

// initialize LCD microcontroller
ks_selectchip(LEFT);
ks_putdata(LCD_CMD_CTRL,DISPLAY_OFF); // switch display off
ks_putdata(LCD_CMD_CTRL,START_LINE);
ks_putdata(LCD_CMD_CTRL,X_ADRESS);
ks_putdata(LCD_CMD_CTRL,Y_ADRESS);
ks_putdata(LCD_CMD_CTRL,DISPLAY_ON); // display on
ks_selectchip(RIGHT);
ks_putdata(LCD_CMD_CTRL,DISPLAY_OFF); // display off
ks_putdata(LCD_CMD_CTRL,START_LINE);
ks_putdata(LCD_CMD_CTRL,X_ADRESS);
ks_putdata(LCD_CMD_CTRL,Y_ADRESS);
ks_putdata(LCD_CMD_CTRL,DISPLAY_ON); // Display on
glcd_clear();

return;
}

// Function clears LCD and sets address counter to zero

void glcd_clear(void) {
static unsigned char u8Page=0;
static unsigned char u8Column=0;

// process the 8 pages of the LCD
for (u8Page=0;u8Page<8;u8Page++) {
ks_selectchip(LEFT); // select left side
ks_putdata(LCD_CMD_CTRL,X_ADRESS|u8Page); // set the page number
ks_putdata(LCD_CMD_CTRL,Y_ADRESS); // set column to 0
// process a page on both sides
for (u8Column=0;u8Column<128;u8Column++) {
if (u8Column==64) {
ks_selectchip(RIGHT); // select right side
ks_putdata(LCD_CMD_CTRL,X_ADRESS|u8Page); // set the page number
ks_putdata(LCD_CMD_CTRL,Y_ADRESS); // Set column to 0
}
ks_putdata(LCD_CMD_DATA,0x00); // erase a column
}
}

return;
}

// Function draws a dot on the LCD
// Entry: u8Xaxis = absciss, u8Yaxis = ordinate

void glcd_dot(unsigned char u8Xaxis, unsigned char u8Yaxis) {
static unsigned char u8DataRead=0;

ks_putdata(LCD_CMD_CTRL,START_LINE); // set adress for line 0
// left side
if (u8Xaxis<64) {
ks_selectchip(LEFT); // select left side
ks_putdata(LCD_CMD_CTRL,X_ADRESS|(u8Yaxis/8)); // select page number
ks_putdata(LCD_CMD_CTRL,Y_ADRESS|u8Xaxis); // select column
u8DataRead=ks_getdata(LCD_CMD_DATA); // read the current location
u8DataRead=ks_getdata(LCD_CMD_DATA); // on the LCD. dummy read
ks_putdata(LCD_CMD_CTRL,X_ADRESS|(u8Yaxis/8)); // select page number
ks_putdata(LCD_CMD_CTRL,Y_ADRESS|u8Xaxis); // select column
ks_putdata(LCD_CMD_DATA,u8DataRead|(1<<(u8Yaxis%8))); // plot the dot
// right side
} else {
ks_selectchip(RIGHT); // select left side
ks_putdata(LCD_CMD_CTRL,X_ADRESS|(u8Yaxis/8)); // select page number
ks_putdata(LCD_CMD_CTRL,Y_ADRESS|(u8Xaxis-64)); // select column
u8DataRead=ks_getdata(LCD_CMD_DATA); // read the current location
u8DataRead=ks_getdata(LCD_CMD_DATA); // on the LCD. dummy read
ks_putdata(LCD_CMD_CTRL,X_ADRESS|(u8Yaxis/8)); // select page number
ks_putdata(LCD_CMD_CTRL,Y_ADRESS|(u8Xaxis-64)); // select column
ks_putdata(LCD_CMD_DATA,u8DataRead|(1<<(u8Yaxis%8))); // plot the dot
}
ks_putdata(LCD_CMD_CTRL,START_LINE); // set adress for line 0

return;
}

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru