/*  Filename     PKIT7.C
    Description  PKIT-7 Volt Meter
    Hardware     PKIT-7
    Compiler     CCS PCW C Complier V3.28
    Engineer     Kriangsak B.
    Company      Sila Research Co.,Ltd. */

#include <12f675.h>
#fuses INTRC_IO,PUT,NOWDT,NOMCLR,NOBROWNOUT,NOCPD,NOPROTECT

#use delay (clock=4000000)

#define DATA PIN_A5
#define STR PIN_A4
#define CLK PIN_A2
#define JP1 PIN_A3

/********** SUB FUNCTION **********/

char const SEGTAB[16] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
                         0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
                         // standard segment code

void out595sub (char x) {
    char i;
    for (i=0;i<=7;++i) {
        if (x & 0x80) output_high (DATA); else output_low (DATA);
        x <<= 1;
        delay_us (10);
        output_high (CLK);
        delay_us (10);
        output_low (CLK);
    }
}

void out595 (char a,b,c) {             // out to 74hc595=3
    output_low (CLK);
    output_low (STR);
    delay_us (10);
    out595sub (a);
    out595sub (b);
    out595sub (c);
    delay_us (10);
    output_high (STR);
    delay_us (10);
    output_low (STR);
}

/********** MAIN **********/

void mainv1 (void) {
    char a,b,c;
    int32 x;
    set_adc_channel (0);
    delay_us (10);
    x = read_adc ();                    // x = 0-1023 (10-bit adc) , 0-5 volt
    x = (x * 500) / 1023;               // 0.0-50.0 (xx.x)
    c = x % 10; x = x / 10;             // change to 3 char
    b = x % 10; x = x / 10;
    a = x % 10;
    if (a!=0) a = SEGTAB[a];            // change to segment code
    b = SEGTAB[b] | 0x80;               // with dot
    c = SEGTAB[c];
    out595 (a,b,c);                     // out to hc595
}

void mainv2 (void) {
    char a,b,c;
    int32 x;
    set_adc_channel (1);
    delay_us (10);
    x = read_adc ();                    // x = 0-1023 (10-bit adc) , 0-5 volt
    x = (x * 999) / 1023;               // 0.00-9.99 (x.xx)
    c = x % 10; x = x / 10;             // change to 3 char
    b = x % 10; x = x / 10;
    a = x % 10;
    a = SEGTAB[a] | 0x80;               // change to segment code
    b = SEGTAB[b];
    c = SEGTAB[c];
    out595 (a,b,c);                     // out to hc595
}

void main (void) {
    delay_ms (250);
    output_high (JP1);
    setup_adc_ports (AN0_ANALOG);       // analog-0
    setup_adc_ports (AN1_ANALOG);       // analog-1
    setup_adc_ports (VSS_VDD);
    setup_adc (ADC_CLOCK_INTERNAL);
    delay_ms (250);
    while (1) {
        if (input (JP1)==1) mainv1 ();
        else mainv2 ();
        delay_ms (500);
    }
}


