



/**********************************************************************************************
 *                                                                                            *
 * Ex1.      :   Using Command Read ASCII Distance (RA and Ra)                                *
 *               By Use Interupt Recive ASCII Distance                                        *
 *                                                                                            *
 *                                                                                            *
 **********************************************************************************************
 *                                                                                            *
 * Target MCU     : AT89C51RE2 (CP-JR51RE2 V1.0)                                              *
 * Editor         :  uvision3 3.62c                                                           *       
 * Compiler       : Keil C51 (V9.51)                                                          *
 * Create By      : Mr. Sittiphol Yooyod (WWW.ETT.CO.TH)                                      *
 * Last Update    : 15/October/2014                                                           *
 *															                                  *
 * Port Interface :      															    	  *
 *                                                                                            *
 *                : # MCU-89C51RE2 #                 # Module ET-REMOTE Distance #            *
 *                  --------------                  --------------------                      *
 * UART0(RS232#1) :    P3.0(RX0)        Connect             Tx(RS232 PORT)                    *
 *                     P3.1(TX0)        Connect             Rx(RS232 PORT)                    *
 *                     GND              Connect             GND                               *
																							  *
 *                                                         Set JP-TTL/RS232 to RS232          *
 *       Baud Rate = 57600 at Clock 18.432 Mhz             Set JP-BR (57600)                  *
 *                                                         Disable Filter                     *
 *                                                                                            *
 *       LCD     :   Connect 4bit data ;LCD 16x2 by                                           *
 *                                                                                            *  
 *                P2.1		           connect             E                                  *
 *                P2.2                 connect             RW				   	   	          *
 *                P2.3			       connect	           RS							      *
 *                P2.4-P2.7            connect	           data 4 bit high                    *
 *                                                                                            *
 *       5V                                                                                   *
 *      --+--                                                                                 *
 *        |                                                                                   *
 *        +-----------------+                                                                 *
 *        |                 |                                                                 *
 *       ---                |                                                                 *
 *       |\|                |                                                                 *
 *    VR |/|<---------------|--+                                                              *
 *   10K ---                |  | P2.3 P2.2 P2.1         P2.4 P2.5 P2.6 P2.7                   *
 *        |                 |  |   ^   ^   ^              ^   ^   ^   ^                       *
 *        |                 |  |   |   |   |              |   |   |   |                       *
 *        +--------------+--|--|---|---|---|--+--+--+--+  |   |   |   |                       *
 *      __|__            |  |  |   |   |   |  |  |  |  |  |   |   |   |                       *
 *       ---             |  |  |   |   |   |  |  |  |  |  |   |   |   |                       *
 *        -             1| 2| 3|  4|  5| 6 | 7| 8| 9|10|11|12 | 13| 14|                       *
 *                     __|__|__|___|___|___|__|__|__|__|__|___|___|___|_                      *
 *                    |  G Vcc Vo RS  R/W  E  D0 D1 D2 D3 D4  D5  D6 D7 |                     *
 *                    |    _________________________________________    |                     *
 *                    |   |                                         |   |                     *
 *                    |   |               Module                    |   |                     *
 *                    |   |         LCD 2x16 Charecter              |   |                     *  
 *                    |   |_________________________________________|   |                     *
 *                    |                                                 |                     *
 *                    |_________________________________________________|                     *
 *                                                                                            *                                                                                              
 *                                                                                            *
 *                                                                                            * 
 *                                                                                            * 
 *   Operation    : Read Distance (RA-Cmm) Value Integer Display to LCD on Line 1 and         *
 *                  Read Distance (Ra-Cmm) Value Integer+Point Display to LCD on Line 2       *                                                                           
 *                                                                                            *
 **********************************************************************************************/
 

 						
#include <at89c51xd2.h>
#include <stdio.h>

 sbit   Ena = P2^1                    ;  //Refferent Bit2.1 = Ena LCD
  
 unsigned int cnt =0                  ;  //valiable delay Counter timer0
 unsigned char distance[10],num=0     ;


//--------------LCD Function --------------

void EN_LCD(void)                     ;
void init_lcd(void)                   ;                // Function Initial LCD
void write_ins(unsigned char cmm)     ;                // Function write Command LCD
void write_data(unsigned char dat)    ;                // Function write data LCD
void gotolcd(unsigned char p)         ;                // Function Write position Curser

//-----------Initial Funtion -------------
void UART0_Init(void)                 ;
void Timer0_Init(void)                ;

//---------- Delay -------------
void delay_ms(unsigned int count)     ;


/********************************************
 **             Function Delay(ms)         **
 ********************************************/

//--------- delay ms ----------
void delay_ms(unsigned int count)          
 {
   	
    TR0 = 1        ;   //On Timer0
    ET0 = 1        ;   //Enable INT. Timer0
    cnt = 0        ;   //Start counter delay 	  

    while(cnt<count){;}

    TR0 = 0        ;	//off Timer0
    ET0 = 0        ;	//Disable INT. Timer0
 }


/***************************************************************
 **                                                           **
 **      Interrupt Service Timer0 (Interrupt every 1 ms)      **
 **                                                           **
 ***************************************************************/

//------- Interrupt Service Timer0 every 1 ms ------

 void TM0_Mod1() interrupt 1 
 {
 
  TF0  = 0         ; //Clear int. flag 
  TH0  = 0xF4      ; //Up date 16bit Reload Timer0
  TL0  = 0x00      ; //0xF400 = 1 ms 

  cnt = cnt+1      ; //Counter for Cursor blink

 }


/**********************************************************
 **                                                      **
 **      Interrupt Service Receive DATA UART0 (RX0)      **
 **                                                      **
 **********************************************************/
   
 void Rx_data()	interrupt 4
  {
	unsigned char  ch ;
	 

	if(RI == 1)	                       //If Flag RI =  1 is INT.form Rx
	 {
	   ch = SBUF                    ;  //Recive Data 
	   RI = 0                       ;  //Clear Flag 

	   distance[num] = ch           ;  //Keep data to Buffer Distance
                
       num++                        ;  //Increment Array Pointer      
         
       if(ch == 0x0D)                  //Check end Command
		 num=0                      ;  //Clear Pointer buffer
	 }
 }
/********************************************************
 **                                                    **
 **                        MAIN                        **   
 **                                                    **
 ********************************************************/


void main (void) 
  {
     unsigned char enter = 0x0D,k ;
    
     char mes1[] = {"DistanRA:     Cm"} ;
     char mes2[] = {"DistanRa:   . Cm"} ;

     CKCON0 = 0x01 ;            // div 6 clk mode  X2=1
     AUXR   = 0x10 ;            //Set XRAM = 1792 Byte


	 Timer0_Init()                         ;   
	 UART0_Init() 					       ;

     init_lcd()        ;        //Initial LCD 

//----------- Print Start Message to LCD -----------

     gotolcd(0x00)                         ;  //Start Position data on LCD Line1
     for(k=0;k<16;k++)
        write_data(mes1[k])                ;  //Sent data to LCD

     gotolcd(0x40)                         ;  //Start Position data on LCD Line2
     for(k=0;k<16;k++)                           
        write_data(mes2[k])                ;  //Sent data to LCD
  
     delay_ms(300)                         ;  //Wait Module ET-Remote Distance Ready when Power On
    
	


//----------------- Start Sent Command Read Distance --------------

    while(1) 
    {    
      //################---- Sent Command RA ----#################

	  //---For CMM RA Recive Data to Buffer Distance[] by Byte0 keep '#' ,Byte1-3 Keep Distance or 'Err' ,Byte4 Keep  0x0D(Enter)
	  
      TI = 1                           ;   //Set Flag TI=1 for Start sent data
      printf("*RA=%c",enter)           ;   // Sent Command Read Distance ASCII Integer      
	  while(TI == 0){;}	                   //Check Flag TI=1 Sent data Ready Exit loop 
      TI = 0                           ;   //Clear Flag TI
	    
      while((distance[0]!='#')||(distance[4]!=0x0D)){;} //Wait Recive data Check data Byte0 and Byte4
	  
      
	  if(distance[1]=='E')                    //Check data byte1 if is 'E'(error)  :Distance is not between 3-210 cm
       {
         gotolcd(0x09)                 ;      //Start Position data on LCD Line1
         for(k=1;k<4;k++)                          
            write_data(distance[k])    ;      //Sent Message "Err" to LCD  

	   }
      else    //Distance is between 3-210 cm.
	   {
          gotolcd(0x09)                ;      //Start Position data on LCD Line1
          for(k=1;k<4;k++)                          
             write_data(distance[k])   ;      //Sent Ascii Distance "xxx" to LCD
        }          


       distance[0]=0;         //Clear Buffer keep Distance Byte Start and Byte end
       distance[4]=0;

    	
	
	  //#########---- Sent Command Ra ----############

	  //---For CMM Ra Recive Data to Buffer Distance[] by Byte0 Keep '#' ,Byte1-3 Keep Distance integer or 'Err' 
	  //                                                 ,Byte4 Keep '.' or'o' ,Byte5 Keep Distance Point or 'r' 
	  //                                                  Byte6 Keep 0x0D(Enter)
	  
	  
	  TI = 1                           ;   //Set Flag TI=1 for Start sent data
      printf("*Ra=%c",enter)           ;   // Sent Command Read Distance ASCII Integer+Point      
	  while(TI == 0){;}	                   //Check Flag TI=1 Sent data Ready Exit loop 
      TI = 0                           ;   //Clear Flag TI
	   	   
      while((distance[0]!='#')||(distance[6]!=0x0D)){;} //Wait Recive data Check data Byte0 and Byte6
	      
	  if(distance[1]=='E')                    //Check data byte1 if is 'E'(error)  :Distance is not between 3-210 cm
       {
         gotolcd(0x49)                 ;      //Start Position data on LCD Line2
         for(k=1;k<6;k++)                          
            write_data(distance[k])    ;      //Sent Message "Error" to LCD  

	   }
      else    //Distance is between 3-210 cm.
	   {
          gotolcd(0x49)                ;      //Start Position data on LCD Line2
          for(k=1;k<6;k++)                          
             write_data(distance[k])   ;      //Sent Ascii Distance "xxx.x" to LCD
        }          


       distance[0]=0;         //Clear Buffer keep Distance Byte Start and Byte end
       distance[6]=0;

	} //while
		  
  }



 /**********************************************************
  **                                                      **  
  **                       Sub-Program                    ** 
  **                                                      **
  **********************************************************/

 /********************************************
  *              Initial UART0               *
  ********************************************/

 void UART0_Init(void)
  {
   	//---------initial Uart0 ------------

   BDRCON |= 0x1C  ;  // Select Internal Baud-Rate,enable,0x1E=Fast //0x1C=No fast 	 
   SCON    = 0x50  ;  // Serial Mode1:8bit Uart,enable serial ,Clear Flag Rx/Tx 	   
   ES      = 0     ;  //Disable Serial Uart  Interrupt    

   BRL     = 0xEC  ;  // Baud Rate 57600  ,9600 = 0x88
   PCON   |= 0x80  ;  // Set SMOD1=1 :Double BR  
   BDRCON |= 0x02  ;  // Set SPD  =1 :Fast BR   

   ES      = 1     ; //Enable Serial Uart  Interrupt   
   EA      = 1     ;  //Enable global Interrupt  
   
  
  }


 /********************************************
  *              Initial Timer0               *
  ********************************************/
 
 void Timer0_Init(void)
 {		
  //------- Initial Timer0 Control Cursor ---------

  TH0	= 0xF4   ;	//Start Interrupt every 1 ms
  TL0   = 0x00   ;
  	 
  TMOD |= 0x01   ; //Use Timer0 Mode1 16-bit																							    
   ET0  = 0	     ; //Disable Timer0 Interrupt 
   TR0  = 0      ; //Set TCON Reg. Off Timer0
 }						   


/**********************************************************
 **                                                      **
 **                        LCD Function                  **
 **                                                      **
 **********************************************************/ 


//---------------- initial lcd -------------------


void init_lcd(void)
{
 
  write_ins(0x33)              ;  //CMM Function Set
  write_ins(0x32)              ;  //CMM Function set
  write_ins(0x28)              ;  //CMM Function Set :DL(0)=4bit LCD ,N(1)=2 Line,F(0)= font 5x7 dot

  write_ins(0x0C)              ;  //CMM Display On/OFF :D=1,Display On
  write_ins(0x06)              ;  //CMM Entry :I/D(1)= DD RAM Address Increment,S(0) Cursor Shift
  write_ins(0x01)              ;  //CMM Clear Display
}


//------- Enable LCD -------

 void EN_LCD(void)
  {
    Ena = 1             ;  //Set bit P2.1 =En = 1
    delay_ms(1)         ;
    Ena = 0             ;  //Clear bit P2.1 =En = 0
    delay_ms(1)         ;
 }



//---------- Write Command to LCD -------------


void write_ins(unsigned char cmm)
{

  P2 = cmm & 0xF0            ;	  //Sent cmm 4 bit High, RS:P2.3=0, RW:P2.2=0 
  EN_LCD()                   ;

  P2 = (cmm << 4) & 0xF0     ;  //Sent cmm 4 bit Low, RS:P2.3=0, RW:P2.2=0
  EN_LCD()                   ;
}

//------------- Write data to lcd ----------------



 void write_data(unsigned char dat)
 {

  P2 = (dat & 0xF0)|0x08               ;	  //Sent cmm 4 bit High, RS:P2.3=1, RW:P2.2=0
  EN_LCD()                             ;

  P2 = ((dat << 4) & 0xF0) | 0x08      ;	 //Sent cmm 4 bit Low, RS:P2.3=1 , RW:P2.2=0
  EN_LCD()                             ;

 }


//------------ Move Cursor LCD ------------

void gotolcd(unsigned char p)
 {
   p |= 0x80    ;
   write_ins(p) ;
 }

