An On-Screen-Display with only 5 components !
PicoOClock : Turn your oscilloscope into a digital clock
Let me introduce PicoOClock to you with this short video clip :
*******************************************************************************
* PICOCLOCK : PIC Oscilloscope CLOCK
*******************************************************************************
* This program shows how to display a digital clock on an oscilloscope
* with a PIC and only 4 resistors.
* RB1 +----
____|-----+---------> to oscilloscope Y input
* set timebase to 0.1 ms, V/div = 1 V
* select external trigger.
* source code for mikro C compiler V7.0.0.3
* feel free to use this code at your own risks
* and don't bother me if you get addicted watching this clock.
* target : PIC16 or PIC18, 16 Mhz crystal
* tested with PIC16F84A and PIC16F877A
* Author : Bruno Gavand, October 2007
* see more details on http://www.micro-examples.com/
*******************************************************************************
* 2 bits R2R DAC gives 4 output levels :
* 10 digits 7 segment encoding + blank
* slot index for digit start
* time slot encoded line flags :
* (if no line flag is set, spot is redirected to lowest line)
* bit 6 is lower vertical bar
* bit 7 is upper vertical bar
Unsigned char dIdx = 0 ; // time slot counter
Unsigned char fIdx = 0 ; // frame counter
Unsigned int scaler = 0 ; // RTC scaler
Unsigned char ss = 0, mn = 0, hh = 0 ; // RTC
* around 10 micro-second delay
If(INTCON.T0IF) // if timer 0 overflow
Scaler++ ; // increment scaler
Scaler = 0 ; // clear scaler
If(ss == 60) // last second in minute ?
If(mn == 60) // last minute in hour ?
If(hh == 24) // last hour in day ?
If(dIdx == 7) // hour : minute separator
Else if(dIdx == 14) // minute : second separator
Switch(fIdx) // depending on frame index
If(dIdx == SLOTS) // last slot ?
TRIGGER = 1 ; // triggers the scope
If(fIdx == 3) // last frame ?
FIdx = 0 ; // clear frame
TRIGGER = 0 ; // end trigger
INTCON.T0IF = 0 ; // clear timer 0 overflow
* set PORTA as digital I/O
TRISA = 0b110 ; // PORTA direction register
TRISB = 0 ; // PORTB is output
Memset(&line, 0, sizeof(line)) ;
Memset(display, 0, sizeof(display)) ;
OPTION REG = 0b11011000 ; // timer 0 prescaler is 1:1
INTCON = 0b10100000 ; // start interrupts
If(KEY) // is a button pressed ?
If(KEY MIN UP) // adjust minutes
Else if(KEY HH UP) // adjust hours
Mn %= 60 ; // prevent minute overflow
Hh %= 24 ; // prevent hours overflow
Delay ms(100) ; // debounce
* prepare time slot flags
(*p).F0 = s.F0 ; // a segment
(*p).F1 = s.F6 ; // g segment
(*p).F2 = s.F3 ; // d segment
(*p).F6 = s.F4 ; // e segment
(*p).F7 = s.F5 ; // f segment
P++ ; // next slot, center part of the digit
(*p).F0 = s.F0 ; // a segment (continuation)
(*p).F1 = s.F6 ; // g segment (continuation)
(*p).F2 = s.F3 ; // d segment (continuation)
P++ ; // next slot, right part of the digit
(*p).F6 = s.F2 ; // b segment
(*p).F7 = s.F1 ; // c segment
==Discussion and comments==