Code:
//uint8_t LCD_InitTab[] = {0x39,0x14,0x55,0x6d,0x78,0x38,0x0f,0x06,0x01};
const uint8_t LCD_InitTab[] = {0x29,0x14,0x56,0x6d,0x70,0x38,0x0f};
#define _____ 0x00
#define ____X 0x01
#define ___X_ 0x02
#define ___XX 0x03
#define __X__ 0x04
#define __X_X 0x05
#define __XX_ 0x06
#define __XXX 0x07
#define _X___ 0x08
#define _X__X 0x09
#define _X_X_ 0x0A
#define _X_XX 0x0B
#define _XX__ 0x0C
#define _XX_X 0x0D
#define _XXX_ 0x0E
#define _XXXX 0x0F
#define X____ 0x10
#define X___X 0x11
#define X__X_ 0x12
#define X__XX 0x13
#define X_X__ 0x14
#define X_X_X 0x15
#define X_XX_ 0x16
#define X_XXX 0x17
#define XX___ 0x18
#define XX__X 0x19
#define XX_X_ 0x1A
#define XX_XX 0x1B
#define XXX__ 0x1C
#define XXX_X 0x1D
#define XXXX_ 0x1E
#define XXXXX 0x1F
const uint8_t Chargen[] = {
#ifdef ARROWS
// left arrow
_____,
__X__,
_X___,
XXXXX,
_X___,
__X__,
_____,
_____,
// top left arrow
XXX__,
XX___,
X_X__,
___X_,
____X,
_____,
_____,
_____,
// up arrow
__X__,
_XXX_,
X_X_X,
__X__,
__X__,
__X__,
_____,
_____,
// top right arrow
__XXX,
___XX,
__X_X,
_X___,
X____,
_____,
_____,
_____,
// right arrow
_____,
__X__,
___X_,
XXXXX,
___X_,
__X__,
_____,
_____,
// bottom right arrow
_____,
_____,
_____,
X____,
_X___,
__X_X,
___XX,
__XXX,
// down arrow
_____,
_____,
__X__,
__X__,
__X__,
X_X_X,
_XXX_,
__X__,
// bottom left arrow
_____,
_____,
_____,
____X,
___X_,
X_X__,
XX___,
XXX__,
#else
// bottom row
_____,
_____,
_____,
_____,
_____,
_____,
_____,
XXXXX,
// two rows
_____,
_____,
_____,
_____,
_____,
_____,
XXXXX,
XXXXX,
// three rows
_____,
_____,
_____,
_____,
_____,
XXXXX,
XXXXX,
XXXXX,
// four rows
_____,
_____,
_____,
_____,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
// five rows
_____,
_____,
_____,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
// six rows
_____,
_____,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
// seven rows
_____,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
// full block
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
XXXXX,
#endif
};
void SPI_WriteByte(uint8_t data) {
uint8_t mask = 0x80;
while (mask) {
SCKout = 0;
if (data & mask) {
SDOout = 1;
} else {
SDOout = 0;
}
SCKout = 1;
mask >>= 1;
}
}
void LCD_SendCMD(uint8_t command){
RSout = 0;
CSBout = 0;
SPI_WriteByte(command);
CSBout = 1;
__delay_us(28);
}
void LCD_SendData(uint8_t data){
RSout = 1;
CSBout = 0;
SPI_WriteByte(data);
CSBout = 1;
__delay_us(28);
}
void LCD_SendCMDBlock(const uint8_t* commands, int length) {
while (length) {
LCD_SendCMD(*commands++);
length--;
}
}
void LCD_SendDataBlock(const uint8_t* data, int length) {
RSout = 1;
CSBout = 0;
while (length) {
LCD_SendData(*data++);
length--;
}
CSBout = 1;
}
void LCD_ClearDisplay(void){
LCD_SendCMD(0x01);
__delay_us(1500);
}
void LCD_SetCursor(int mode){
LCD_SendCMD(0b00001100 | (mode & 0b00000011));
}
void LCD_SetDisplayAddress(int address){
LCD_SendCMD(0b10000000 | (address & 0b01111111));
}
void LCD_SetCharGenAddress(int address){
LCD_SendCMD(0b01000000 | (address & 0b00111111));
}
void LCD_Init(void){
LCD_SendCMDBlock(LCD_InitTab, sizeof(LCD_InitTab));
LCD_ClearDisplay();
}
int LCD_SetExtraChars(const uint8_t* BitPattern, int length) {
if(*BitPattern == 0xFF){ // unprogrammed EEPROM data
return -1;
}
if(length > 64){
length = 64;
}
LCD_SetCharGenAddress(0);
LCD_SendDataBlock((uint8_t*) BitPattern, length);
return 0;
}
void LCD_SetBacklight(int intensity) {
int tmp;
if (intensity > 15) {
intensity = 15;
}
tmp = 0x01 << intensity;
OC2R = tmp;
}
Ist schon eine Weile her, daß ich das geschrieben hab, daher weiß ich nicht mehr, was der Unterschied der beiden Initialisierungssquenzen am Anfang ist. Da sind auch noch zusätzliche Zeichen drin, die auf die freien Plätze programmiert werden können und ein paar #defines, die das besser "lesbar" machen. Das Backlight hatte ich wohl an einem PWM Ausgang.
Lesezeichen