Programm in C

 

Hauptprogramm

Display-Unterprogramm

zurück zum Softwaremenü


Hauptprogramm

/*****************************************************************************************
**											**
**      Datei: Auswucht.C                                            			**
**      Das Programm bewirkt: Steuerung der Auswuchtmaschine,        			**
**			      Kommunikation zwischen Controller,     			**
**                            Tastatur und Display über I2C-Bus      			**
**                                                                   			**
**      Eingangsparameter:      KEINE!  (void)                       			**
**                                                                   			**
**      Ausgangsparameter:      KEINE!  (void)                       			**
**                                                                   			**
**      Rueckgabewert:          KEINER! (void)                       			**
**                                                                   			**
******************************************************************************************
**                                                                   			**
**      Autor: Anne Magin, Thorsten Breuer                           			**
**      Datum: 09.01.1999                              WS 98/99      			**
**                                                                   			**
*****************************************************************************************/

/********************* Steueranweisungen fuer den Compiler ******************************/

#pragma OBJECTEXTEND             /* typengerechtes Programm Debug */
#pragma CODE DEBUG               /* Symbolisches Debuggen ein */
#pragma SYMBOLS                  /* alle Symbole werden aufgelistet */

/*************************** Text im Quelltext einbinden ********************************/

#include <DISP.C>

/*************************** globale Variablen ******************************************/

sbit Schlitten_i = 0xFA;                        /*Schlitten: Stepper Impulse*/
sbit Schlitten_r = 0xFB;                        /*Schlitten: Stepper Richtung*/
sbit End = 0x95;				/*Endschalter an Massen, P1.5 Leiste C15*/
sbit Ref = 0xEE;                                /*Nullsignal der Lichtschranke*/
sbit P44 = 0xEC;                                /*Achsausrichtung: Stepper Impulse*/
sbit P45 = 0xED;				/*Achsausrichtung: Stepper Richtung*/
sbit P43 = 0xEB;				/*Stepper an Achse elekt. entkoppeln*/
sbit Kessler = 0xFF;                            /*Ein-Aus-Schalter fuer DC-Motor*/
sbit P54 = 0xFC;                                /*Massen: Stepper Impulse*/
sbit P55 = 0xFD;                                /*Massen: Stepper Richtung*/

unsigned int xdata Weg[4];			/*Array fuer 4 Verstellwege der Gewichte*/
unsigned int xdata zaehler;			/*Zaehlervariable fuer Timer*/
unsigned int xdata Weg_temp;			/*temporaere Wegvariable*/
unsigned int xdata impulse;			/*Variable fuer abzuarbeitende Impulse*/
unsigned char xdata j;				/*Zaehlervariable für Warteschleife*/
unsigned char xdata achs_pos;                   /*Variable fuer aktuelle Achsenposition*/
unsigned char xdata rotation;			/*Erkennungsbit fuer Rotation*/
unsigned int xdata step;			/*allgemeine Impulsvariable*/

unsigned char xdata Masse;			/*Variable fuer das gewaehlte Arrayelement*/
unsigned char xdata key_old;			/*zuletzt gedrückte Taste*/
unsigned int xdata drueckauf;			/*Zähler für die Erkennung von*/
unsigned int xdata drueckab;			/*permanentem Tastendruck*/


/*************************** Prototypen **************************************************/

void Timer_0_ISR(void);			  	/*Prototyp - Timerunterprogramm*/
void impuls(void);			        /*Prototyp - Motorimpuls-Unterprogramm*/
void drueck_zeit(void);				/*Prototyp - Drueckzeit der Tasten*/
void achse(void);				/*Prototyp - Positionierung der Achsen*/
void referenz_m(void);                          /*Prototyp - Referenzposition von Massen*/
void referenz_a(void);                          /*Prototyp - Referenzposition von Aufbau*/
void wellenrotation();				/*Prototyp - Rotation der Unwucht*/
void eingabefenster();				/*Prototyp - Displayausgabe*/
void init_variablen();				/*Prototyp - Initialisierung der Variablen*/
void werbefernsehen();


/****************************************************************************************/
/*                                    Hauptprogramm                                     */
/****************************************************************************************/

void main(void)
{
  SP = 99;

  init_variablen();				/* Initialisierungsteil*/

  initial_i2c();
  display_init();
  clear_display();
  werbefernsehen();

  referenz_a();					/*Aufbau in Ausgangsposition fahren*/
  referenz_m();					/*Massen in Ausgangsposition fahren*/

  eingabefenster();

/*----------------------------------------------------------------------------*/
 
 while (1)					/*Endlosschleife Tastaturabfrage*/  
 {
   key = taste_einlesen();			/*Tastatur einlesen*/
   if (key=='1' || key=='2'|| key=='3'|| key=='4') 
   {   str[0] = key;
       str[1] = '\0';
       write(112);
       Masse = ((int) key)-49;
       Weg_temp = Weg[Masse];
       zahlausgabe(Weg_temp);
    }
/*-----------------------------------------------------------------------------*/
  if (key=='5')
  {
     if (Weg_temp>0)
     {
	Weg_temp = Weg_temp-1;
        if (key==key_old)
	{          
	   if (drueckauf<30) drueckauf = drueckauf+1;            
  	   else if (Weg_temp>4) Weg_temp = Weg_temp-5;
        }
        zahlausgabe(Weg_temp);
     } 
     key_old = key;
     key = "j";
   }
   else drueckauf = 0;

/*-----------------------------------------------------------------------------*/
  if (key=='6')
  {
    if (Weg_temp<312)
    {
       Weg_temp = Weg_temp+1;
       if (key==key_old)
       {
	  if (drueckab<30) drueckab = drueckab+1;            
  	  else if (Weg_temp<308) Weg_temp = Weg_temp+5;
       }
       zahlausgabe(Weg_temp);
    }
    key_old = key;
    key = "j";
  }
  else drueckab = 0; 	

/*------------------------------------------------------------------------------*/
  if (key=='F') wellenrotation();

     
/*------------------------------------------------------------------------------*/
  if (key=='E' && Weg_temp!=Weg[Masse])
     {
	if(Weg_temp < Weg[Masse])		/*Abfrage ob Verfahrweg negativ*/
	{
          P55 = 0;			  	/*Motorrichtungsbit setzen*/
	  impulse = Weg[Masse] - Weg_temp;	/*absoluten Verfahrweg berechnen*/
	}
	else
	{
	  P55 = 1;		  	  	/*Motorrichtungsbit setzen*/
	  impulse =  Weg_temp - Weg[Masse]; 	/*absoluten Verfahrweg berechnen*/
	}

	if(rotation==1)	 referenz_a();	  	/*Referenz suchen falls Aufbau rotiert wurde*/
	  
        achse();                          	/*Unterprogramm zur Achsenpositionierung starten*/
        impuls();			  	/*Impuls-Unterprogramm starten*/



     }
  }
}


/******************************************************************************************/
/*				 U N T E R P R O G R A M M E 			          */
/******************************************************************************************/

/*********************** Unterprogramm fuer Timer_0 ***************************************/

void Timer_0_ISR(void) interrupt 1        	/* ISR-Routine*/
{
        zaehler--;				/* bei jedem Einsprung*/
	return;       		  
}

/*********************** Unterprogramm fuer Drueckzeit ************************************/

void drueck_zeit(void)
{
	TMOD = 0x1;		  		/*Modus 1, 16 bit Zaehler*/
	zaehler = 65535;	  		/*Zaehlervariable laden*/
	TL0 = 0;          	  		/*Zaehler auf 0 setzen*/
        TH0 = 0;
	TR0 = 1;				/*Zaehler starten*/
	while(!TF0);  				/*Warten bis Zaehler fertig*/
	zaehler = 65535;	  		/*Zaehlschleife noch einmal durchlaufen*/
	TL0 = 0;          	  	   	  
        TH0 = 0;
	TR0 = 1;
	while(!TF0);
	TMOD = 0x0;		  		/*Modus 0, 8 bit Zaehler*/
	zaehler = 1;		  		/*Zaehlervariable laden*/
	TL0 = 0x1;          	  		/*Vorteiler auf 1 setzen*/
       	TH0 = 0x7d;				/*125µs zaehlen*/
	TR0 = 1;				/*Zaehler starten*/
	while(!TF0);				/*Warten bis Zaehler fertig*/
}


/******************** Unterprogramm fuer Eingabefenster ***********************************/

void eingabefenster()
{
 clear_display();

 strcpy(str,"Masse Nr.:");
 write(101);
 strcpy(str,"Ort: 00.00 mm");
 write(201);
  	 str[0] = ziffer[Masse+1];
	 str[1] = '\0';
	 write(112);
 zahlausgabe(Weg_temp);
}

/******************** Unterprogramm fuer Wellenrotation ***********************************/

void wellenrotation()
{  
 unsigned char xdata Cursor = 201;
	P43 = 0;	  	  		/*Stepper an Achse entkoppeln*/
	for (j=5;j>0;j--) drueck_zeit();	/*Warteschleife*/
 	rotation = 1;		  		/*Aufbau wurde rotiert*/
	Weg_temp = Weg[Masse];	  		/*Ruecksetzen voriger Eingaben*/
	Kessler = 1;		  		/*DC-Motor aktivieren*/
			
 clear_display();
 strcpy(str,"Welle rotiert!!!");
 write(101);
 str[2] = '\0';

 while (taste_einlesen() !='F')
 {
   str[0] = ' ';
   str[1] = '*';
   write(Cursor);
   Cursor = Cursor+1;
   wait(10000);
   if (Cursor==215) 
   { 
      str[1] = ' ';
      write(Cursor);
      str[1] = '*';
      Cursor = 201; 
   }    
 }
 wait(500);
 while (taste_einlesen() == 'F');

	Kessler = 0;				/*DC-Motor ausschalten*/
	for (j=20;j>0;j--) drueck_zeit();	/*Warteschleife bis Motorstillstand*/
 
 eingabefenster();
 
}

/************************** Initialisierung von Variablen und Portpins ********************/

void init_variablen()
{
	for(i=0;i<10;i=i+1)
	ziffer[i] = (char) (i+48);
	key = "";
	Kessler = 0;                            /*DC-Motor ausschalten*/
	P43 = 0;				/*Achsausrichtung abgekoppelt*/        
	Weg[0] = 0;			  	/*Alle Verfahrwege auf 0 setzen*/
        Weg[1] = 0;
	Weg[2] = 0;
	Weg[3] = 0;
	impulse = 0;				/*abzuarbeitende Impulse auf 0 setzen*/
	Masse = 0;				/*Array-Variable auf Element 0 setzen*/
	Weg_temp = Weg[Masse]; 			/*temp. Wegvariable Weg[0] zuweisen*/
        IEN0 = 0x92;                      	/*generelle Interruptfreigabe*/
        TMOD = 0x1;                       	/*Modus 1, 16 bit Zaehler*/
        TCON = 0x0;                       	/*TCON-Register setzen*/
	P45 = 1;				/*Drehrichtung fuer Achsausrichtung festlegen*/
}



/********************* Unterprogramm fuer Referenzposition Massen anfahren ****************/

void referenz_m()
{
  clear_display();
  strcpy(str,"Kalibrierung");				
  write(101);
  strcpy(str,"Bitte Warten....");
  write(201);

      j = 0;
      while(j<4)
      {                                      
	Schlitten_r = 1;			/*Vorfahren des Greifers*/
        Schlitten_i = 0;
	step = 4300;				/*Anzahl der Auf- und Abflanken bis Anschlag*/
        while(step>0)                              
        {  zaehler = 1;				/*Zaehlervariable fuer Timer mit 1 laden*/
	   TMOD = 0x0;		  		/*Modus 0, 8 bit Zaehler*/
	   TL0 = 0;				/*Zaehler auf 0 setzen*/
           TH0 = 0x7D;
	   TR0 = 1;				/*Zaehler starten*/
	   while(!TF0);				/*Warten bis Zaehler fertig*/		  
           Schlitten_i = ~Schlitten_i;		/*Motorflanken ausgeben*/
	   step--;
        }

						/*Massen zurueckdrehen*/
	P55 = 0;                             	/*Stepper-Richtungsbit auf Rückwärts setzten*/
	P54 = 0;
	step = 0;				/*Zaehlvariable fuer Flanken auf 0 setzen*/

        while(End)                          	/*Masse zum Anschlag drehen*/
        {  zaehler = 1;				/*Zaehlervariable fuer Timer mit 1 laden*/
	   TMOD = 0x0;		  		/*Modus 0, 8 bit Zaehler*/
	   TL0 = 0;				/*Zaehler auf 0 setzen*/
           TH0 = 0x7D;
	   TR0 = 1;				/*Zaehler starten*/
	   while(!TF0);				/*Warten bis Zaehler fertig*/
	   P54 = ~P54;				/*Motorflanken ausgeben*/
	   if(step==15) step = 0;		/*Flankenzahl nach 1/6 Drehung wieder auf 0 setzen*/
	   else step++;				/*Flankenzahl erhoehen*/
         }
	TR0 = 0;

	if(step!=0)				/*falls Masse nicht in definierter Position*/
	{  
           for(i=0;i<4;i++) drueck_zeit();      /*Kurze Pause vor Richtungsänderung*/
	   P55 = 1;
	   while(step>0)			/*Masse auf definierte Position zurueckdrehen*/
	   {	zaehler = 1;			/*Zaehlervariable fuer Timer mit 1 laden*/
	   	TMOD = 0x0;		  	/*Modus 0, 8 bit Zaehler*/
	   	TL0 = 0;			/*Zaehler auf 0 setzen*/
           	TH0 = 0x7D;
	   	TR0 = 1;			/*Zaehler starten*/
	   	while(!TF0);			/*Warten bis Zaehler fertig*/
	   	P54 = ~P54;
		step--;
	   }
	}
	TR0 = 0;


	Schlitten_r = 0;			/*Rueckfahren des Greifers*/
        Schlitten_i = 0;
	step = 4300;				/* 3840*/
        while(step>0)                              
        {	zaehler = 1;			/*Zaehlervariable fuer Timer mit 1 laden*/
		TMOD = 0x0;		  	/*Modus 0, 8 bit Zaehler*/
		TL0 = 0;			/*Zaehler auf 0 setzen*/
        	TH0 = 0x7D;
		TR0 = 1;			/*Zaehler starten*/
		while(!TF0);			/*Warten bis Zaehler fertig*/		  
                Schlitten_i = ~Schlitten_i;	/*Motorflanken ausgeben*/
		step--;
        }
	TR0 = 0;
						/*Aufbau weiterdrehen*/
	P44 = 0;
	step = 100;				/*Flankenanzahl fuer 1/4 Umdrehung*/
	while(step>0)                           /*Aufbau eine Position weiter drehen*/   
        {	zaehler = 1;			/*Zaehlervariable fuer Timer mit 1 laden*/
		TMOD = 0x1;		  	/*Modus 1, 16 bit Zaehler*/
		TL0 = 0;			/*Zaehler auf 0 setzen*/
        	TH0 = 0x7D;
		TR0 = 1;			/*Zaehler starten*/
		while(!TF0);			/*Warten bis Zaehler fertig*/		  
                P44 = ~P44;			/*Motorflanken ausgeben*/
		step--;
         }
       	TR0 = 0;
	j++;
      }
}

/***************** Unterprogramm fuer Referenzposition Aufbau anfahren ********************/

void referenz_a()
{
  clear_display();
  strcpy(str,"Suche");
  write(101);
  strcpy(str,"Referenzpunkt...");
  write(201);

	P44 = 0;				/*Stepper-Impulse auf 0 setzen*/
	P43 = 1;				/*Achsausrichtung ankoppeln*/
        while(Ref)                              /*Nullpunkt suchen (Ref=Signal des Nullpunkts)*/
	{                               
          zaehler = 1;				/*Zaehlervariable fuer Timer mit 1 laden*/
	  TMOD = 0x1;		  		/*Modus 1, 16 bit Zaehler*/
	  TL0 = 0;				/*Zaehler auf 0 setzen*/
          TH0 = 0x7D;
	  TR0 = 1;				/*Zaehler starten*/
	  while(!TF0);				/*Warten bis Zaehler fertig*/		  
          P44 = ~P44;				/*Motorflanken ausgeben*/
        }
	
        achs_pos = 0;                           /*Setzt aktuelle Achsposition auf 0*/
	rotation = 0;				/*Bit auf keine Rotation setzen*/

}


/****************** Unterprogramm fuer Positionierung der Achsen **************************/

void achse()
{
	clear_display();
	strcpy(str,"Welle wird");
	write(101);
	strcpy(str,"Positioniert...");
	write(201);

	P44 = 0;				/*Stepper-Impuls auf 0 setzen*/
	while(Masse!=achs_pos)			/*Drehen bis gewuenschte Position erreicht*/
	{  step = 100;				/*entspricht 1/4 Drehung bei Motor mit 200 Schritten*/
	   while(step>0)                        /*Aufbau 1/4 Umdrehung weiterdrehen*/      
           {	zaehler = 1;			/*Zaehlervariable fuer Timer mit 1 laden*/
		TMOD = 0x1;		  	/*Modus 1, 16 bit Zaehler*/
		TL0 = 0;			/*Zaehler auf 0 setzen*/
        	TH0 = 0x7D;
		TR0 = 1;			/*Zaehler starten*/
		while(!TF0);			/*Warten bis Zaehler fertig*/		  
                P44 = ~P44;			/*Motorflanken ausgeben*/
		step--;
            }
	   if(achs_pos==3) achs_pos = 0;
           else achs_pos++;                     /*Aktuelle Position um 1 erhöhen*/
	}
}



/*********************** Unterprogramm fuer Massenverstellung *****************************/

void impuls()
{
	int schlitt = 8*Weg[Masse];		/*Position der Masse in Schlittenposition umrechnen*/
	Weg[Masse] = Weg_temp;		  	/*IST-Wert wird jetzt geaendert*/
	clear_display();
	strcpy(str,"Masse Nr.");
	write(101);
	str[1] = '\0';
	str[0] = ziffer[Masse+1];
	write(111);
	strcpy(str,"wird verstellt...");
	write(201);

	Schlitten_r = 1;			/*Vorfahren des Greifers*/
        Schlitten_i = 0;
	step = 4300;				/*Anzahl der Auf- und Abflanken bis Anschlag*/
        while(step>schlitt)                     /*Greifer auf Position der Masse fahren*/         
        {	zaehler = 1;			/*Zaehlervariable fuer Timer mit 1 laden*/
		TMOD = 0x0;		  	/*Modus 0, 8 bit Zaehler*/
		TL0 = 0;			/*Zaehler auf 0 setzen*/
        	TH0 = 0x7D;
		TR0 = 1;			/*Zaehler starten*/
		while(!TF0);			/*Warten bis Zaehler fertig*/		  
                Schlitten_i = ~Schlitten_i;	/*Motorflanken ausgeben*/
		step--;
        }

	for(j=0;j<4;j++) drueck_zeit();		/*Warteschleife*/
	if (P55==1) Schlitten_r = 0;		/*Schlitten in gleiche Richtung wie Massen verfahren*/
	step=0;

	impulse = 2*8*impulse;                  /*8schritte/60° bei Motor mit 48 Schritten,*/
						/* 2x wegen Erzeugen von Auf-und Abflanke*/
	P54 = 0;
	while(impulse > 0)
	{
		zaehler = 1;			/*Zaehlervariable fuer Timer mit 1 laden*/
		TMOD = 0x0;		  	/*Modus 0, 8 bit Zaehler*/
		TL0 = 0;			/*Zaehler auf 0 setzen*/
        	TH0 = 0x7D;
		TR0 = 1;			/*Zaehler starten*/
		while(!TF0);			/*Warten bis Zaehler fertig*/
                P54 = ~P54;			/*Motorflanken ausgeben*/
		if(impulse%2==0) 		/*Bei jedem zweiten Schritt von Masse Spindel weiterdrehen*/
		{ Schlitten_i = ~Schlitten_i;
   		  step++;
		}
		impulse--;			/*Impulse um 1 verringern*/
	}

	if(Schlitten_r==1) step = schlitt - step;	/*Aktuelle Position des Schlittens bestimmen*/
	else step = schlitt + step;

	Schlitten_r = 0;			/*Rueckfahren des Greifers*/
        Schlitten_i = 0;
	step = 4300-step;
        while(step>0)                              
        {	zaehler = 1;			/*Zaehlervariable fuer Timer mit 1 laden*/
		TMOD = 0x0;		  	/*Modus 0, 8 bit Zaehler*/
		TL0 = 0;			/*Zaehler auf 0 setzen*/
        	TH0 = 0x7D;
		TR0 = 1;			/*Zaehler starten*/
		while(!TF0);			/*Warten bis Zaehler fertig*/		  
                Schlitten_i = ~Schlitten_i;	/*Motorflanken ausgeben*/
		step--;
        }
	eingabefenster();
}


/****************** Gruppenvorstellung über Display **************************/

void werbefernsehen()
{
  strcpy (str, "Konstruktion 4");
  write (102);
  for (i=0; i<10; i++) drueck_zeit();  
  strcpy (str, "Gruppe 1");
  write (205);

          for (i=0; i<30; i++) drueck_zeit();  
  clear_display();
  strcpy (str, "AUSWUCHTMASCHINE");
  write (101);
  strcpy (str, "(** WS 98/99 **)");
  write (201);   
          for (i=0; i<30; i++) drueck_zeit();  
  strcpy (str, "ANNE MAGIN");
  clear_display();
  write (101);   
  strcpy (str, "THORSTEN BREUER");
  write (201);   
          for (i=0; i<30; i++) drueck_zeit();  
  strcpy (str, "JOERG KNEBEL");
  clear_display();
  write (101);   
  strcpy (str, "DOMINIC FIESS");  
  write (201);   
          for (i=0; i<30; i++) drueck_zeit();  
  strcpy (str, "BETREUUNG:");
  clear_display();
  write (101);   
  strcpy (str, "Prof. Kessler");  
  write (201);
       for (i=0; i<30; i++) drueck_zeit();  
  clear_display();
  strcpy (str, "LEITUNG:");    
  write (101);   
  strcpy (str, "Prof. Weber");    
  write (201);   
       for (i=0; i<30; i++) drueck_zeit();  
  clear_display();
  strcpy (str, "Taste: E");    
  write (105);   
  strcpy (str, "fuer Start");    
  write (204);   
    
  while (key!='E') key=taste_einlesen();
  clear_display();
 
  strcpy (str, "Programmstart...");  
  write (201);   
          for (i=0; i<15; i++) drueck_zeit();  
}

 


 

Display-Unterprogramm

/*****************************************************************************************
**                                                                     			**
**     Datei: DISP.C                                                   			**
**     Das Programm beinhaltet: Routinen zur Kommunikation zwischen    			**
**				Controller, Tastatur und Display       			**
**				über I2C-Bus     		       			**
**				(Quasi eine Bibliothek für Auswucht.C) 			**
**                                                                     			**
**      Eingangsparameter:      KEINE!  (void)                         			**
**                                                                     			**
**      Ausgangsparameter:      KEINE!  (void)                         			**
**                                                                     			**
**      Rueckgabewert:          KEINER! (void)                         			**
**                                                                     			**
******************************************************************************************
**                                                                     			**
**      Autor: Thorsten Breuer                                         			**
**	  Quellen: 									**
**      Datum: 09.01.1999                              WS 98/99    			**
**                                                                     			**
*****************************************************************************************/


/**************************** Steueranweisungen fuer den Compiler ***********************/

#pragma OBJECTEXTEND
#pragma CODE DEBUG
#pragma SYMBOLS


/********************************** Text im Quelltext einbinden *************************/

#include <euro_535.h>
#include <stdio.h>
#include <string.h>


/*********************************** Konstanten *****************************************/

#define A0_LOW ((unsigned char *)0x28020L)
#define A0_HIGH ((unsigned char *)0x28021L)

#define CLS 		0x01
#define HOME 		0x02
#define ENTRY 		0x04
#define INCREMENT 	0x02
#define DECREMENT 	0x00

#define CONTROL		0x08
#define DISPLAY_ON	0x04
#define DISPLAY_OFF	0x00
#define CURSOR_ON	0x02
#define CURSOR_OFF	0x00
#define BLINK		0x01
#define NO_BLINK	0x00

#define SHIFT		0x10
#define SHI_LEFT	0x00
#define SHI_RIGHT	0x04
#define DIS_LEFT	0x08
#define DIS_RIGHT	0x0C

#define FUNCTION_SET	0x20

#define _8BIT		0x10
#define _4BIT		0x00
#define _2LINE		0x08
#define _1LINE		0x00
#define _10DOTS		0x04
#define _7DOTS		0x00

/***************************** globale Variablen ****************************************/

unsigned char key;				/* speichert, welche Taste gedrückt ist */
unsigned char i; 			  	/* allgemeine Zaehlvariable */
unsigned char antwort[25];
unsigned char str[16];
unsigned char ziffer[10];


/*********************************** Prototypen *****************************************/

void display_init(void);
void instruction(char wert);
void instruct(char wert);
void clear_display(void);
void write(unsigned int zeile);			/* Displayausgabe */
void ausgabe_display(unsigned char byte);	/* Kommunikation mit dem Display */
void transmit_i2c(unsigned char byte);
void wait(unsigned int);			/* Warteschleife für kurze Pausen */
void initial_i2c(void);	
unsigned char read_tast(void);			/* Byte von Tastatur lesen */
void write_tast(unsigned char);			/* Byte an Tastatur anlegen */
unsigned char taste_einlesen(void); 		/* Tastendruck ermitteln */
void zahlausgabe(unsigned int);			/* Verfahrweg in mm ausgeben */



/************************** Warteschleife für kurze Wartezeiten *************************/

void wait(unsigned int zeit)
{
while (zeit>0)
	zeit--;
}


/**************************** I2C-Bus initialisieren ************************************/

void initial_i2c(void)
{
*A0_HIGH = 0x80;
wait(50);

*A0_LOW = 0x55;
wait(50);

*A0_HIGH = 0xA0;
wait(50);

*A0_LOW = 0x1C;
wait(50);
}



/*************************** Display initialisieren ************************************/

void display_init(void)
{
wait(1500);
instruct(3);
wait(500);
instruct(3);
wait(100);
instruct(3);
wait(50);
instruct(2);
wait(50);

instruction(FUNCTION_SET | _2LINE);
wait(50);
instruction(CONTROL | DISPLAY_OFF);
wait(50);
instruction(CLS);
wait(150);
instruction(CONTROL | DISPLAY_ON | CURSOR_OFF | NO_BLINK);
wait(50);
}


/**************************** 8-BIT Wert übergeben *************************************/

void instruction(char wert)
{
antwort[0] = (wert & 0x0F) << 4;
antwort[1] = wert & 0xF0;
transmit_i2c(antwort[1]);
transmit_i2c(antwort[1]+4);
transmit_i2c(antwort[1]);
transmit_i2c(antwort[0]);
transmit_i2c(antwort[0]+4);
transmit_i2c(antwort[0]);
}


/**************************** 4-BIT Wert übergeben *************************************/

void instruct(char wert)
{
wert *=16;
transmit_i2c(wert);
transmit_i2c(wert+4);
transmit_i2c(wert);
}


/********************* Löscht Diplay und setzt Cursor auf Home *************************/

void clear_display(void)
{
instruction(CLS);
wait(50);
instruction(HOME);
wait(50);
}


/******************** Ausgabe von ASCII-Zeichen auf LC-Display *************************/

void write(unsigned int zeile)
{
if (zeile<200)
	{
	zeile -= 101;
	instruction(0x80+zeile);
	}

if (zeile>199)
	{
	zeile -=201;
	instruction(0xC0+zeile);
	}

for (i=0; i<strlen(str);i++)
	{
	antwort[2] = str[i];
	antwort[0] = (antwort[2] & 0x0F) << 4;
	antwort[1] = antwort[2] & 0xF0;
	ausgabe_display(antwort[1]);
	ausgabe_display(antwort[0]);
	}
}


/*********************** Schreiben in DD-RAM des LC-Displays ****************************/

void ausgabe_display(unsigned char byte)
{
transmit_i2c(byte+1);
transmit_i2c(byte+5);
transmit_i2c(byte+1);
}


/************************* Byte über I2C-Bus übertragen *********************************/

void transmit_i2c(unsigned char byte)
{
*A0_HIGH = 0xC0;
wait(50);
*A0_LOW = 0x40;
wait(50);
*A0_HIGH = 0xC5;
wait(50);
*A0_HIGH = 0xC1;
wait(50);
*A0_LOW = byte;
wait(50);
*A0_HIGH = 0xC2;
}


/****************************** Tastaturabfrage *****************************************/

unsigned char taste_einlesen(void)
{
 unsigned char test = 0;
 unsigned char taste = 0;
 unsigned char taste_wert='q'; 				/* dummywert */
 
 write_tast(0xFE); wait(25);				/* 1. Spalte einlesen */
 test = read_tast();
   if ( test == 0xEE ) {taste = 1; taste_wert = '1';}
   if ( test == 0xDE ) {taste = 2; taste_wert = '4';}
   if ( test == 0xBE ) {taste = 3; taste_wert = '7';}
   if ( test == 0x7E ) {taste = 4; taste_wert = 'A';}
 
 write_tast(0xFD); wait(25);				/* 2. Spalte einlesen */
 test = read_tast(); 
   if ( test == 0xED ) {taste = 5; taste_wert = '2';}
   if ( test == 0xDD ) {taste = 6; taste_wert = '5';}
   if ( test == 0xBD ) {taste = 7; taste_wert = '8';}
   if ( test == 0x7D ) {taste = 8; taste_wert = '0';}
 
 write_tast(0xFB); wait(25);				/* 3. Spalte einlesen */
 test = read_tast(); 
   if ( test == 0xEB ) {taste = 9;  taste_wert = '3';}
   if ( test == 0xDB ) {taste = 10; taste_wert = '6';}
   if ( test == 0xBB ) {taste = 11; taste_wert = '9';}
   if ( test == 0x7B ) {taste = 12; taste_wert = 'B';}
 
 write_tast(0xF7); wait(25);				/* 4. Spalte einlesen */
 test = read_tast(); 
   if ( test == 0xE7 ) {taste = 13; taste_wert = 'F';}
   if ( test == 0xD7 ) {taste = 14; taste_wert = 'E';}
   if ( test == 0xB7 ) {taste = 15; taste_wert = 'D';}
   if ( test == 0x77 ) {taste= 16; taste_wert = 'C';}
  
   return taste_wert; 
  }


/*************************** Byte an die Tastatur anlegen *******************************/

void write_tast(unsigned char byte)
{
 *A0_HIGH = 0xC0;			/* C0H in S1 =>ES0 = 1;  */
   wait(50);				/* I2C-Bus Kommunikation freigeben */

 *A0_LOW = 0x42;			/* laden der slave addresse  */
   wait(50);

 *A0_HIGH = 0xC5;			/* C5H in S1 =>START; slave addresse und */
   wait(50);				/* clock pulse für slave acknowledgement */
					/* wird rausgeschickt. */
 *A0_HIGH = 0xC1;			/* C1H in S1 => Freigabe der I2C-Bus Kommun. */
   wait(50);				/* SDC und SCL sind HIGH */
					/* Naechste Lese- oder Schreiboperation ist */
					/* zu/von data transfer register S0 wenn A=LOW */
  *A0_LOW = byte;			/* Byte übertragen */
   wait(50);


 *A0_HIGH  = 0xC2;			/* C2H in S1 =>STOP */
}

/***************************** Byte von der Tastatur lesen *****************************/

unsigned char read_tast(void)
{
 unsigned char wert = 0; 
 *A0_HIGH = 0xC0;			/* C0H in S1 =>ES0 = 1; */
   wait(25);				/* I2C-Bus Kommunikation freigeben */

 *A0_LOW = 0x43;			/* laden der slave addresse */
   wait(25);

 *A0_HIGH = 0xC5;			/* C5H in S1 =>START; slave addresse und */
   wait(25);				/* clock pulse für slave acknowledgement */ 
/* wird rausgeschickt. */
 *A0_HIGH = 0xC1;			/* C1H in S1 -> Freigabe der I2C-Bus Kommun.*/
   wait(25);				/* SDC und SCL sind HIGH */			

					/* Naechste Lese- oder Schreiboperation ist */
					/* zu/von data transfer register S0 wenn A=LOW */
  wert = *A0_LOW;			/* Byte lesen */
  wait(25);

 *A0_HIGH  = 0xC2;			/* C2H in S1 =>STOP */
 return wert;
}


/********** Aus den Schritten des Steppers Verfahrweg errechnen und ausgeben ***********/

void zahlausgabe(unsigned int schritt)
{
unsigned int mm = schritt*100/12;	/* Umrechnung von Stepperschritten */
					/* in mm Verfahrweg */
str[0]=ziffer[ mm/1000];		/* Zerlegung der Zahl in ihre */ 
str[1]=ziffer[(mm%1000) /100];		/* einzelnen Stellen und */
str[2]='.';				/* Umwandlung jeder Stelle in ein char-Zeichen */
str[3]=ziffer[(mm%100) / 10]; 
str[4]=ziffer[(mm%10)];
str[5]='\0';
write(206);
}