You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
extr/lcd.c

211 lines
4.7 KiB
C

/*
* lcd.c
*
* Created: 20.01.2018 12:51:11
* Author: Ulrich
*/
#include "lcd.h"
volatile unsigned char char_counter = 0;
volatile uint8_t lcd_ctrl_reg = 0;
// output data to lcd
void lcd_out (unsigned char c) {
i2c_start(LCD_I2C_ADDR);
i2c_byte(c | LCD_BACKLIGHT);
i2c_stop();
}
//***************************************************************************************
// CD = Command or Data
void lcd_nibble_out(unsigned char c, unsigned char cd) {
unsigned char out = 0;
unsigned char rs = 0;
if(cd) rs=LCD_RS;
//4 upper bits
if(c & (1<<4)) out |= LCD_D4;
if(c & (1<<5)) out |= LCD_D5;
if(c & (1<<6)) out |= LCD_D6;
if(c & (1<<7)) out |= LCD_D7;
lcd_out(out | rs | LCD_E);
_delay_ms(5);
lcd_out(out | rs);
//4 lower bits
out=0;
if(c & (1<<0)) out |= LCD_D4;
if(c & (1<<1)) out |= LCD_D5;
if(c & (1<<2)) out |= LCD_D6;
if(c & (1<<3)) out |= LCD_D7;
lcd_out(out | rs | LCD_E);
_delay_ms(5);
lcd_out(out | rs );
}
void lcd_set_position(uint8_t row, uint8_t col){
if(col >= LCD_WIDTH)
return;
if(row==0)
lcd_nibble_out(0x80|col, 0);
if(row==1)
lcd_nibble_out(0xC0|col, 0);
if(row==2)
lcd_nibble_out(0x80|(col+LCD_WIDTH), 0);
if(row==3)
lcd_nibble_out(0xC0|(col+LCD_WIDTH), 0);
char_counter = (row * LCD_WIDTH) + col;
}
void lcd_cursor(uint8_t en){
if(en)
lcd_nibble_out(0x08 | 0x04 | 0x02, 0);
else
lcd_nibble_out(0x08 | 0x04, 0);
}
//***************************************************************************************
// clear LCD
void lcd_clear() {
lcd_nibble_out(0x01, 0); // clear display
lcd_nibble_out(0x80, 0);
char_counter = 0;
}
//***************************************************************************************
// LCD home
void lcd_home() {
lcd_nibble_out(0x80, 0);
char_counter = 0;
}
//***************************************************************************************
// Init LCD
void lcd_init() {
unsigned char loop=3;
while(loop--){
lcd_out(LCD_D4 | LCD_D5 | LCD_E);
_delay_ms(10);
lcd_out(LCD_D4 | LCD_D5);
_delay_ms(100);
}
// 4 bit mode
lcd_out(LCD_D5 | LCD_E);
_delay_ms(10);
lcd_out(LCD_D5);
_delay_ms(10);
lcd_nibble_out(0x28, 0);
lcd_nibble_out(0x0C, 0);
lcd_clear();
}
//***************************************************************************************
void lcd_write_char (char c) {
if(char_counter == LCD_WIDTH) lcd_set_position(1,0);
if(char_counter == 2*LCD_WIDTH) lcd_set_position(2,0);
if(char_counter == 3*LCD_WIDTH) lcd_set_position(3,0);
if(char_counter == 4*LCD_WIDTH) lcd_set_position(0,0);
char_counter++;
lcd_nibble_out(c, 1);
}
//***************************************************************************************
void lcd_print_str(char *str) {
while (*str != 0){
if(char_counter == LCD_WIDTH) lcd_set_position(1,0);
if(char_counter == 2*LCD_WIDTH) lcd_set_position(2,0);
if(char_counter == 3*LCD_WIDTH) lcd_set_position(3,0);
if(char_counter == 4*LCD_WIDTH) lcd_set_position(0,0);
char_counter++;
lcd_nibble_out(*str++, 1);
}
}
//***************************************************************************************
void lcd_write_P (const char *Buffer,...)
{
va_list ap;
va_start (ap, Buffer);
int format_flag;
char str_buffer[10];
char str_null_buffer[10];
char move = 0;
char Base = 0;
int tmp = 0;
char by;
char *ptr;
//Ausgabe der Zeichen
for(;;){
by = pgm_read_byte(Buffer++);
if(by==0) break; // end of format string
if (by == '%'){
by = pgm_read_byte(Buffer++);
if (isdigit(by)>0){
str_null_buffer[0] = by;
str_null_buffer[1] = '\0';
move = atoi(str_null_buffer);
by = pgm_read_byte(Buffer++);
}
switch (by){
case 's':
ptr = va_arg(ap,char *);
while(*ptr) { lcd_write_char(*ptr++); }
break;
case 'b':
Base = 2;
goto ConversionLoop;
case 'c':
//Int to char
format_flag = va_arg(ap,int);
lcd_write_char (format_flag++);
break;
case 'i':
Base = 10;
goto ConversionLoop;
case 'o':
Base = 8;
goto ConversionLoop;
case 'x':
Base = 16;
//****************************
ConversionLoop:
//****************************
itoa(va_arg(ap,int),str_buffer,Base);
int b=0;
while (str_buffer[b++] != 0){};
b--;
if (b<move){
move -=b;
for (tmp = 0;tmp<move;tmp++){
str_null_buffer[tmp] = '0';
}
//tmp ++;
str_null_buffer[tmp] = '\0';
strcat(str_null_buffer,str_buffer);
strcpy(str_buffer,str_null_buffer);
}
lcd_print_str (str_buffer);
move =0;
break;
}
}else{
lcd_write_char (by);
}
}
va_end(ap);
}