Hades logoHades applet banner
PIC16F84 and LCD chronograph

applet icon

The image above shows a thumbnail of the interactive Java applet embedded into this page. Unfortunately, your browser is not Java-aware or Java is disabled in the browser preferences. To start the applet, please enable Java and reload this page. (You might have to restart the browser.)

Circuit Description

This applet demonstrates a PIC16-based controller for a digital clock/chronograph The circuit consists of the microcontroller, a standard ASCII-mode liquid-crystal display, and two switches.

Press the input switches to control the stopwatch interactively; open the PIC user-interface to watch the program execution, setting breakpoints, etc. (I recommend to uncheck the 'update display' checkbox and to click the data and program memories to enforce repainting. This saves a lot of CPU cycles and makes the animation of the clock go smoothly).

The LC display show the current time or switch to chronograph mode. In chronograph mode, the user can start/stop or clean and restart. Click again on mode switch to show the current clock time. (Note that the simulation might run slower than real-time in the stopwatch mode, due to the very high number of repaints of the LCD.)

The C source code has been written by the student Douglas, Edson, Elisangela, Hilario and Fernando during the Computer Organization Undergraduate Course, Universidade Federal de Viçosa, Brazil.

The following C code is used for the watch. Note, a special symbol (on left LC display, like a big I inside a circle) was built by using 4 customized new characteres. You can also download an archive file (.tar.gz) with the source code and header files.

// /usr/hitech/bin/picl  -16f84 -C -Zg chronograph.c lcd.c delay.c
// /usr/hitech/bin/picl  -16f84 -Ochronograph.hex \
//                                   chronograph.obj lcd.obj delay.obj


#include	
#include	"lcd.h"
#include	"delay.h"

#define FATOR 5
// 500kh / 4 = 125 khz
// 8.0 e-6 * prescalar * (256-131) * factor
//               2         125     	5    = 0.01 seconds

static bit LCD_RS	@ ((unsigned)&PORTA*8+2);	// Register selec

// clock 
char h = 23; //Initial Hour
char m = 59; //Initial Minute
char s = 59; //Seconds
// chronograph
char m_cr = 0; // Minute
char s_cr = 0; //Seconds
char c_cr = 0; //Cents

char centesimos = 0; //clock cents

char inicia_cr=0;
char Aux=0;
char ajuste = 0;
char i = 0;
char show = 0; // Control variable print in LCD

char n = 0 ;
char oldrb4 = 0;

// Create a LOGO by using 
void CreateAndPrintCharacter(){
  
  lcd_write(0x40); 
  lcd_putch(0x00);  // 00000
  lcd_putch(0x01);  // 00001
  lcd_putch(0x02);  // 00010
  lcd_putch(0x04);  // 00100
  lcd_putch(0x08);  // 01000
  lcd_putch(0x10);  // 10000
  lcd_putch(0x10);  // 10000
  lcd_putch(0x10);  // 10000

  lcd_write(0x48); 
  lcd_putch(0x1F);  // 11111
  lcd_putch(0x00);  // 00000
  lcd_putch(0x00);  // 00000
  lcd_putch(0x00);  // 00000
  lcd_putch(0x0E);  // 01110
  lcd_putch(0x0E);  // 01110
  lcd_putch(0x00);  // 00000
  lcd_putch(0x0E);  // 01110

  lcd_write(0x50); 
  lcd_putch(0x00);  // 00000
  lcd_putch(0x10);  // 10000
  lcd_putch(0x08);  // 01000
  lcd_putch(0x04);  // 00100
  lcd_putch(0x02);  // 00010
  lcd_putch(0x01);  // 00001
  lcd_putch(0x01);  // 00001
  lcd_putch(0x01);  // 00001

  lcd_write(0x58); 
  lcd_putch(0x10);  // 10000
  lcd_putch(0x10);  // 10000
  lcd_putch(0x10);  // 10000
  lcd_putch(0x08);  // 01000
  lcd_putch(0x04);  // 00100
  lcd_putch(0x02);  // 00010
  lcd_putch(0x01);  // 00001
  lcd_putch(0x00);  // 00000

  lcd_write(0x60);  
  lcd_putch(0x0E);  // 01110
  lcd_putch(0x0E);  // 01110
  lcd_putch(0x0E);  // 01110
  lcd_putch(0x0E);  // 01110
  lcd_putch(0x0F);  // 01111
  lcd_putch(0x0F);  // 01111
  lcd_putch(0x00);  // 00000
  lcd_putch(0x1F);  // 11111

  lcd_write(0x68);  
  lcd_putch(0x01);  // 00001
  lcd_putch(0x01);  // 00001
  lcd_putch(0x01);  // 00001
  lcd_putch(0x02);  // 00010
  lcd_putch(0x04);  // 00100
  lcd_putch(0x08);  // 01000
  lcd_putch(0x10);  // 10000
  lcd_putch(0x00);  // 00000

  // imprime a logomarca
  lcd_goto(0);
  lcd_putch(0);

  lcd_goto(1);
  lcd_putch(1);

  lcd_goto(2);
  lcd_putch(2);

  lcd_goto(64);
  lcd_putch(3);

  lcd_goto(65);
  lcd_putch(4);

  lcd_goto(66);
  lcd_putch(5);

 } 


void SendNumbertoLCD(char n)
{
    char c;
    c = (char)((n/10)+48); // Dezena
    lcd_putch(c);
    c = (char)((n%10)+48); // Unidade
    lcd_putch(c);
}


main(){
 
  TRISA = 0x00; // Output bits porta, xESRx
  TRISB = 0xF0; // Input bits portb 7654xxxx, Output Bits xxxx3210

 // ******* INTERRUPÇÕES EM TMR0 *********
   T0IE = 1;  // 1 - Enable  TMR0
              // 0 - Disable TMR0

   T0IF = 0;  // Clean  TMR0 flag

   T0CS = 0;  // clock source
              //  TMR0 ( 1 -> RA4, 0 -> internal clock  )

   // prescaler
   PSA = 0;                       // ( 0 - on; 1 - off ) prescaler ->  TMR0

	
  PS2=0; // pre-scaler 1:8
  PS1=0; // clock 1MHz
  PS0=0;
TMR0=130;


  lcd_init();
  CreateAndPrintCharacter(); 
  lcd_goto(5); 
  lcd_puts("00:00:00");

  GIE = 1;  // Global Interruption Enable

  lcd_goto(69); 
  lcd_puts("http://www.dpi.ufv.br");
  
  while(1){
  	if (show) {
	// RB4 = clock/cronograph
	// RB5 = start/stop
	// RB6 = clean
		if(RB4 == 0  ){ 

			if ( (centesimos == 0) || oldrb4  ) {
			oldrb4 = 0;
			
			lcd_goto(5); 
			SendNumbertoLCD(h); 
			lcd_goto(8); 
			SendNumbertoLCD(m); 
			lcd_goto(11); 
			SendNumbertoLCD(s); 
			}

			if(RB5 == 0 && inicia_cr == 0){
				m_cr = 0; 
				s_cr = 0; 
				c_cr = 0; 
				
			}
			if (RB5 == 1){
				ajuste++;
				if (ajuste >3)
					ajuste=1;
			}
			
			while (RB5 == 1){
				
				if (RB6 == 0)
					n = 0;
					
				if (RB6 == 1 && n == 0){
					if (ajuste == 1)
						h++;
					else if (ajuste ==2)
						m++;
					else if (ajuste == 3)
						s++;
					n=1;
				}
				
				lcd_goto(5); 
				SendNumbertoLCD(h); 
				lcd_goto(8); 
				SendNumbertoLCD(m); 
				lcd_goto(11); 
				SendNumbertoLCD(s); 

			}

		}
		else if(RB4 == 1 ){ 
					
					if(RB5 == 0){

						if( Aux == 1){
						
							Aux = 0;
						}

						
					}
					else{

						Aux = 1;

					
					}

				
					lcd_goto(5);  
					SendNumbertoLCD(m_cr); 
					lcd_goto(8);  
					SendNumbertoLCD(s_cr); 
					lcd_goto(11);   
					SendNumbertoLCD(c_cr); 
				

			  if(RB6 == 1){ 
					
					m_cr = 0; 
					s_cr = 0; 
					c_cr = 0; 
				}


		}
		show = 0;
	}
  }
}

static void interrupt isr(void) {
// se interrupção em TMR0
   if ( T0IF == 1 ) {
	i++;
		TMR0=130;
    	if ( i == FATOR ) {
      		i = 0;
				centesimos++;

				if( Aux == 1)
					c_cr++;

      		show = 1;

    	}
	if(centesimos == 100){
			s++;
			centesimos = 0;
	}

		// hour
	if ( s == 60 ) {
      		m++;
      		s = 0;
    	}
    	if ( m == 60 ) {
      		h++;
      		m = 0;
    	}
    	if ( h == 24 ) {
      		h = 0;
    	}

	// cronograph
    	if ( c_cr == 100 ) {
      		s_cr++;
      		c_cr = 0;
    	}
    	if ( s_cr == 60 ) {
      		m_cr++;
      		s_cr = 0;
    	}
    	if ( m_cr == 60 ) {
      		m_cr = 0;
    	}

        T0IF = 0;  // zera flag de interrupcao em TMR0
   }
}

Print version | Run this demo in the Hades editor (via Java WebStart)
Usage | FAQ | About | License | Feedback | Tutorial (PDF) | Referenzkarte (PDF, in German)
Impressum http://tams.informatik.uni-hamburg.de/applets/hades/webdemos/95-dpi/pic16f84-chronograph/chronograph.html