iqbalpiac
Newbie
Lcd display for ups using for mains,ups ,charging and battery full indications
Code:
#include <avr/io.h>
#include <inttypes.h>
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
#include <util/delay.h>
#include "lcd.h"
#include "custom_char.h"
#define LCD_DATA_PORT PORT(LCD_DATA)
#define LCD_E_PORT PORT(LCD_E)
#define LCD_RS_PORT PORT(LCD_RS)
#define LCD_RW_PORT PORT(LCD_RW)
#define LCD_DATA_DDR DDR(LCD_DATA)
#define LCD_E_DDR DDR(LCD_E)
#define LCD_RS_DDR DDR(LCD_RS)
#define LCD_RW_DDR DDR(LCD_RW)
#define LCD_DATA_PIN PIN(LCD_DATA)
#define SET_E() (LCD_E_PORT|=(1<<LCD_E_POS))
#define SET_RS() (LCD_RS_PORT|=(1<<LCD_RS_POS))
#define SET_RW() (LCD_RW_PORT|=(1<<LCD_RW_POS))
#define CLEAR_E() (LCD_E_PORT&=(~(1<<LCD_E_POS)))
#define CLEAR_RS() (LCD_RS_PORT&=(~(1<<LCD_RS_POS)))
#define CLEAR_RW() (LCD_RW_PORT&=(~(1<<LCD_RW_POS)))
#define LCD_LINE0_DDRAMADDR 0x00
#define LCD_LINE1_DDRAMADDR 0x40
#define LCD_LINE2_DDRAMADDR 0x10
#define LCD_LINE3_DDRAMADDR 0x50
#define LCD_DDRAM 7 //DB7: set DD RAM address
void LCDcursorLeft(uint8_t n) //Moves cursor by n poisitions left
{
uint8_t i;
for (i=0;i<n;i++)
{
LCDCmd(0x10);
}
}
void LCDByte(uint8_t c,uint8_t isdata)
{
//Sends a byte to the LCD in 4bit mode
//cmd=0 for data
//cmd=1 for command
//NOTE: THIS FUNCTION RETURS ONLY WHEN LCD HAS PROCESSED THE COMMAND
uint8_t hn,ln; //Nibbles
uint8_t temp;
hn=c>>4;
ln=(c & 0x0F);
if(isdata==0)
CLEAR_RS();
else
SET_RS();
_delay_us(0.500); //tAS
SET_E();
//Send high nibble
temp=(LCD_DATA_PORT & 0XF0)|(hn);
LCD_DATA_PORT=temp;
_delay_us(1); //tEH
//Now data lines are stable pull E low for transmission
CLEAR_E();
_delay_us(1);
//Send the lower nibble
SET_E();
temp=(LCD_DATA_PORT & 0XF0)|(ln);
LCD_DATA_PORT=temp;
_delay_us(1); //tEH
//SEND
CLEAR_E();
_delay_us(1); //tEL
LCDBusyLoop();
}
void LCDBusyLoop()
{
//This function waits till lcd is BUSY
uint8_t busy,status=0x00,temp;
//Change Port to input type because we are reading data
LCD_DATA_DDR&=0xF0;
//change LCD mode
SET_RW(); //Read mode
CLEAR_RS(); //Read status
//Let the RW/RS lines stabilize
_delay_us(0.5); //tAS
do
{
SET_E();
//Wait tDA for data to become available
_delay_us(0.5);
status=LCD_DATA_PIN;
status=status<<4;
_delay_us(0.5);
//Pull E low
CLEAR_E();
_delay_us(1); //tEL
SET_E();
_delay_us(0.5);
temp=LCD_DATA_PIN;
temp&=0x0F;
status=status|temp;
busy=status & 0b10000000;
_delay_us(0.5);
CLEAR_E();
_delay_us(1); //tEL
}
while(busy);
CLEAR_RW(); //write mode
//Change Port to output
LCD_DATA_DDR|=0x0F;
}
void InitLCD(uint8_t style)
{
/*****************************************************************
This function Initializes the lcd module
must be called before calling lcd related functions
Arguments:
style = LS_BLINK,LS_ULINE(can be "OR"ed for combination)
LS_BLINK :The cursor is blinking type
LS_ULINE :Cursor is "underline" type else "block" type
*****************************************************************/
//After power on Wait for LCD to Initialize
_delay_ms(30);
//Set IO Ports
LCD_DATA_DDR|=(0x0F);
LCD_E_DDR|=(1<<LCD_E_POS);
LCD_RS_DDR|=(1<<LCD_RS_POS);
LCD_RW_DDR|=(1<<LCD_RW_POS);
LCD_DATA_PORT&=0XF0;
CLEAR_E();
CLEAR_RW();
CLEAR_RS();
//Set 4-bit mode
_delay_us(0.3); //tAS
SET_E();
LCD_DATA_PORT|=(0b00000010); //[B] To transfer 0b00100000 i was using LCD_DATA_PORT|=0b00100000
_delay_us(1);
CLEAR_E();
_delay_us(1);
//Wait for LCD to execute the Functionset Command
LCDBusyLoop(); //[B] Forgot this delay
//Now the LCD is in 4-bit mode
LCDCmd(0b00001100|style); //Display On
LCDCmd(0b00101000); //function set 4-bit,2 line 5x7 dot format
/* Custom Char */
LCDCmd(0b01000000);
uint8_t __i;
for(__i=0;__i<sizeof(__cgram);__i++)
LCDData(__cgram[__i]);
LCDGotoXY(0,0);
}
/*void LCDWriteString(const char *msg)
{
/*****************************************************************
This function Writes a given string to lcd at the current cursor
location.
Arguments:
msg: a null terminated string to print
*****************************************************************
while(*msg!='\0')
{
LCDData(*msg);
msg++;
}
}*/
void LCDWriteInt(int val,unsigned int field_length)
{
/***************************************************************
This function writes a integer type value to LCD module
Arguments:
1)int val : Value to print
2)unsigned int field_length :total length of field in which the value is printed
must be between 1-5 if it is -1 the field length is no of digits in the val
****************************************************************/
char str[5]={0,0,0,0,0};
int i=4,j=0;
while(val)
{
str[i]=val%10;
val=val/10;
i--;
}
if(field_length==-1)
while(str[j]==0) j++;
else
j=5-field_length;
if(val<0)
LCDData('-');
for(i=j;i<5;i++)
{
LCDData(48+str[i]);
}
}
/*void LCDGotoXY(uint8_t x,uint8_t y)
{
if(x<40)
{
if(y) x|=0b01000000;
x|=0b10000000;
LCDCmd(x);
}
}*/
void LCDWriteString(const char *msg)
{
/*****************************************************************
This function Writes a given string to lcd at the current cursor
location.
Arguments:
msg: a null terminated string to print
Their are 8 custom char in the LCD they can be defined using
"LCD Custom Character Builder" PC Software.
You can print custom character using the % symbol. For example
to print custom char number 0 (which is a degree symbol), you
need to write
LCDWriteString("Temp is 30%0C");
^^
|----> %0 will be replaced by
custom char 0.
So it will be printed like.
Temp is 30°C
In the same way you can insert any syblom numbered 0-7
*****************************************************************/
while(*msg!='\0')
{
//Custom Char Support
if(*msg=='%')
{
msg++;
int8_t cc=*msg-'0';
if(cc>=0 && cc<=7)
{
LCDData(cc);
}
else
{
LCDData('%');
LCDData(*msg);
}
}
else
{
LCDData(*msg);
}
msg++;
}
}
void LCDGotoXY(uint8_t x, uint8_t y) //Cursor to X Y position
{
register uint8_t DDRAMAddr;
// remap lines into proper order
switch(y)
{
case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
//case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
//case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
}
// set data address
LCDCmd( 1<< LCD_DDRAM | DDRAMAddr);
}
void LCDcursorOFF(void) //turns OFF cursor
{
LCDCmd(0x0C);
}
void LCDrewindarrow(void) //turns OFF cursor
{
unsigned int i;
//uint16_t string[10]={0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00};
uint16_t string[8]={0x0E, 0x11, 0x11, 0x11, 0x11, 0x13, 0x17, 0x1F}; //Char0
for (i=0;i<8;i++)
LCDData(string[i]);
}
Last edited by a moderator: