Witam
Mam problem z uruchomieniem wyświetlacza na sterowniku jak w temacie. Zakupiłem sobie wyświetlacz w sklepie kamami o oznaczeniu LCD12864-NEG_BLUE i przygotowałem dla niego płytkę, której schemat jest w załączniku. Sercem układu jest ATmega8 taktowana z częstotliwością 8MHz (wew. RC), ustawienia Fuse bitów: H-0xD9 L-0x94.
Program pisałem wykorzystując biblioteki radzia, zresztą dostarczany był przez Kamami do płytki ZL16AVR i udostępniony do ściągnięcia, przez co zakładam, że jest sprawny.
Plik main:
Kod:
plik KS0108.c:
Kod:
plik KS0108.h
Kod:
plik KS0108-AVR.c
Kod:
Jestem pewny, ze osoby, które uruchomiły ten wyświetlacz, doskonale znają powyżej przedstawioną bibliotekę i pomogą mi rozwiązać problem. Dodam jeszcze, że na początku pomyliłem piny na wyświetlaczu i połączyłem go w odwrotnej kolejności (tzn. nie od 0 do 20, ale od 20 do 0), lecz nie podejrzewam, aby się coś przez to stało. Nie udało mi się jeszcze niczego na nim wyświetlić. Zwracam się o pomoc, gdzie szukać błędu?
Pozdrawiam i dziękuję za każdą odpowiedź.
![[AVR GCC][KS0108] Problem z uruchomieniem wyświetlacza [AVR GCC][KS0108] Problem z uruchomieniem wyświetlacza](https://obrazki.elektroda.pl/48_1256129358_thumb.jpg)
Mam problem z uruchomieniem wyświetlacza na sterowniku jak w temacie. Zakupiłem sobie wyświetlacz w sklepie kamami o oznaczeniu LCD12864-NEG_BLUE i przygotowałem dla niego płytkę, której schemat jest w załączniku. Sercem układu jest ATmega8 taktowana z częstotliwością 8MHz (wew. RC), ustawienia Fuse bitów: H-0xD9 L-0x94.
Program pisałem wykorzystując biblioteki radzia, zresztą dostarczany był przez Kamami do płytki ZL16AVR i udostępniony do ściągnięcia, przez co zakładam, że jest sprawny.
Plik main:
Kod:
//***************** (c) 2008 BTC Korporacja ***********************************
// http://www kamami.com
// PROJECT : CHAR LCD
// BOARD : ZL16AVR (with ATmega88 in socket U1)
// COMPILER : WinAVR 20080610
//
//******************************************************************************
//
// THE SOFTWARE INCLUDED IN THIS FILE IS FOR GUIDANCE ONLY.
// BTC KORPORACJA SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
// OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
// FROM USE OF THIS SOFTWARE.
//
//******************************************************************************
//
// DESCRIPTION :
// Using LCD graphic display (KS0108 compatible)
//
// Settings and connections on ZL16AVR:
// JP4 (DISPLAY) - 1-2 (=GRAPH)
//
// D0 (LCD_GRAPH/con12) - PD0 (con18)
// D1 (LCD_GRAPH/con12) - PD1 (con18)
// D2 (LCD_GRAPH/con12) - PD2 (con18)
// D3 (LCD_GRAPH/con12) - PD3 (con18)
// D4 (LCD_GRAPH/con12) - PD4 (con18)
// D5 (LCD_GRAPH/con12) - PD5 (con18)
// D6 (LCD_GRAPH/con12) - PD6 (con18)
// D7 (LCD_GRAPH/con12) - PD7 (con18)
//
// RS (LCD_GRAPH/con12) - PB0 (con16)
// RW (LCD_GRAPH/con12) - PB1 (con16)
// E (LCD_GRAPH/con12) - PB2 (con16)
// CS1(LCD_GRAPH/con12) - PB3 (con16)
// CS2(LCD_GRAPH/con12) - PB4 (con16)
//
//******************************************************************************
//#ifndef F_CPU
#define F_CPU 8000000 // 16 MHz - turn on external resonator (fuse bits)
//#endif
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include "KS0108.c"
#include "KS0108-AVR.c"
#include "kamami.h"
//-------------------------------------
// main program
//-------------------------------------
int main(void)
{
unsigned char i;
GLCD_Initialize(); // LCD initialization
do{
GLCD_ClearScreen(); // clear screen
GLCD_GoTo(0,0);
GLCD_WriteString("K A M A M I"); //
GLCD_WriteStringXY("development board",12,1); // display text
GLCD_WriteStringXY(" -- ZL16AVR -- ",12,3); //
GLCD_WriteStringXY(" www.kamami.com ",12,4); //
for(i = 0; i < 200; i++) // wait2 seconds
_delay_ms(10); //
GLCD_Bitmap(kamami,0,0,128,64); // display picture
for(i = 0; i < 200; i++) // wait 2 seconds
_delay_ms(10); //
}while(1);
}
//-------------------------------------
// End of file
//-------------------------------------
plik KS0108.c:
Kod:
//******************************************************************************
//
// THE SOFTWARE INCLUDED IN THIS FILE IS FOR GUIDANCE ONLY.
// BTC KORPORACJA SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
// OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
// FROM USE OF THIS SOFTWARE.
//
//******************************************************************************
#include "KS0108.h"
#include "font5x8.h"
//-------------------------------------------------------------------------------------------------
// Reference to MCU-specific external functions
//-------------------------------------------------------------------------------------------------
extern void GLCD_InitalizePorts(void);
extern void GLCD_WriteData(unsigned char);
extern void GLCD_WriteCommand(unsigned char, unsigned char);
extern unsigned char GLCD_ReadData(void);
extern unsigned char GLCD_ReadStatus(unsigned char);
//-------------------------------------------------------------------------------------------------
unsigned char screen_x = 0, screen_y = 0; // screen coordinates
//-------------------------------------------------------------------------------------------------
// Initialization interface and LCD controller
//-------------------------------------------------------------------------------------------------
void GLCD_Initialize(void)
{
unsigned char i;
GLCD_InitalizePorts();
for(i = 0; i < 3; i++)
GLCD_WriteCommand((DISPLAY_ON_CMD | ON), i);
}
//-------------------------------------------------------------------------------------------------
// Sets screen coordinates and address
//-------------------------------------------------------------------------------------------------
void GLCD_GoTo(unsigned char x, unsigned char y)
{
unsigned char i;
screen_x = x;
screen_y = y;
for(i = 0; i < KS0108_SCREEN_WIDTH/64; i++)
{
GLCD_WriteCommand(DISPLAY_SET_Y | 0,i);
GLCD_WriteCommand(DISPLAY_SET_X | y,i);
GLCD_WriteCommand(DISPLAY_START_LINE | 0,i);
}
GLCD_WriteCommand((DISPLAY_SET_Y | (x % 64)), (x / 64));
GLCD_WriteCommand((DISPLAY_SET_X | y), (x / 64));
}
//-------------------------------------------------------------------------------------------------
// Sets text coordinates and address
//-------------------------------------------------------------------------------------------------
void GLCD_TextGoTo(unsigned char x, unsigned char y)
{
GLCD_GoTo(x*6,y);
}
//-------------------------------------------------------------------------------------------------
// Clears screen
//-------------------------------------------------------------------------------------------------
void GLCD_ClearScreen(void)
{
unsigned char i, j;
for(j = 0; j < KS0108_SCREEN_HEIGHT/8; j++)
{
GLCD_GoTo(0,j);
for(i = 0; i < KS0108_SCREEN_WIDTH; i++)
GLCD_WriteData(0x00);
}
}
//-------------------------------------------------------------------------------------------------
// Writes char to screen memory
//-------------------------------------------------------------------------------------------------
void GLCD_WriteChar(char charToWrite)
{
char i;
charToWrite -= 32;
for(i = 0; i < 5; i++)
GLCD_WriteData(GLCD_ReadByteFromROMMemory((char *)(font5x8 + (5 * charToWrite) + i)));
GLCD_WriteData(0x00);
}
//-------------------------------------------------------------------------------------------------
// Write null-terminated string to screen memory
//-------------------------------------------------------------------------------------------------
void GLCD_WriteString(char * stringToWrite)
{
while(*stringToWrite)
GLCD_WriteChar(*stringToWrite++);
}
//-------------------------------------------------------------------------------------------------
// Write null-terminated string to screen memory
//-------------------------------------------------------------------------------------------------
void GLCD_WriteStringXY(char * stringToWrite, char x, char y)
{
GLCD_GoTo(x,y);
while(*stringToWrite)
GLCD_WriteChar(*stringToWrite++);
}
//-------------------------------------------------------------------------------------------------
// Sets or clears pixel at (x,y)
//-------------------------------------------------------------------------------------------------
void GLCD_SetPixel(unsigned char x, unsigned char y, unsigned char color)
{
unsigned char tmp;
GLCD_GoTo(x, y/8);
tmp = GLCD_ReadData();
GLCD_GoTo(x, y/8);
tmp = GLCD_ReadData();
GLCD_GoTo(x, y/8);
if(color)
tmp |= (1 << (y%8));
else
tmp &= ~(1 << (y%8));
GLCD_WriteData(tmp);
}
//-------------------------------------------------------------------------------------------------
// Displays bitmap at (x,y) and (dx,dy) size
//-------------------------------------------------------------------------------------------------
void GLCD_Bitmap(char * bmp, unsigned char x, unsigned char y, unsigned char dx, unsigned char dy)
{
unsigned char i, j;
for(j = 0; j < dy / 8; j++)
{
GLCD_GoTo(x,y + j);
for(i = 0; i < dx; i++)
GLCD_WriteData(GLCD_ReadByteFromROMMemory(bmp++));
}
}
//-------------------------------------------------------------------------------------------------
// End of file KS0108.c
//-------------------------------------------------------------------------------------------------
plik KS0108.h
Kod:
#define KS0108_SCREEN_WIDTH 128
#define KS0108_SCREEN_HEIGHT 64
#define DISPLAY_SET_Y 0x40
#define DISPLAY_SET_X 0xB8
#define DISPLAY_START_LINE 0xC0
#define DISPLAY_ON_CMD 0x3E
#define ON 0x01
#define OFF 0x00
#define DISPLAY_STATUS_BUSY 0x80
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
void GLCD_Initialize(void);
void GLCD_WriteData(unsigned char);
void GLCD_ClearScreen(void);
void GLCD_TextGoTo(unsigned char, unsigned char);
void GLCD_GoTo(unsigned char, unsigned char);
void GLCD_WriteString(char *);
unsigned char GLCD_ReadByteFromROMMemory(char *);
void GLCD_WriteStringXY(char * stringToWrite, char x, char y);
void GLCD_Bitmap(char * bmp, unsigned char x, unsigned char y, unsigned char dx, unsigned char dy);
plik KS0108-AVR.c
Kod:
//-------------------------------------------------------------------------------------------------
// Universal KS0108 driver library
// Atmel AVR MCU low-level driver.
// (c) Radosław Kwiecień, radek@dxp.pl
//-------------------------------------------------------------------------------------------------
#include <avr/io.h>
#include <avr/pgmspace.h>
#define KS0108_DATA_PORT PORTD
#define KS0108_DATA_DIR DDRD
#define KS0108_DATA_PIN PIND
#define KS0108_CTRL_PORT PORTB
#define KS0108_CTRL_DIR DDRB
#define KS0108_RS (1 << 0)
#define KS0108_RW (1 << 1)
#define KS0108_EN (1 << 2)
#define KS0108_CS1 (1 << 3)
#define KS0108_CS2 (1 << 4)
#define KS0108_CS3 (1 << 5)
extern unsigned char screen_x;
extern unsigned char screen_y;
#define DISPLAY_STATUS_BUSY 0x80
//-------------------------------------------------------------------------------------------------
// Delay function
//-------------------------------------------------------------------------------------------------
void GLCD_Delay(void)
{
asm("nop");
asm("nop");
//asm("nop");
//asm("nop");
}
//-------------------------------------------------------------------------------------------------
// Enalbe Controller (0-2)
//-------------------------------------------------------------------------------------------------
void GLCD_EnableController(unsigned char controller)
{
switch(controller){
case 0 : KS0108_CTRL_PORT &= ~KS0108_CS1; break;
case 1 : KS0108_CTRL_PORT &= ~KS0108_CS2; break;
case 2 : KS0108_CTRL_PORT &= ~KS0108_CS3; break;
}
}
//-------------------------------------------------------------------------------------------------
// Disable Controller (0-2)
//-------------------------------------------------------------------------------------------------
void GLCD_DisableController(unsigned char controller)
{
switch(controller){
case 0 : KS0108_CTRL_PORT |= KS0108_CS1; break;
case 1 : KS0108_CTRL_PORT |= KS0108_CS2; break;
case 2 : KS0108_CTRL_PORT |= KS0108_CS3; break;
}
}
//-------------------------------------------------------------------------------------------------
// Read Status from specified controller (0-2)
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ReadStatus(unsigned char controller)
{
unsigned char status;
KS0108_DATA_DIR = 0x00;
KS0108_CTRL_PORT |= KS0108_RW;
KS0108_CTRL_PORT &= ~KS0108_RS;
GLCD_EnableController(controller);
KS0108_CTRL_PORT |= KS0108_EN;
GLCD_Delay();
status = KS0108_DATA_PIN;
KS0108_CTRL_PORT &= ~KS0108_EN;
GLCD_DisableController(controller);
return status;
}
//-------------------------------------------------------------------------------------------------
// Write command to specified controller
//-------------------------------------------------------------------------------------------------
void GLCD_WriteCommand(unsigned char commandToWrite, unsigned char controller)
{
while(GLCD_ReadStatus(controller)&DISPLAY_STATUS_BUSY);
KS0108_DATA_DIR = 0xFF;
KS0108_CTRL_PORT &= ~(KS0108_RW | KS0108_RS);
GLCD_EnableController(controller);
KS0108_DATA_PORT = commandToWrite;
KS0108_CTRL_PORT |= KS0108_EN;
GLCD_Delay();
KS0108_CTRL_PORT &= ~KS0108_EN;
GLCD_DisableController(controller);
}
//-------------------------------------------------------------------------------------------------
// Read data from current position
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ReadData(void)
{
unsigned char data;
while(GLCD_ReadStatus(screen_x / 64)&DISPLAY_STATUS_BUSY);
KS0108_DATA_DIR = 0x00;
KS0108_CTRL_PORT |= (KS0108_RW | KS0108_RS);
GLCD_EnableController(screen_x / 64);
//GLCD_Delay();
KS0108_CTRL_PORT |= KS0108_EN;
GLCD_Delay();
data = KS0108_DATA_PIN;
KS0108_CTRL_PORT &= ~KS0108_EN;
GLCD_DisableController(screen_x / 64);
screen_x++;
return data;
}
//-------------------------------------------------------------------------------------------------
// Write data to current position
//-------------------------------------------------------------------------------------------------
void GLCD_WriteData(unsigned char dataToWrite)
{
while(GLCD_ReadStatus(screen_x / 64)&DISPLAY_STATUS_BUSY);
KS0108_DATA_DIR = 0xFF;
KS0108_CTRL_PORT &= ~KS0108_RW;
KS0108_CTRL_PORT |= KS0108_RS;
KS0108_DATA_PORT = dataToWrite;
GLCD_EnableController(screen_x / 64);
KS0108_CTRL_PORT |= KS0108_EN;
GLCD_Delay();
KS0108_CTRL_PORT &= ~KS0108_EN;
GLCD_DisableController(screen_x / 64);
screen_x++;
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
void GLCD_InitalizePorts(void)
{
KS0108_CTRL_DIR |= (KS0108_CS1 | KS0108_CS2 | KS0108_CS3 | KS0108_RS | KS0108_RW | KS0108_EN);
KS0108_CTRL_PORT |= (KS0108_CS1 | KS0108_CS2 | KS0108_CS3);
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ReadByteFromROMMemory(char * ptr)
{
return pgm_read_byte(ptr);
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
Jestem pewny, ze osoby, które uruchomiły ten wyświetlacz, doskonale znają powyżej przedstawioną bibliotekę i pomogą mi rozwiązać problem. Dodam jeszcze, że na początku pomyliłem piny na wyświetlaczu i połączyłem go w odwrotnej kolejności (tzn. nie od 0 do 20, ale od 20 do 0), lecz nie podejrzewam, aby się coś przez to stało. Nie udało mi się jeszcze niczego na nim wyświetlić. Zwracam się o pomoc, gdzie szukać błędu?
Pozdrawiam i dziękuję za każdą odpowiedź.