Hallo robotka,
ich habe auch ein Display von Reichelt mit diesem Kontroller aber für den RP6.
Das Display hat 4x16 Zeichen
Ich kenne mich mit deiner Programmierung nicht aus, aber ich poste dir mal die bei mir funktionierende Libteile:
lcd.c
Code:
// LCD
// All LCD routines are prepared to control a 2x16 character LCD.
// If you want to connect a bigger LCD you need to change some things in
// these routines! (especially in the initLCD, setCursorLCD and showScreenLCD
// routines)
char lcd_tmp_buffer[17];
/**
* Sets the LCD ports without affecting the LEDs and also pulses the
* enable line of the LCD to 'inform' the LCD about the new data.
*
*/
void setLCDD(uint8_t lcdd)
{
PORTA = lcdd;
sleep(5);
PORTG |= DISP_EN_RD;
delayCycles(150);
PORTG &= ~DISP_EN_RD;
delayCycles(20);
}
/**
* Write a command to the LCD.
*/
void writeLCDCommand(uint8_t cmd)
{
PORTG &= ~DISP_RS_ALE;
setLCDD(cmd);
delayCycles(500);
}
/**
* Initialize the LCD. Always call this before using the LCD!
*
*/
void initLCD(void)
{
delayCycles(34000); //No need for Power ON delay as usually the
// Bootloader should have been executed before...
PORTG &= ~DISP_WR;
PORTG &= ~DISP_RS_ALE;
PORTG &= ~DISP_EN_RD;
mSleep(5);
writeLCDCommand(0b00110000);
delayCycles(55500);
mSleep(50);
writeLCDCommand(0b00110000);
delayCycles(55500);
mSleep(5);
writeLCDCommand(0b00110000);
delayCycles(55500);
mSleep(5);
writeLCDCommand(0b00111000);
delayCycles(55500);
mSleep(1);
writeLCDCommand(0b00001000);
delayCycles(55500);
mSleep(1);
writeLCDCommand(0b00000001);
delayCycles(55500);
mSleep(1);
writeLCDCommand(0b00000010);
delayCycles(55500);
mSleep(1);
writeLCDCommand(0b00001100);
delayCycles(55500);
mSleep(1);
mSleep(5);
clearLCD();
}
/**
* Clears the whole LCD!
*/
void clearLCD(void)
{
writeLCDCommand(0b00000001);
delayCycles(5500);
}
/**
* Write a single character to the LCD.
*
* Example:
*
* writeCharLCD('R');
* writeCharLCD('P');
* writeCharLCD('6');
* writeCharLCD(' ');
* writeCharLCD('0');
* writeCharLCD(48); // 48 is ASCII code for '0'
* writeCharLCD(49); // '1'
* writeCharLCD(50); // '2'
* writeCharLCD(51); // '3'
* //...
*
* would output:
* RP6 00123
* at the current cursor position!
* use setCursorPos function to move the cursor to a
* different location!
*/
void writeCharLCD(uint8_t ch)
{
PORTG |= DISP_RS_ALE;
setLCDD(ch);
delayCycles(50);
}
/**
* Writes a null terminated string from flash program memory to the LCD.
* You can use the macro writeStringLCD_P(STRING); instead, this macro
* ensures that the String is stored in program memory only!
*
* Example:
*
* writeNStringLCD_P(PSTR("RP6 Control"));
*
* // There is also a Macro that makes life easier and
* // you can simply write:
* writeStringLCD_P("RP6 Control");
*
*/
void writeNStringLCD_P(const char *pstring)
{
uint8_t c;
for (;(c = pgm_read_byte_near(pstring++));writeCharLCD(c));
}
/**
* Writes a String from SRAM to the LCD.
*/
void writeStringLCD(char *string)
{
while(*string)
writeCharLCD(*string++);
}
/**
* Writes a string with specified length and offset from SRAM to the LCD.
* If it is a null terminated string, output will be stopped at the
* end. It does not need to be null terminated, but it is recommended
* to use only null terminated strings/buffers, otherwise the function could
* output any SRAM memory data stored after the string until it reaches a 0
* or the specified length!
*
* Example:
*
* writeStringLength("RP6 Robot Sytem",16,0);
* // would output: "RP6 Robot Sytem\n"
* writeStringLength("RP6 Robot Sytem",11,4);
* // would output: "Robot System"
* writeStringLength("RP6 Robot Sytem",40,4);
* // would output: "Robot System"
* // No matter if the specified length is 40 characters!
*
*/
void writeStringLengthLCD(char *string, uint8_t length, uint8_t offset)
{
for(string = &string[offset]; *string && length; length--)
writeCharLCD(*string++);
}
/**
* Write a number (with specified base) to the LCD.
*
* Example:
*
* // Write a hexadecimal number to the LCD:
* writeInteger(0xAACC,16);
* // Instead of 16 you can also write "HEX" as this is defined in the
* // RP6RobotBaseLib.h :
* writeInteger(0xAACC, HEX);
* // Other Formats:
* writeInteger(1024,DEC); // Decimal
* writeInteger(511,OCT); // Ocal
* writeInteger(0b11010111,BIN); // Binary
*/
void writeIntegerLCD(int16_t number, uint8_t base)
{
itoa(number, &lcd_tmp_buffer[0], base);
writeStringLCD(&lcd_tmp_buffer[0]);
}
/**
* Same as writeInteger, but with defined length.
* This means this routine will add leading zeros to the number if length is
* larger than the actual value or cut the upper digits if length is smaller
* than the actual value.
*
* Example:
*
* // Write a hexadecimal number to the LCD:
* writeIntegerLength(0xAACC, 16, 8);
* // Instead of 16 you can also write "HEX" as this is defined in the
* // RP6ControlLib.h :
* writeIntegerLength(0xAACC, HEX, 8);
* // Other Formats:
* writeIntegerLength(1024,DEC,6); // Decimal
* writeIntegerLength(511,OCT,4); // Ocal
* writeIntegerLength(0b11010111,BIN,8); // Binary
*/
void writeIntegerLengthLCD(int16_t number, uint8_t base, uint8_t length)
{
char buffer[17];
itoa(number, &buffer[0], base);
int8_t cnt = length - strlen(buffer);
if(cnt > 0) {
for(; cnt > 0; cnt--, writeCharLCD('0'));
writeStringLCD(&buffer[0]);
}
else
writeStringLengthLCD(&buffer[0],length,-cnt);
}
/**
* This function is useful for displaying text screens on the LCD.
* It clears the whole LCD and writes the two Strings to line 1 and
* line 2.
*/
void _showScreenLCD_P(const char *line1, const char *line2, const char *line3, const char *line4)
{
clearLCD();
setCursorPosLCD(0, 0);
writeNStringLCD_P(line1);
setCursorPosLCD(1, 0);
writeNStringLCD_P(line2);
setCursorPosLCD(2, 0);
writeNStringLCD_P(line3);
setCursorPosLCD(3, 0);
writeNStringLCD_P(line4);
}
/**
* Sets the cursor position on LCD.
*/
void setCursorPosLCD(uint8_t line, uint8_t pos)
{
//pos |= 248; //128
if(line==0) pos += 0b0010000000;
if(line==1) pos += 0b0010101000;
if(line==2) pos += 0b0010010000; //pos += 0x10
if(line==3) pos += 0b0011010000;
writeLCDCommand(pos);
}
/**
* Clears some characters after the given position.
*/
void clearPosLCD(uint8_t line, uint8_t pos, uint8_t length)
{
setCursorPosLCD(line,pos);
while(length--)
writeCharLCD(' ');
}
lcd.h
Code:
// LCD:
void setLCDD(uint8_t lcdd);
void writeLCDCommand(uint8_t cmd);
void initLCD(void);
void clearLCD(void);
void clearPosLCD(uint8_t line, uint8_t pos, uint8_t length);
void writeCharLCD(uint8_t ch);
#define writeStringLCD_P(__pstr) writeNStringLCD_P((PSTR(__pstr)))
void writeStringLengthLCD(char *string, uint8_t length, uint8_t offset);
void writeStringLCD(char *string);
void writeNStringLCD_P(const char *pstring);
void _showScreenLCD_P(const char *line1, const char *line2, const char *line3, const char *line4);
#define showScreenLCD(__line1,__line2,__line3,__line4); ({_showScreenLCD_P((PSTR(__line1)),(PSTR(__line2)),(PSTR(__line3)),(PSTR(__line4)));})
#ifndef HEX
#define HEX 16
#endif
#ifndef DEC
#define DEC 10
#endif
#ifndef OCT
#define OCT 8
#endif
#ifndef BIN
#define BIN 2
#endif
void writeIntegerLCD(int16_t number, uint8_t base);
void writeIntegerLengthLCD(int16_t number, uint8_t base, uint8_t length);
void setCursorPosLCD(uint8_t line, uint8_t pos);
Das ist die geänderte RP6 Orginallib
Ich hoffe dir helfen zu können
Thorben
Lesezeichen