Bench Power Supply 2.0

0-25v @ 0-5Amp

I need someone to correct my grammatical error, thanks

History

This project is like the one that all of you must have done in electronics.  I took the idea from Circuit Cellar. The original power supply provides an output of 2.5-15V at 500mA. This circuit will provide 0-25V at 0 to 5A. You will see there is a lot of modification to achieve this.

This is my second version of this power supply, the first one was made with mosfet who need a higher voltage on the gate I had to use a higher input voltage and because of this there was a lot of heat generated for nothing.  This version work with transistor and it's much more better.  

    I will explain you some part of this power supply.  First you must find a transformer which can handle 24VAC at 5A and one with 6.3VAC at 100ma.  I use 2 transformator to have 2 DC level 30V and 40V. The 30V Power the high current for the output and the 40V power all the rest of the circuit.  The LT7013 opamp is split in 2 function, the part A is the voltage control and the part B is the current control both opamp output is connected together via diode so the one who output a lower voltage win on the second, so if you set your voltage to 10V and your current to 1A and you short your ouput the current part will pull down his output and the voltage will drop.  The current part use a very nice component the ZXCT1009 that work like a current mirror.  it will generate a current proportionally the the one who pass in the sense resistor, this current is pass in the pot R8 who convert it in voltage.  The output have many transistor because the opamp can't give a lot of current, and note that the resistor R23 is very important, this one will protect your output transistor from a output short circuit "transistor explosion is faster than the current sense".  If you build this supply you will be impress how fine it's work.

    I also connect to this power supply a LCD to inform you of the set point for voltage and current, plus the current voltage and current.  It's done with a small ATMega32 with 4 A/D input to received the value from the power supply and with some simple calculation it display those value.

 

Features

puce Output Voltage adjustable from 0 to 25v
puce Output Current adjustable from 0 to 5amp
puce Digital reading of set points for current & voltage and output current & voltage.
puce No need of multi tap transformer or center tap transformer
puce Short circuit protected
puce Very low cost

 

Pictures (from the version 1.0)

Click to enlarge

Power supply side view

LCD Display

 

Power supply back view

Power supply front view

 

 

LCD Display

Power supply top view

 

Sources codes & Schematics

-Schematic of the powersupply  in PDF format

-Schematic of the digital volt & amp reading  in PDF format

-Printed Circuit Board of this power supply!!!!

-Circuit cellar inspiration article  in PDF format

 

//*****************************************************************************
//
Powersupply
// Version 1.0 Jan 2007
//
// 1.0 -> -Everything is new
//
// Sylvain Bissonnette
//*****************************************************************************
// Editor : UltraEdit32
//*****************************************************************************
//
//                    R E T U R N   S T A C K   6 4
//                    Internal RC oscillator of 8Mhz
//                   
//*****************************************************************************
//
//                          F U S E   B I T
//
//( )7      ( )6     ( )BL12 ( )BL11  ( )BL02   ( )BL01    ( )Lock2   ( )Lock1
//( )7      ( )6     ( )     ( )      ( )       ( )M103C   ( )WDTON   ( )
//( )OCDEN  ( )JTAGE (X)SPIEN(X)CKOPT (X)EESAVE ( )BOOTSZ1 (X)BOOTSZ0 (X)BOOTRST
//(X)BODLEV (X)BODEN ( )SUT1 (X)SUT0  ( )CKSEL3 (X)CKSEL2  ( )CKSEL1  ( )CKSEL0
//
//*****************************************************************************
//                          P I N   U S A G E
//
// PA0 -> GND
// PA1 -> ADC Input #1
// PA2 -> ADC Input #2
// PA3 -> ADC Input #3
// PA4 -> ADC Input #4
// PA5 -> GND
// PA6 -> GND
// PA7 -> GND
//
// PB0 -> N/C
// PB1 -> N/C
// PB2 -> N/C
// PB3 -> N/C
// PB4 -> N/C
// PB5 -> N/C
// PB6 -> N/C
// PB7 -> N/C
//
// PC0 -> LCD DB7
// PC1 -> LCD DB6
// PC2 -> LCD DB5
// PC3 -> LCD DB4
// PC4 -> LCD E
// PC5 -> LCD R/W
// PC6 -> LCD RS
// PC7 -> LCD BackLight
//
// PD0 -> N/C
// PD1 -> N/C
// PD2 -> +5
// PD3 -> LED
// PD4 -> N/C
// PD5 -> N/C
// PD6 -> N/C
// PD7 -> LCD Contrast
//
//*****************************************************************************
//                        T I M E R   U S A G E
//
// Timer 0 not use
// Timer 1 not use
// Timer 2 is use for LCD Contrast
// Timer 3 not use
//
//*****************************************************************************

//*****************************************************************************
//                            I N C L U D E
//*****************************************************************************
#include <iom32v.h>
#include <shortnametype.h>
#include <macros.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <eeprom.h>

//*****************************************************************************
//                            D E F I N E
//*****************************************************************************
#define VERSION                 10
#define TRUE                    1
#define FALSE                   0
#define XTAL                    16000000
#define LED                               (1<<PD3);

// ADC
#define ADC2                              (1<<REFS0) + 2
#define ADC3                              (1<<REFS0) + 3
#define ADC4                              (1<<REFS0) + 4
#define ADC5                              (1<<REFS0) + 5

// LCD
#define LCD_D7                  0x01
#define LCD_D6                  0x02
#define LCD_D5                  0x04
#define LCD_D4                  0x08
#define LCD_E                   0x10
#define LCD_RW                  0x20
#define LCD_RS                  0x40
#define LCD_BACKLIGHT           0x80

#define LCD_PIN                 PINC
#define LCD_DDR                 DDRC
#define LCD_PORT                PORTC

#define LCD_DATA                0x01
#define LCD_CTRL                0x00

#define LCD_C_BLINK_ON          0x09
#define LCD_C_BLINK_OFF         0xfe
#define LCD_C_ON                0x0a
#define LCD_C_OFF               0xfd
#define LCD_DISPLAY_ON          0x0c
#define LCD_DISPLAY_OFF         0xfb
#define LCD_BRIGHT_25           0x23
#define LCD_BRIGHT_50           0x22
#define LCD_BRIGHT_75           0x21
#define LCD_BRIGHT_100          0x20
#define LCD_BACKLIGHT_ON        0x24
#define LCD_BACKLIGHT_OFF       0x25



//*****************************************************************************
//                            P R O T O T Y P E
//*****************************************************************************
void main(void);
void Info(void);
void Delay(ushort Del);

// A/D
void ADInit(void);
void AD_interrupt(void);

// LCD
void LCDInit(ushort x,ushort y);
void LCDOff(void);
void LCDClrSCR(void);
void LCDGotoXY(ushort,ushort);
ushort LCDWhereX(void);
ushort LCDWhereY(void);
void LCDWriteString(char *);
void LCDWriteConstString(const char *);
void LCDWriteChar(char);
void LCDWriteData(ushort,ushort);
ushort LCDReadData(ushort rs);
void LCDCreateCHR(ushort chnumber, char *ptr);
void LCDWait(void);
void LCDDelay50us(int Delay);
void LCDTextAttr(ushort attribute);
void LCDContrast(ushort Cont);

//*****************************************************************************
//                      G L O B A L   V A R I A B L E
//*****************************************************************************

// LCD
ushort MaxX, MaxY, LCDStat;
char Text[20];

// ADC
int AD1;
int AD2;
int AD3;
int AD4;

//*****************************************************************************
//                      M A I N
//*****************************************************************************
void main()
{
   float VoltSet,Volt,CurrentSet,Current;

  WDR();
  WDTCR = 0x0f; // Watch Dog enable
  LCDInit(20,2);
  ADInit();
  DDRD |= LED;

  SEI(); //re-enable interrupts

  Info();
  Delay(75);
  LCDClrSCR();
   LCDGotoXY(1,1);
   LCDWriteConstString("Vset:      Vout:\0");
   LCDGotoXY(1,2);
   LCDWriteConstString("Aset:      Aout:\0");

  while(1)
  {
    WDR();
    _StackCheck();
    PORTD ^= LED;

    VoltSet =    (((float)(AD2)) * 25) / 1024;
    Volt =       (((float)(AD1)) * 25) / 1024;
    CurrentSet = (((float)(AD4)) * 4) / 1024;
    Current =    (((float)(AD3)) * 4) / 1024;

    LCDGotoXY(6,1);
    csprintf(&Text[0],"%#4.1f\0",VoltSet);
      LCDWriteString(&Text[0]);

      LCDGotoXY(17,1);
      csprintf(&Text[0],"%#4.1f\0",Volt);
      LCDWriteString(&Text[0]);

      LCDGotoXY(6,2);
    csprintf(&Text[0],"%#4.1f\0",CurrentSet);
      LCDWriteString(&Text[0]);

      LCDGotoXY(17,2);
      csprintf(&Text[0],"%#4.1f\0",Current);
      LCDWriteString(&Text[0]);

    Delay(5);
  }
}

/******************************************************************************

Name:         void _StackOverflowed(char c)

Description:  This function is automaticaly called if
              the stack crash/


Input:        none

Output:       none

Misc:
******************************************************************************/
void _StackOverflowed(char c)
{
  while(TRUE);
}

/*****************************************************************************

Name:         void Info(void)

Description:  Display power on message

Input:        void

Output:       void

Misc:        

******************************************************************************/
void Info(void)
{
  LCDClrSCR();
  LCDGotoXY(1,1);
  LCDWriteConstString("PowerSupply  Ver:1.0\0");
  LCDGotoXY(1,2);
  LCDWriteConstString("Sylvain  Bissonnette\0");
}

/******************************************************************************

Name:         void Delay(ushort Del)

Description:  This function make a delay

Input:        none

Output:       none

Misc:
******************************************************************************/
void Delay(ushort Del)
{
  int i,j;
  for (i=0;i<Del;i++) for (j=0;j<32000;j++) WDR();
}

/******************************************************************************

Name:         ADCInit(void)

Description:  This function initialize the ADC

Input:        none

Output:       none

Misc:
******************************************************************************/
void ADInit(void)
{
   ADCSRA = (1<<ADEN) + (1<<ADIE) + (1<<ADPS2) + (1<<ADPS1) + (1<<ADPS0);
  ADMUX = ADC2;

  ADCSRA |= (1<<ADSC);      // Start AD convertion
}

/******************************************************************************

Name:         AD_interrupt(void)

Description:  This function is automaticaly called when the AD had finish
              is convertion

Input:        none

Output:       none

Misc:
******************************************************************************/
#pragma interrupt_handler AD_interrupt:17
void AD_interrupt(void)
{

   if (ADMUX == ADC2)
   {
      AD1 = (int)((int)ADCH << 8) + ADCL;
      ADMUX = ADC3;
   }

   else if (ADMUX == ADC3)
   {
      AD2 = (int)((int)ADCH << 8) + ADCL;
      ADMUX = ADC4;
   }

   else if (ADMUX == ADC4)
   {
      AD3 = (int)((int)ADCH << 8) + ADCL;
      ADMUX = ADC5;
   }

   else if (ADMUX == ADC5)
   {
      AD4 = (int)((int)ADCH << 8) + ADCL;
      ADMUX = ADC2;
   }

   ADCSRA |= (1<<ADSC);      // Start AD convertion
}

//*****************************************************************************
// LCD Code
//*****************************************************************************
/******************************************************************************

Name:         LCDCreateCHR

Description:  Create a new char in CGRAM

Input:        ushort  : Character number (0-7)
              *ushort : 7 ushort containing the data

Output:       none

Misc:

******************************************************************************/
void LCDCreateCHR(ushort chnumber, char *ptr)
{
  ushort i,j;

  i = 8 * chnumber;

  for (j=0;j<8;j++)
  {
    LCDWriteData(LCD_CTRL,(0x40 | (i + j)));
    LCDWriteData(LCD_DATA,ptr[j]);
  }
}


/******************************************************************************

Name:         void LCDClrSCR(void)

Description:  Clear the LCD

Input:        none

Output:       none

Misc:

******************************************************************************/
void LCDClrSCR(void)
{
  LCDWait();
  LCDWriteData(LCD_CTRL,0x01);      // Clear display
}

/******************************************************************************

Name:         LCDGotoXY(ushort x, ushort y)

Description:  Position cursor on the LCD at X & Y location

Input:        X -> X position on the LCD
              Y -> Y position on the LCD

Output:       none

Misc:

******************************************************************************/
void LCDGotoXY(ushort x,ushort y)
{
  ushort address;

  x--;

  if (MaxY < 3)
  {
    switch(y)
    {
      case '\x01' :
      address = 0 + x;
      break;
      case '\x02' :
      address = 64 + x;
      break;
    }
  }
  else
  {
    switch(y)
    {
      case '\x01' :
      address = 0 + x;
      break;
      case '\x02' :
      address = 64 + x;
      break;
      case '\x03' :
      address = 20 + x;
      break;
      case '\x04' :
      address = 84 + x;
      break;
    }
  }
  LCDWriteData(LCD_CTRL,address | 0x80);
}

/******************************************************************************

Name:         LCDWhereX

Description:  Get the x position of the cursor on the LCD

Input:        None

Output:       ushort : Cursor position "x"

Misc:

******************************************************************************/
ushort LCDWhereX(void)
{
ushort i,x,y;

i = LCDReadData(LCD_CTRL) & 0x7f;

y = LCDWhereY();

if (MaxY == 2)
    {
    if (y == 1) x = i;
    if (y == 2) x = i - 0x40;
    }
else if (MaxY == 4)
    {
    if (y == 1) x = i;
    if (y == 2) x = i - 0x40;
    if (y == 3) x = i - 0x14;
    if (y == 4) x = i - 0x54;
    }
x = x + 1;
return x;
}

/******************************************************************************

Name:         LCDWhereY

Description:  Get the y position of the cursor on the LCD

Input:        None

Output:       ushort : Cursor position "y"

Misc:

******************************************************************************/
ushort LCDWhereY(void)
{
  ushort i,j;

  i = LCDReadData(LCD_CTRL) & 0x7f;

  if (MaxY == 2)
  {
    if (i < 0x28) j = 1;
    else j = 2;
  }
  else if (MaxY == 4)
  {
    if ((i >0x00) && (i < 0x15)) j = 1;
    if ((i >0x14) && (i < 0x28)) j = 3;
    if ((i >0x40) && (i < 0x55)) j = 2;
    if ((i >0x54) && (i < 0x68)) j = 4;
  }
  return j;
}

/******************************************************************************

Name:         WtireByteLCD(char byte)

Description:  Write a byte on the LCD at cursor position

Input:        byte

Output:       none

Misc:

******************************************************************************/
void LCDWriteChar(char byte)
{
  char tmp;

  tmp = byte & 0xf0;
  tmp = tmp >> 4;
  tmp += 0x30;
  if (tmp > 0x39) tmp += 0x07;
  LCDWriteData(LCD_DATA,tmp);

  tmp = byte & 0x0f;
  tmp += 0x30;
  if (tmp > 0x39) tmp += 0x07;
  LCDWriteData(LCD_DATA,tmp);
}

/******************************************************************************

Name:         void LCDWriteString(char *ptr)

Description:  Write a string from RAM on the LCD

Input:        string pointer

Output:       none

Misc:

******************************************************************************/
void LCDWriteString(char *ptr)
{
  ushort i;

  for (i=1;i<41;i++)
  {
    if (*ptr == 0x00) break;
    LCDWriteData(LCD_DATA,*ptr++);
  }
}

/******************************************************************************

Name:         void LCDWriteConstString(const char *ptr)

Description:  Write a constant string on the LCD

Input:        string pointer

Output:       none

Misc:

******************************************************************************/
void LCDWriteConstString(const char *ptr)
{
  ushort i;

  for (i=1;i<41;i++)
  {
    if (*ptr == 0x00) break;
    else if (i == 21) LCDGotoXY(1,2);
    LCDWriteData(LCD_DATA,*ptr++);
  }
}

/******************************************************************************

Name:         void LCDWriteData(ushort rs, ushort ch)

Description:  Write a byte in rs of the LCD

Input:        rs -> Register select
              ch -> byte to write

Output:       none

Misc:

******************************************************************************/
void LCDWriteData(ushort rs,ushort ch)
{
  ushort Stat;

  Stat = LCD_PIN & LCD_BACKLIGHT;

  LCD_PORT = Stat;

  LCDWait();

  if ((ch & 0x80) == 0x80) LCD_PORT |= LCD_D7;
  if ((ch & 0x40) == 0x40) LCD_PORT |= LCD_D6;
  if ((ch & 0x20) == 0x20) LCD_PORT |= LCD_D5;
  if ((ch & 0x10) == 0x10) LCD_PORT |= LCD_D4;
  if (rs == 1) LCD_PORT |= LCD_RS;
   LCDDelay50us(1);
  LCD_PORT |= LCD_E;
  LCD_PORT &= ~LCD_E;

  LCD_PORT = Stat;
  if ((ch & 0x08) == 0x08) LCD_PORT |= LCD_D7;
  if ((ch & 0x04) == 0x04) LCD_PORT |= LCD_D6;
  if ((ch & 0x02) == 0x02) LCD_PORT |= LCD_D5;
  if ((ch & 0x01) == 0x01) LCD_PORT |= LCD_D4;
  if (rs == 1) LCD_PORT |= LCD_RS;
   LCDDelay50us(1);
  LCD_PORT |= LCD_E;
  LCD_PORT &= ~LCD_E;
}

/******************************************************************************

Name:         ushort LCDRead(ushort rs)

Description:  read a byte in rs of the LCD

Input:        rs -> Register select

Output:       ushort

Misc:    

******************************************************************************/
ushort LCDReadData(ushort rs)
{
  ushort Byte=0;

  LCD_DDR &= ~(LCD_D7 + LCD_D6 + LCD_D5 + LCD_D4);

  LCD_PORT = LCD_PIN & LCD_BACKLIGHT;
  LCD_PORT |= LCD_RW;
  if (rs == 1) LCD_PORT |= LCD_RS;
  LCDDelay50us(1);

  LCD_PORT |= LCD_E;
  LCD_PORT |= LCD_E;
  if (LCD_PIN & LCD_D7) Byte |= 0x80;
  if (LCD_PIN & LCD_D6) Byte |= 0x40;
  if (LCD_PIN & LCD_D5) Byte |= 0x20;
  if (LCD_PIN & LCD_D4) Byte |= 0x10;
  LCD_PORT &= ~LCD_E;

  LCD_PORT |= LCD_E;
  LCD_PORT |= LCD_E;
  if (LCD_PIN & LCD_D7) Byte |= 0x08;
  if (LCD_PIN & LCD_D6) Byte |= 0x04;
  if (LCD_PIN & LCD_D5) Byte |= 0x02;
  if (LCD_PIN & LCD_D4) Byte |= 0x01;
  LCD_PORT &= ~LCD_E;

  LCD_PORT &= ~LCD_RW;

  LCD_DDR |= LCD_D7 + LCD_D6 + LCD_D5 + LCD_D4;

  return (Byte);
}

/******************************************************************************

Name:         void LCDWait(void)

Description:  wait for the LCD to be ready

Input:        none

Output:       none

Misc:    

******************************************************************************/
void LCDWait(void)
{
  while((LCDReadData(0) & 0x80) == 0x80) WDR();
}

/******************************************************************************

Name:         void LCDDelay50us(int Delay)

Description:  Delay of 50 us with a 1Mhz resonator

Input:        Delay X x 50us

Output:       none

Misc:

******************************************************************************/
void LCDDelay50us(int Delay)
{
  int i,j;

  for (i=0;i<Delay;i++)
  {
    for (j=1;j<120;j++);
    asm("WDR");
  }
}

/******************************************************************************

Name:         void LCDTextAttr(ushort Attribute)

Description:  Set the LCD attribute

Input:        LCD_C_BLINK_ON     : Cursor blink on
              LCD_C_BLINK_OFF    : Cursor blink off
              LCD_C_ON           : Cursor on
              LCD_C_OFF          : Cursor off
              LCD_DISPLAY_ON     : Display ON
              LCD_DISPLAY_OFF    : Display OFF
              LCD_BRIGHT_25      : VFD 25% Bright
              LCD_BRIGHT_50      : VFD 50% Bright
              LCD_BRIGHT_75      : VFD 75% Bright
              LCD_BRIGHT_100     : VFD 100% Bright
              LCD_BACK_LIGHT_ON  : Back Light ON
              LCD_BACK_LIGHT_OFF : Back Light OFF

Output:       none

Misc:

******************************************************************************/
void LCDTextAttr(ushort attribute)
{
switch (attribute)
    {
    case LCD_C_BLINK_ON:
         LCDStat |= LCD_C_BLINK_ON;
         LCDWriteData(LCD_CTRL,LCDStat);
         break;

    case LCD_C_BLINK_OFF:
         LCDStat &= LCD_C_BLINK_OFF;
         LCDWriteData(LCD_CTRL,LCDStat);
         break;

    case LCD_C_ON:
         LCDStat |= LCD_C_ON;
         LCDWriteData(LCD_CTRL,LCDStat);
         break;

    case LCD_C_OFF:
         LCDStat &= LCD_C_OFF;
         LCDWriteData(LCD_CTRL,LCDStat);
         break;

    case LCD_DISPLAY_ON:
         LCDStat |= LCD_DISPLAY_ON;
         LCDWriteData(LCD_CTRL,LCDStat);
         break;

    case LCD_DISPLAY_OFF:
         LCDStat &= LCD_DISPLAY_OFF;
         LCDWriteData(LCD_CTRL,LCDStat);
         break;

    case LCD_BRIGHT_25:
         LCDWriteData(LCD_CTRL,0x20);
         LCDWriteData(LCD_DATA,0x03);
         break;

    case LCD_BRIGHT_50:
         LCDWriteData(LCD_CTRL,0x20);
         LCDWriteData(LCD_DATA,0x02);
         break;

    case LCD_BRIGHT_75:
         LCDWriteData(LCD_CTRL,0x20);
         LCDWriteData(LCD_DATA,0x01);
         break;

    case LCD_BRIGHT_100:
         LCDWriteData(LCD_CTRL,0x20);
         LCDWriteData(LCD_DATA,0x00);
         break;

    case LCD_BACKLIGHT_ON:
         LCD_PORT |= LCD_BACKLIGHT;
         break;

    case LCD_BACKLIGHT_OFF:
         LCD_PORT &= ~(LCD_BACKLIGHT);
         break;
    }
}

/******************************************************************************

Name:         void LCDOn(ushort X, ushort Y)

Description:  Initialize LCD in 4bit mode

Input:        ushort X -> X size
              ushort Y -> Y size

Output:       none

Misc:

******************************************************************************/
void LCDInit(ushort X, ushort Y)
{
  MaxX = X;
  MaxY = Y;
  LCDStat = 0x0c;
  LCD_PORT = 0x00;
  LCD_DDR = LCD_D7+LCD_D6+LCD_D5+LCD_D4+LCD_E+LCD_RS+LCD_RW+LCD_BACKLIGHT;
  LCD_PORT = ~(LCD_D7+LCD_D6+LCD_D5+LCD_D4+LCD_E+LCD_RS+LCD_RW);
  LCD_PORT |= LCD_BACKLIGHT;
  LCDDelay50us(340);

  LCD_PORT = (LCD_D5 + LCD_D4 + LCD_BACKLIGHT);
  LCD_PORT |= LCD_E;
  LCD_PORT &= ~LCD_E;
  LCDDelay50us(100);
  LCD_PORT |= LCD_E;
  LCD_PORT &= ~LCD_E;
  LCDDelay50us(100);
  LCD_PORT |= LCD_E;
  LCD_PORT &= ~LCD_E;
  LCDDelay50us(100);

  LCD_PORT = (LCD_D5 + LCD_BACKLIGHT);
  LCD_PORT |= LCD_E;
  LCD_PORT &= ~LCD_E;
  LCDDelay50us(100);

  if (Y == 1) LCDWriteData(LCD_CTRL,0x20);    // 1 line
  else LCDWriteData(LCD_CTRL,0x28);           // 2 line

  LCDWriteData(LCD_CTRL,0x0c);                // Disp ON-Cur OFF-Blink OFF
  LCDWriteData(LCD_CTRL,0x01);                // Clear display
  LCDDelay50us(50);
  LCDWriteData(LCD_CTRL,0x06);                // Cursor INC Shift OFF

  DDRD |= 0x80;
  TCCR2 = 0x79;
  OCR2 = 0xf0;
}

/******************************************************************************

Name:         void LCDContrast(ushort Cont)

Description:  Set the LCD Contrast

Input:        from 0 to 255

Output:       none

Misc:

******************************************************************************/
void LCDContrast(ushort Cont)
{
  OCR2 = Cont;
}

/******************************************************************************

Name:         void LCDOff(void)

Description:  Shut down LCD

Input:        none

Output:       none

Misc:

******************************************************************************/
void LCDOff(void)
{
 LCD_DDR = 0xff;
 LCD_PORT = 0x00;
 DDRD &= ~0x80;
}