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 #includeRun the applet | Run the editor (via Webstart)#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 } }