/************************************************** ***
************************************************** ***/
#include <mega8.h>
#include <stdio.h>
#include <delay.h>
#define PROGRESSPIXELS_PER_CHAR 6
void LCDprogressBar(unsigned char progress,unsigned char maxprogress,unsigned char length);
void define_char(unsigned char flash *pc,unsigned char char_code);
flash unsigned char LcdCustomChar0[] =//define 8 custom LCD chars
{
0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00 // 0. 0/5 full progress block
};
const unsigned char LcdCustomChar1[] =//define 8 custom LCD chars
{
0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00 // 1. 1/5 full progress block
};
const unsigned char LcdCustomChar2[] =//define 8 custom LCD chars
{
0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00 // 2. 2/5 full progress block
};
const unsigned char LcdCustomChar3[] =//define 8 custom LCD chars
{
0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00 // 3. 3/5 full progress block
};
const unsigned char LcdCustomChar4[] =//define 8 custom LCD chars
{
0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00 // 4. 4/5 full progress block
};
const unsigned char LcdCustomChar5[] =//define 8 custom LCD chars
{
0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00 // 5. 5/5 full progress block
};
const unsigned char LcdCustomChar6[] =//define 8 custom LCD chars
{
0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00 // 6. rewind arrow
};
const unsigned char LcdCustomChar7[] =//define 8 custom LCD chars
{
0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00 // 7. fast-forward arrow
};
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
unsigned int vv,v,i,Vadj1,Vadj2,Iadj1,Iadj2,Iadj3;
unsigned char buff[20];
unsigned int adc_data,i_limit;
unsigned char ADC_VREF_TYPE=0x40;
#define buz PORTD.4
interrupt [EXT_INT0] void ext_int0_isr(void)
{
}
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
// Read the AD conversion result
adc_data=ADCW;
}
// Read the AD conversion result
// with noise canceling
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
#asm
in r30,mcucr
cbr r30,__sm_mask
sbr r30,__se_bit | __sm_adc_noise_red
out mcucr,r30
sleep
cbr r30,__se_bit
out mcucr,r30
#endasm
return adc_data;
}
void main(void)
{
DDRD=0XF0;
PORTD=0X0F;
// ADC initialization
// ADC Clock frequency: 500.000 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x8D;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
GICR|=0x40;
MCUCR=0x02;
GIFR=0x40;
lcd_init(16);
#asm("sei")
lcd_putsf(" HOSSEIN TOMARI");
lcd_gotoxy(0,1);
lcd_putsf(" V-A METER ");
delay_ms(2000);
lcd_clear();
lcd_putsf(" POWER SUPPLY");
delay_ms(2000);
define_char(LcdCustomChar0,0);
define_char(LcdCustomChar1,1);
define_char(LcdCustomChar2,2);
define_char(LcdCustomChar3,3);
define_char(LcdCustomChar4,4);
define_char(LcdCustomChar5,5);
define_char(LcdCustomChar6,6);
define_char(LcdCustomChar7,7);
while (1)
{
ADC_VREF_TYPE=0x40;
v=read_adc(0)*4.8875855327468;
vv=v;
Vadj1=(v%100)/10;
Vadj2=(v%100)%10;
v=v/100;
sprintf(buff,"V=%d.%d%d ",v,Vadj1,Vadj2);
lcd_gotoxy(0,0);
lcd_puts(buff);
i=(read_adc(1)*5)/(1.023*0.56);
if(i<1000)
{
ADC_VREF_TYPE=0x00;
i=(read_adc(1)*1)/(1.023*0.56);
}
else
ADC_VREF_TYPE=0x40;
if(i<1000)
{
sprintf(buff,"I=%d mA ",i);
lcd_gotoxy(8,0);
lcd_puts(buff);
}
else
{
Iadj1=(i%1000)/100;
Iadj2=((i%1000)/10)%10;
Iadj3=(i%1000)%10;
sprintf(buff,"I=%d.%d%d%dA",i/1000,Iadj1,Iadj2,Iadj3);
lcd_gotoxy(8,0);
lcd_puts(buff);
}
/*while(i>=(read_adc(2)*5)/(1023))
{
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("CURRENT LIMITED");
lcd_gotoxy(0,1);
sprintf(buff,"I=%d mA",i);
lcd_puts(buff);
while(i>=(read_adc(1)*1)/(1.023*0.56))
{
buz=1;
delay_ms(100);
buz=0;
delay_ms(500);
}
}*/
lcd_gotoxy(0,1);
LCDprogressBar(v,40,16);
delay_ms(500);
};
}
void LCDprogressBar(unsigned char progress,unsigned char maxprogress,unsigned char length)
{
unsigned char ii;
unsigned int pixelprogress;
unsigned char c;
// draw a progress bar displaying (progress / maxprogress)
// starting from the current cursor position
// with a total length of "length" characters
// ***note, LCD chars 0-5 must be programmed as the bar characters
// char 0 = empty ... char 5 = full
// total pixel length of bargraph equals length*PROGRESSPIXELS_PER_CHAR;
// pixel length of bar itself is
pixelprogress = ((length*PROGRESSPIXELS_PER_CHAR));
pixelprogress=progress*pixelprogress;
pixelprogress =pixelprogress/maxprogress;
// print exactly "length" characters
for(ii=0; ii<length; ii++)
{
// check if this is a full block, or partial or empty
// (u16) cast is needed to avoid sign comparison warning
if( ((ii*PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
{
// this is a partial or empty block
if( ((ii*PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
{
// this is an empty block
// use space character?
c = 0;
}
else
{
// this is a partial block
c = pixelprogress % PROGRESSPIXELS_PER_CHAR;
}
}
else
{
// this is a full block
c = 5;
}
// write character to display
lcd_putchar(c);
}
}
void define_char(unsigned char flash *pc,unsigned char char_code)
{
unsigned char i,a;
a=(char_code<<3)|0x40;
for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);
}