Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Please check this microchip XC8 C code?

Status
Not open for further replies.
T

treez

Guest
Newbie level 1
Please check this microchip XC8 C code?...

Code:
// * File:   3 CHANNEL  LED CONTROL SOFTWARE

//Clear is not implemented, the reasons for it is unknown.

//;WE ARE TRUNCATING THE ADC REGISTER SO JUST USE UPPER 8 BITS
//This code assumes LED MCPCB thermistors with B=3970 and 10K @ 25degC
//Makes sure the current level is never changed more than about 4 times
//per second.
//Does not go below 0.6A in current

//if a led driver is enabled, and turned on (external mode), but there is no
//current flowing approx 2 seconds after being turned on, then you go into
//fault mode, and can only get out of it by...........
//1..Turning equipment off then on
//2..pressing reset and then releasing reset
//3..setting both dipswitchs 2 and 3 to off

//;DEFINE INPUTS FROM DIPSWITCH
//;Note that the new board has pullups on the dipswitch,
//;whereas 550587 PCB had pull downs, thus logic is reversed.
//; XXX DIPSWITCH POLARITY:- XXX
//;DIP 1...ON = EXTERNAL CONNECTOR CONTROL
//;DIP 2...ON = LOGIC HIGH (note 'ON' gives a low input)
//;DIP 3...ON = LOGIC HIGH
//;DIP 4...OFF = 10V is for max current
//;DIP 5...OFF = 80degC, ON = 90degC
//;DIP 6... UNUSED
//;DIP 7... UNUSED
//;DIP 8...ON = NO FAN FITTED, OFF = FAN FITTED
//
//; XXX  EXTERNAL CONTROL CONNECTOR POLARITY:- XXX
//;CLEAR = ACTIVE HIGH (ie high clears it)
//;RESET = ACTIVE HIGH (ie high resets it)
//;CH1...HIGH = ON, LOW = OFF
//;CH2...HIGH = ON, LOW = OFF
//;CH3...HIGH = ON, LOW = OFF
//
//;List of input ports:
//; ************** DIPSWITCH INPUTS:
//;DIP1 = RB0
//;DIP2 = RB1
//;DIP3 = RB2
//;DIP4 = RB3
//;DIP5 = RB4
//;DIP6 = RB5
//;DIP7 = RC5
//;DIP8 = RE6
//
//;************* External connector INPUTS:
//;clear =       RC1    clears when high
//;ch3 on/off =  RC7    channel on when high
//;RESET =       RD5    reset when high
//;CH1 on/off =  RD6    channel on when high
//;ch2 on/off =  RD7    channel on when high
//
//;Other inputs (DIGITAL I/O
//;Fan tacho = RG2
//;mclr =      RG5
//
//;Inputs that are ADC inputs:
//;RA2 = AN2
//;RA3 = AN3
//;RA5 = AN4 ADCON0=0x10
//;RF1 = AN6 ADCON0=0x18
//;RF2 = AN7 ADCON0=0x1C
//;RF3 = AN8 ADCON0=0x20
//;RF4 = AN9 ADCON0=0x24
//;RF5 = AN10 ADCON0=0x28
//;RF6 = AN11 ADCON0=0x2C
//;RF7 = AN5  ADCON0=0x14
//
//;**********ADC INPUTS:
//;AN0 = NC
//;AN1 = NC
//;AN2 = VREF- (0V)
//;AN3 = VREF+ (3V)
//;AN4 = Therm ch1
//;AN5 = I_CH1
//;AN6 = 0-10V control input
//;AN7 = PCB thermistor
//;AN8 = I_ch2
//;AN9 = I_ch3
//;AN10 = Therm-ch2
//;AN11 = Therm-ch3
//
//;OOOOOOOOOOO LIST OF OUTPUTS:
//;Trip =          RA4
//;Indicator LED = RC2
//;MCP4013_CS =    RC3
//;MCP4013_UD =    RC4
//;Shutdown-Ch2 =  RE0
//;Shutdown-Ch1 =  RE1
//;Fancon PWM =    RE4
//;Shutdown-Ch3 =  RG0
//
//;NCNCNCNCNCNCNCNCNC LIST OF NON CONNECTED PINS:
//;RA0
//;RA1
//;RA6
//;RA7
//;    RB6  = PGC
//;    RB7  = PGD
//;RC0
//;RC6
//;    RD0
//;    RD1
//;    RD2
//;    RD3
//;    RD4
//;RE2
//;RE3
//;RE5
//;RE7
//;    RG1
//;    RG3
//;    RG4/*

#include <xc.h>

// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Disabled - Controlled by SRETEN bit)
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Disabled)

// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)

// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = NOSLP    // Brown Out Detect (Enabled while active, disabled in SLEEP, SBOREN disabled)
#pragma config BORV = 0         // Brown-out Reset Voltage bits (3.0V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)

// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)

// CONFIG3L
#pragma config RTCOSC = INTOSCREF// RTCC Clock Select (RTCC uses INTRC)

// CONFIG3H
#pragma config CCP2MX = PORTC   // CCP2 Mux (RC1)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = OFF      // Master Clear Enable (MCLR Disabled, RG5 Enabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)

// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)

// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)

// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-017FF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 01800-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)

// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)

// CONFIG7L
#pragma config EBRT0 = OFF      // Table Read Protect 00800-017FF (Disabled)
#pragma config EBRT1 = OFF      // Table Read Protect 01800-03FFF (Disabled)
#pragma config EBRT2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBRT3 = OFF      // Table Read Protect 06000-07FFF (Disabled)

// CONFIG7H
#pragma config EBRTB = OFF      // Table Read Protect Boot (Disabled)

#include <stdint.h>

#define  _XTAL_FREQ 4000000

void    set_ana_dig_ports(void);
void    disable_interrupts(void);
void    disable_pullups(void);
void    disable_opendrain(void);
void    disable_comparators(void);
void    setup_adc(void);
void    setup_ports(void);
void    NC_pins_low(void);  //make all NC pins low.
void    read_dips(void);
void    read_extreg5(void); //reads the five digital inputs of the ext conn.
void    pre_internal(void); //Go here before going into internal mode
void    pre_external(void);
void    set_initials_int(void); //Read dips, set comparison for change of dip
                                //set current.
void    set_initials_ext(void); //Read dips, set comparison for change of dips
                                //& change of ext conn,and change of 0-10v
                                //& set current.
void    externalmode(void); //this is where leds get driven in ext mode
void    internalmode(void); //this is where leds get driven in internal mode.
void    set_current_int(void);  //  set current for internal mode
void    set_current_ext_AH(void);  //set current in ext mode, 10V = highest curr
void    set_current_ext_AL(void);  //set current in ext mode, 0V = highest curr
void    top_mcp4013(void);
void    read_temps(void);
void    read_analog(void);
void    read_current(void);
void    fault_int(void);
void    fault_ext(void);

//CONFIGS

/*DEFINE OUTPUTS*/
#define ch1out      LATEbits.LATE1
#define ch2out      LATEbits.LATE0
#define ch3out      LATGbits.LATG0
#define ind_ledout  LATCbits.LATC2
#define fanconout   LATEbits.LATE4
#define tripout     LATAbits.LATA4
#define mcp4013_csout  LATCbits.LATC3
#define mcp4013_udout  LATCbits.LATC4
//DIPSWITCH INPUTS
#define dip1pin     PORTBbits.RB0
#define dip2pin     PORTBbits.RB1
#define dip3pin     PORTBbits.RB2
#define dip4pin     PORTBbits.RB3
#define dip5pin     PORTBbits.RB4
#define dip6pin     PORTBbits.RB5
#define dip7pin     PORTCbits.RC5
#define dip8pin     PORTEbits.RE6

//DEFINE INPUTS FROM EXT. CONNECTOR
#define resetext       PORTDbits.RD5
#define ch1ext    PORTDbits.RD6
#define ch2ext    PORTDbits.RD7
#define ch3ext    PORTCbits.RC7
#define clearext       PORTCbits.RC1

/* TURN LEDS ON AND OFF*/
#define ON1    LATEbits.LATE1 = 1  /*Turn on chan1*/
#define OFF1   LATEbits.LATE1 = 0  /*Turn off chan1*/
#define ON2    LATEbits.LATE0 = 1 /*Turn on chan2*/
#define OFF2   LATEbits.LATE0 = 0 /*Turn off chan2*/
#define ON3    LATGbits.LATG0 = 1 /*Turn on chan2*/
#define OFF3   LATGbits.LATG0 = 0  /*Turn off chan2*/
#define FANON  LATEbits.LATE2 = 1   /*Turn fan on*/
#define FANOFF LATEbits.LATE2 = 0  /*Turn fan off*/


/*DEFINE INPUTS FROM DIPSWITCH*/
/*Note that the new board has pullups on the dipswitch,*/
/*whereas 550587 PCB had pull downs, thus logic is reversed.*/
uint8_t    dipsw1;
uint8_t    dipsw2;
uint8_t    dipsw3;
uint8_t    dipsw4;
uint8_t    dipsw5;
uint8_t    dipsw8;
uint8_t    dip8;   //bit0=dip1...
uint8_t    dip8_init;   //comparison register to see if dips changed.
uint8_t    extreg5;    //bit0=reset,bit1=ch1...etc, to bit4=clear
                            //external connector pins
uint8_t    extreg5_init;
uint8_t    extp3;    //reset
uint8_t    extp4;    //ch1
uint8_t    extp5;    //ch2
uint8_t    extp6;    //ch3
uint8_t    extp9;    //an in
uint8_t    extp10;   //clear
uint8_t    extp11;   //TRIP OUT
uint8_t    temp1;
uint8_t    temp2;
uint8_t    temp3;
uint8_t    tempb;
uint8_t    ana8;           //holds ADRESH
uint8_t    ana8_init;
uint8_t    max_led_temp;
uint8_t    max_pcb_temp;
uint8_t    board_90c;      //max board temp value
uint8_t    board_80c;
uint8_t    led_90c;
uint8_t    led_80c;        //max led temp value
uint8_t    ledthermopen;   //trip value when thermistor open
uint8_t    pcbthermopen;
uint8_t    currentint;        //represents 0A, 1.76A, 2.64A, 3.52A
                                //bit0=0,bit1=1a76...etc
uint8_t    mcp4013pulses;   //number of down pulses needed to get current.
uint8_t    i;
uint8_t    extreg5; //holds state of digital inputs of external connectoe
uint8_t    extp3;   //reset pin of external connector
uint8_t    extp4;   //channel 1 en/disable
uint8_t    extp5;   //channel 2 en/disable
uint8_t    extp6;   //channel 3 en/disable
uint8_t    extp10;  //clear pin of external connector...not implemented.
uint8_t     triptempled;    //either for 80degc or 90degc
uint8_t     triptempboard;  //90degc
uint8_t     tripledthermopen;   //not implemented as could be zero degc
uint8_t    ch1temp;
uint8_t    ch2temp;
uint8_t    ch3temp;
uint8_t    boardtemp;
uint8_t    analog_in;   //0-10v signal input
uint8_t    analog_in_init;  //for comparison, to see if need to change it.
uint8_t    i_ch1;   //current in channel 1...is it running current or not?
uint8_t    i_ch2;
uint8_t    i_ch3;
uint8_t    count;   //used for delay after enabling led driver..see if current
                    //actually is flowing.
uint8_t    fault_internal;  //fault flag, fault = 1, no_fault = 0
uint8_t    fault_external;
uint8_t     extreg5_debounce;   //debounce comparison checker
uint8_t     dip8_debounce;


void main(void) {
    OSCCON = 0x56;      //4mhz internal oscillator.
    disable_interrupts();
    disable_pullups();
    disable_opendrain();
    disable_comparators();
    setup_adc();
    setup_ports();
    NC_pins_low();  //make all NC pins low.

    here:
    while(1){
    OFF1;
    OFF2;
    OFF3;
    FANOFF;

    read_dips();
    read_temps();
    if (currentint == 1) {goto  here;}
    if (boardtemp > triptempboard) {goto    here;}

    here_1:
    if (dipsw1 == 1)  pre_internal();  //OFF (actually high) = INTERNAL MODE
    if (currentint == 1) {goto  here;}
    if (dipsw1 == 1)  internalmode();    //*************************
    if (fault_internal == 1)  {fault_int();}
    if (currentint == 1) {goto  here;}
    if (boardtemp > triptempboard) {goto    here;}
    if (dipsw1 == 1) {goto    here_1;}

    if (dipsw1 == 0) pre_external();    //External mode selected
    if (currentint == 1) {goto  here;}
    if (dipsw1 == 0) externalmode();    //**************************
    if (fault_external == 1)  {fault_ext();}
    if (currentint == 1) {goto  here;}
    if (boardtemp > triptempboard) {goto    here;}
    goto    here_1;
    }
    return;
}
void    set_ana_dig_ports(void){
    ANCON0 = 0xFC;
    ANCON1 = 0x0F;
    ANCON2 = 0x00;
    return;
}
void    disable_interrupts(void) {
    INTCON =0x00;
    INTCON2 =0x80;
    INTCON3 = 0x00;
    PIE1 = 0x00;
    PIE2 = 0x00;
    PIE3 = 0x00;
    PIE4 = 0x00;
    PIE5 = 0x00;
    PIE6 = 0x00;
    return;
}
void    disable_pullups(void){
    PADCFG1 = 0;
    return;
}
void    disable_opendrain(void){
    ODCON1 = 0;
    ODCON2 = 0;
    ODCON3 = 0;
    return;
}
void    disable_comparators(void){
    CM1CON = 0;
    CM2CON = 0;
    CM3CON = 0;
    return;
}
void    setup_adc(void){
    ADCON0 = 0;
    ADCON1 = 0x10;  //VREF
    ADCON2 = 0x3E;  // Left jus/Tacq
    return;
}
void    setup_ports(void){
    TRISA =   0x2C;
    TRISB   = 0x3F;
    TRISC   = 0xA2;
    TRISD   = 0xD0;
    TRISE   = 0x40;
    TRISF   = 0xFE;
    TRISG   = 0x24;
    return;
}
void    NC_pins_low(void){
//Make all NC pins low (they are already made to outputs)
//They are outputs for noise immunity reasons.
    LATAbits.LATA0 = 0;
    LATAbits.LATA1 = 0;
    LATAbits.LATA6 = 0;
    LATAbits.LATA7 = 0;

    LATBbits.LATB6  = 0;    //PGC
    LATBbits.LATB7  = 0;    //PGD

    LATCbits.LATC0 = 0;
    LATCbits.LATC6 = 0;

    LATDbits.LATD0 = 0;
    LATDbits.LATD1 = 0;
    LATDbits.LATD2 = 0;
    LATDbits.LATD3 = 0;
    LATDbits.LATD4 = 0;

    LATEbits.LATE2 = 0;
    LATEbits.LATE3 = 0;
    LATEbits.LATE5 = 0;
    LATEbits.LATE7 = 0;

    LATGbits.LATG1 = 0;
    LATGbits.LATG3 = 0;
    LATGbits.LATG4 = 0;
    return;
}
void    read_extreg5(void){
    //Read just the five digital inputs from ext conn.
    //put them in extreg5;
    //There is debounce here....you only get the reading if two consecutive
    //readings 300ms apart, are the same.
    here_extreg:
    extreg5 = 0x00;    //first 5 bits of ext5 holds ext conn res,1,2,3,cl
    if (resetext) {extp3 = 0x01; extreg5 = extreg5 || 0x01;}
    else    {extp3 = 0x00;}
    if (ch1ext) {extp4 = 0x01; extreg5 = extreg5 || 0x02;}
    else    {extp4 = 0x00;}
    if (ch2ext) {extp5 = 0x01; extreg5 = extreg5 || 0x04;}
    else    {extp5 = 0x00;}
    if (ch3ext) {extp6 = 0x01; extreg5 = extreg5 || 0x08;}
    else    {extp6 = 0x00;}
    if (clearext) {extp10 = 0x01; extreg5 = extreg5 || 0x10;}
    else    {extp10 = 0x00;}

    extreg5_debounce = extreg5;
    __delay_ms(100);    //debounce delay
    __delay_ms(100);
    __delay_ms(100);

    extreg5 = 0x00;    //first 5 bits of ext5 holds ext conn res,1,2,3,cl
    if (resetext) {extp3 = 0x01; extreg5 = extreg5 || 0x01;}
    else    {extp3 = 0x00;}
    if (ch1ext) {extp4 = 0x01; extreg5 = extreg5 || 0x02;}
    else    {extp4 = 0x00;}
    if (ch2ext) {extp5 = 0x01; extreg5 = extreg5 || 0x04;}
    else    {extp5 = 0x00;}
    if (ch3ext) {extp6 = 0x01; extreg5 = extreg5 || 0x08;}
    else    {extp6 = 0x00;}
    if (clearext) {extp10 = 0x01; extreg5 = extreg5 || 0x10;}
    else    {extp10 = 0x00;}

    if (extreg5 != extreg5_debounce ) {goto here_extreg;}
    return;
}
void    read_dips(void){
    //dip8 register holds the state of dipswitch in corresponding bit places.
    //There is debounce here..if two consecutive dipswitch readings, 300ms
    //apart are not the same, then you keep reading the dipswitchs, until
    //they are the same.
    here_dip8:
    dip8 = 0x00;
    if (dip1pin) {dipsw1 = 0x01; dip8 = dip8 || 0x01;}
    else    {dipsw1 = 0x00;}
    if (dip2pin) {dipsw2 = 0x01; dip8 = dip8 || 0x02;}
    else    {dipsw2 = 0x00;}
    if (dip3pin) {dipsw3 = 0x01; dip8 = dip8 || 0x04;}
    else    {dipsw3 = 0x00;}
    if (dip4pin) {dipsw4 = 0x01; dip8 = dip8 || 0x08;}
    else    {dipsw4 = 0x00;}
    if (dip5pin) {dipsw5 = 0x01; dip8 = dip8 || 0x10;}
    else    {dipsw5 = 0x00;}
    if (dip8pin) {dipsw8 = 0x01; dip8 = dip8 || 0x80;}
    else    {dipsw8 = 0x00;}

    dip8_debounce = dip8;
    __delay_ms(100);    //debounce delay
    __delay_ms(100);
    __delay_ms(100);

    dip8 = 0x00;
    if (dip1pin) {dipsw1 = 0x01; dip8 = dip8 || 0x01;}
    else    {dipsw1 = 0x00;}
    if (dip2pin) {dipsw2 = 0x01; dip8 = dip8 || 0x02;}
    else    {dipsw2 = 0x00;}
    if (dip3pin) {dipsw3 = 0x01; dip8 = dip8 || 0x04;}
    else    {dipsw3 = 0x00;}
    if (dip4pin) {dipsw4 = 0x01; dip8 = dip8 || 0x08;}
    else    {dipsw4 = 0x00;}
    if (dip5pin) {dipsw5 = 0x01; dip8 = dip8 || 0x10;}
    else    {dipsw5 = 0x00;}
    if (dip8pin) {dipsw8 = 0x01; dip8 = dip8 || 0x80;}
    else    {dipsw8 = 0x00;}

    if(dip8 != dip8_debounce) {goto here_dip8;}

    if ((dipsw2 == 0) && (dipsw3 ==0)) {currentint = 4;}   //3.52A
    if ((dipsw2 == 1) && (dipsw3 ==0))  {currentint = 3;}   //2.64A
    if ((dipsw2 == 0) && (dipsw3 ==1))   {currentint = 2;}   //1.76A
    if ((dipsw2 == 1) && (dipsw3 ==1))   {currentint = 1;}   //SHUTDOWN (0A)

    if (dipsw5 == 0)  {triptempled = 200;} //90degc (Thermistor)
    if (dipsw5 == 1)  {triptempled = 200;} //decimal 168 for 80degc (Thermistor)
    triptempboard = 184; //90degC = board trip temperature. MCP9701A
    tripledthermopen = 10;  //For when LED thermistor goes open...not used as
                            //similar to zero degC.
    return;
}
void    read_analog(void){
//Read the 0-10V signal
    ADCON0 = 0x18;  //Select  ADC module FOR AN6 (0-10v)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    analog_in = ana8;
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.
    return;
}
void    read_temps(void){
    ADCON0 = 0x10;  //Select  ADC module FOR AN4 (therm ch1)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    ch1temp = ana8;
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.

    ADCON0 = 0x28;  //Select  ADC module FOR AN10 (therm ch2)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    ch2temp = ana8;
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.

    ADCON0 = 0x2C;  //Select  ADC module FOR AN11 (therm ch3)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    ch3temp = ana8;
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.

    ADCON0 = 0x1C;  //Select  ADC module FOR AN7 (Board thermistor,MCP9701A)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    ch3temp = ana8;
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.
    return;
}
void    read_current(void){
    //This reads the current from the LTC6101's via ADC, to see if the
    //current has gone to zero....ie below 130mA.
    ADCON0 = 0x14;  //Select  ADC module FOR AN5 (I ch1)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    if (ana8 < 7) {i_ch1 = 0;} //No current in chan 1..ie its less than 130mA
    else {i_ch1 = 1;}          //Current is in chan 1, so i_ch1 = 1
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.

    ADCON0 = 0x20;  //Select  ADC module FOR AN8 (I ch2)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    if (ana8 < 7) {i_ch2 = 0;} //No current in chan 2..ie its less than 130mA
    else {i_ch2 = 1;}
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.

    ADCON0 = 0x24;  //Select  ADC module FOR AN9 (I ch3)
    ADCON0bits.ADON = 1;    //Turn on ADC module
    ADCON0bits.GODONE = 1;  //START ADC CONVERSION
    while(GODONE) {;}   //Wait till conversion complete.
    ana8 = ADRESH;
    if (ana8 < 7) {i_ch3 = 0;} //No current in chan 3..ie its less than 130mA
    else {i_ch3 = 1;}
    ADCON0bits.ADON = 0;  //turn off ADC MODULE.
    return;
}
void    set_initials_int(void){
    read_dips();
    dip8_init = dip8;                   //for comparison later
    return;
}
void    set_initials_ext(void){
    read_dips();
    dip8_init = dip8;                   //for comparison later
    read_extreg5();
    extreg5_init = extreg5;
    read_analog();       //read the 0-10v signal.
    analog_in_init = analog_in;   //0-10V signal for comparison
    return;
}
void    pre_internal(void){
    set_initials_int();
    set_current_int();
    return;
    }
void    pre_external(void){
    set_initials_ext();
    if (dipsw4 == 1) {set_current_ext_AH();}
    if (dipsw4 == 0) {set_current_ext_AL();}
    return;
    ;}
// **********************************************************
void    internalmode(void){
    //If after about 2 seconds of the led drivers being enabled, no LED
    //current is detected, and the channel is switched on, then you go into
    //a fault routine.
    FANON;
    fault_internal = 0;  //clear internal mode fault flag
    count = 0;
    while(1){

    read_dips();
    if (dip8 != dip8_init) {break;}
    read_temps();
    if (boardtemp > triptempboard){break;}
    if (ch1temp <= triptempled) {ON1;}
    if (ch2temp <= triptempled) {ON2;}
    if (ch3temp <= triptempled) {ON3;}
    
    if (ch1temp > triptempled) {OFF1;}
    if (ch2temp > triptempled) {OFF2;}
    if (ch3temp > triptempled) {OFF3;}
    count = count + 1;
    if (count > 20) {count = 0; read_current();}

    if (i_ch1 == 0) {fault_internal = 1;}
    if (i_ch2 == 0) {fault_internal = 1;}
    if (i_ch3 == 0) {fault_internal = 1;}
    if (fault_internal == 1) {break;}
    }
return;}
void    externalmode(void) {
    //If after about 2 seconds of the led drivers being enabled, no LED
    //current is detected, and the channel is switched on, then you go into
    //a fault routine.
    count = 0;
    fault_external = 0;
    FANON;
        while(1){
    read_dips();
    if (dip8 != dip8_init) {break;}
    read_extreg5();
    if (extreg5 != extreg5_init){break;}
    read_analog();
    if (analog_in != analog_in_init) {break;}
    read_temps();
    if (boardtemp > triptempboard) {break;}
    if ((extp4 == 1) && (ch1temp < triptempled )) {ON1;}
    if ((extp5 == 1) && (ch2temp < triptempled )) {ON2;}
    if ((extp6 == 1) && (ch3temp < triptempled )) {ON3;}

    if ((extp4 == 0) || (ch1temp >= triptempled)) {OFF1;}
    if ((extp5 == 0) || (ch2temp >= triptempled)) {OFF2;}
    if ((extp6 == 0) || (ch3temp >= triptempled)) {OFF3;}

    count = count + 1;
    if (count >20) {count = 0; read_current();}
    if (i_ch1 == 0 && extp4 == 1){fault_external =1; break;}
    if (i_ch2 == 0 && extp5 == 1){fault_external =1; break;}
    if (i_ch3 == 0 && extp6 == 1){fault_external =1; break;}
        }
    return;
}

void    fault_int(void){
    //You will have been sent to fault because the led current went to zero
    //when in internal mode. ie the led current in any channel went to zero
    //when it should have been running.
    //To get out of this fault routine requires either switching the equipment
    //off then on, or setting the dipswitchs 2 & 3 to OFF,OFF.
    ind_ledout = 1;
    OFF1;
    OFF2;
    OFF3;
    while(1){
    read_dips();
    if (dipsw2 && dipsw3){break;}   //these dips allow you to get out of fault
    }
    ind_ledout = 0;
    fault_internal = 0;
  return;
}

void    fault_ext(void){
    //You will have been sent to fault because the led current went to zero
    //when in external mode. ie the led current in any channel went to zero
    //when it should have been running.
    //To get out of this fault routine requires either switching the equipment
    //off then on, or setting the dipswitchs 2 & 3 to OFF,OFF....or,
    //pressing the reset button.
    ind_ledout = 1;
    OFF1;
    OFF2;
    OFF3;
    while(1){
       read_dips();
       read_extreg5();
       if ((dipsw2 == 1) && (dipsw3 == 1)) {break;} //these dips allow
                                                    //you to get out of fault
       if (extp3 == 1) {break;}   //reset pressed means get out of
                                  //this fault routine
    }

    while(1){
    read_extreg5();
    if (extp3 == 0) {break;}    //Start again but only when the reset button is
                                //released.
    }
    ind_ledout = 0;
    fault_external = 0;
    return;
}
//***************************************************************
void    set_current_int(void){
    //set mcp4013 by topping the mcp4013, then decrementing
    if (currentint == 2) mcp4013pulses = 31;    //no. of downpulses for 1.76A.
    if (currentint == 3) mcp4013pulses = 17;    //no. of downpulses for 2.54A.
    if (currentint == 4) mcp4013pulses = 4;     //no. of downpulses for 3.52A
    top_mcp4013();      //top out the mcp4013
    mcp4013_csout = 1;  //disable mcp4013
    mcp4013_csout = 1;
    mcp4013_udout = 0;  //ready to decrement
    mcp4013_udout = 0;
    mcp4013_csout = 0;  //enable mcp4013
    mcp4013_csout = 0;
    for (i== 0; i== mcp4013pulses; i++){
    mcp4013_udout = 1;  //pulse it to the level
    mcp4013_udout = 1;
    mcp4013_udout = 0;
    mcp4013_udout = 0;
    }
    mcp4013_csout = 1;
    mcp4013_csout = 1;  //disable mcp4013
    return;
}
void    top_mcp4013(void) {
        mcp4013_csout = 1;
        mcp4013_csout = 1;  //disable mcp4013
        mcp4013_udout = 1;  //ready to increment wiper
        mcp4013_udout = 1;
        mcp4013_csout = 0;  //enable mcp4013
        mcp4013_csout = 0;
        for(i==64;i==0;i--){
        mcp4013_udout = 0;
        mcp4013_udout = 0;
        mcp4013_udout = 1;
        mcp4013_udout = 1;
        }
        mcp4013_csout = 1;  //disable mcp4013
        mcp4013_csout = 1;
        return;
}

void    set_current_ext_AH(void){
    //This is to set the current in external mode when the 4th dipswitch
    //asks for the 0-10V signal to be "10V = Highest current"
    //["AH" stands for Active High"]
    //MCP4013pulses will here be the number of downpulses to pulse the digital
    //pot with. (starting from the top of the resistor 'chain')
    //Never go below 11 POT steps (ie, never below 0.176V -> 300mA)
    //Make max current correspond to 235bits to 255bits on the 0-10V input
    //(9.2V)

//CALCULATING NUMBER OF DOWNPULSES.
    if (currentint == 2) {
    //9 apart
    if  (analog_in >= 235)            {mcp4013pulses = 31;}
    if ((analog_in >= 225) && (analog_in <= 234)) {mcp4013pulses = 32;}
    if ((analog_in >= 215) && (analog_in <= 224)) {mcp4013pulses = 33;}
    if ((analog_in >= 205) && (analog_in <= 214)) {mcp4013pulses = 34;}
    if ((analog_in >= 195) && (analog_in <= 204)) {mcp4013pulses = 35;}
    if ((analog_in >= 185) && (analog_in <= 194)) {mcp4013pulses = 36;}
    if ((analog_in >= 175) && (analog_in <= 184)) {mcp4013pulses = 37;}
    if ((analog_in >= 165) && (analog_in <= 174)) {mcp4013pulses = 38;}
    if ((analog_in >= 155) && (analog_in <= 164)) {mcp4013pulses = 39;}
    if ((analog_in >= 145) && (analog_in <= 154)) {mcp4013pulses = 40;}
    if ((analog_in >= 135) && (analog_in <= 144)) {mcp4013pulses = 41;}
    if ((analog_in >= 125) && (analog_in <= 134)) {mcp4013pulses = 42;}
    if ((analog_in >= 115) && (analog_in <= 124)) {mcp4013pulses = 43;}
    if ((analog_in >= 105) && (analog_in <= 114)) {mcp4013pulses = 44;}
    if ((analog_in >= 95) && (analog_in <= 104))  {mcp4013pulses = 45;}
    if ((analog_in >= 85) && (analog_in <= 94))   {mcp4013pulses = 46;}
    if ((analog_in >= 75) && (analog_in <= 84))   {mcp4013pulses = 47;}
    if ((analog_in <= 74))                       {mcp4013pulses = 48;}

    }

    if (currentint == 3) {
     //6 apart
    if  (analog_in >= 235)            {mcp4013pulses = 17;}
    if ((analog_in >= 228) && (analog_in <= 234)) {mcp4013pulses = 18;}
    if ((analog_in >= 221) && (analog_in <= 227)) {mcp4013pulses = 19;}
    if ((analog_in >= 214) && (analog_in <= 220)) {mcp4013pulses = 20;}
    if ((analog_in >= 207) && (analog_in <= 213)) {mcp4013pulses = 21;}
    if ((analog_in >= 200) && (analog_in <= 206)) {mcp4013pulses = 22;}
    if ((analog_in >= 193) && (analog_in <= 199)) {mcp4013pulses = 23;}
    if ((analog_in >= 186) && (analog_in <= 192)) {mcp4013pulses = 24;}
    if ((analog_in >= 179) && (analog_in <= 185)) {mcp4013pulses = 25;}
    if ((analog_in >= 172) && (analog_in <= 178)) {mcp4013pulses = 26;}
    if ((analog_in >= 165) && (analog_in <= 171)) {mcp4013pulses = 27;}
    if ((analog_in >= 158) && (analog_in <= 164)) {mcp4013pulses = 28;}
    if ((analog_in >= 151) && (analog_in <= 157)) {mcp4013pulses = 29;}
    if ((analog_in >= 144) && (analog_in <= 150)) {mcp4013pulses = 30;}
    if ((analog_in >= 137) && (analog_in <= 143)) {mcp4013pulses = 31;}
    if ((analog_in >= 130) && (analog_in <= 136)) {mcp4013pulses = 32;}
    if ((analog_in >= 123) && (analog_in <= 129)) {mcp4013pulses = 33;}
    if ((analog_in >= 116) && (analog_in <= 122)) {mcp4013pulses = 34;}
    if ((analog_in >= 109) && (analog_in <= 115)) {mcp4013pulses = 35;}
    if ((analog_in >= 102) && (analog_in <= 108)) {mcp4013pulses = 36;}
    if ((analog_in >= 95) && (analog_in <= 101))  {mcp4013pulses = 37;}
    if ((analog_in >= 88) && (analog_in <= 94))   {mcp4013pulses = 38;}
    if ((analog_in >= 81) && (analog_in <= 87))   {mcp4013pulses = 39;}
    if ((analog_in >= 74) && (analog_in <= 80))   {mcp4013pulses = 40;}
    if ((analog_in >= 67) && (analog_in <=73))    {mcp4013pulses = 41;}
    if ((analog_in >= 60) && (analog_in <= 66))   {mcp4013pulses = 42;}
    if ((analog_in >= 53) && (analog_in <= 59))   {mcp4013pulses = 43;}
    if ((analog_in >= 46) && (analog_in <= 52))   {mcp4013pulses = 44;}
    if ((analog_in >= 39) && (analog_in <= 45))   {mcp4013pulses = 45;}
    if ((analog_in >= 32) && (analog_in <= 38))   {mcp4013pulses = 46;}
    if ((analog_in >= 25) && (analog_in <= 31))   {mcp4013pulses = 47;}
    if ((analog_in <= 24))                        {mcp4013pulses = 48;}

    }

    if (currentint == 4){
    //4 apart
    if  (analog_in >= 235)                   {mcp4013pulses = 4;}
    if ((analog_in >= 230) && (analog_in <= 234)) {mcp4013pulses = 5;}
    if ((analog_in >= 225) && (analog_in <= 229)) {mcp4013pulses = 6;}
    if ((analog_in >= 220) && (analog_in <= 224)) {mcp4013pulses = 7;}
    if ((analog_in >= 215) && (analog_in <= 219)) {mcp4013pulses = 8;}
    if ((analog_in >= 210) && (analog_in <= 214)) {mcp4013pulses = 9;}
    if ((analog_in >= 205) && (analog_in <= 209)) {mcp4013pulses = 10;}
    if ((analog_in >= 200) && (analog_in <= 204)) {mcp4013pulses = 11;}
    if ((analog_in >= 195) && (analog_in <= 199)) {mcp4013pulses = 12;}
    if ((analog_in >= 190) && (analog_in <= 194)) {mcp4013pulses = 13;}
    if ((analog_in >= 185) && (analog_in <= 189)) {mcp4013pulses = 14;}
    if ((analog_in >= 180) && (analog_in <= 184)) {mcp4013pulses = 15;}
    if ((analog_in >= 175) && (analog_in <= 179)) {mcp4013pulses = 16;}
    if ((analog_in >= 170) && (analog_in <= 174)) {mcp4013pulses = 17;}
    if ((analog_in >= 165) && (analog_in <= 169)) {mcp4013pulses = 18;}
    if ((analog_in >= 160) && (analog_in <= 164)) {mcp4013pulses = 19;}
    if ((analog_in >= 155) && (analog_in <= 159)) {mcp4013pulses = 20;}
    if ((analog_in >= 150) && (analog_in <= 154)) {mcp4013pulses = 21;}
    if ((analog_in >= 145) && (analog_in <= 149)) {mcp4013pulses = 22;}
    if ((analog_in >= 140) && (analog_in <= 144)) {mcp4013pulses = 23;}
    if ((analog_in >= 135) && (analog_in <= 139)) {mcp4013pulses = 24;}
    if ((analog_in >= 130) && (analog_in <= 134)) {mcp4013pulses = 25;}
    if ((analog_in >= 125) && (analog_in <= 129)) {mcp4013pulses = 26;}
    if ((analog_in >= 120) &&  (analog_in <= 124)) {mcp4013pulses = 27;}
    if ((analog_in >= 115) &&  (analog_in <= 119))  {mcp4013pulses = 28;}
    if ((analog_in >= 110) &&  (analog_in <= 114))  {mcp4013pulses = 29;}
    if ((analog_in >= 105) &&  (analog_in <= 109))  {mcp4013pulses = 30;}
    if ((analog_in >= 100) &&  (analog_in <= 104))  {mcp4013pulses = 31;}
    if ((analog_in >= 95) &&  (analog_in <= 99))  {mcp4013pulses = 32;}
    if ((analog_in >= 90) &&  (analog_in <= 94))  {mcp4013pulses = 33;}
    if ((analog_in >= 85) &&  (analog_in <= 89))  {mcp4013pulses = 34;}
    if ((analog_in >= 80) &&  (analog_in <= 84))  {mcp4013pulses = 35;}
    if ((analog_in >= 75) &&  (analog_in <= 79))  {mcp4013pulses = 36;}
    if ((analog_in >= 70) &&  (analog_in <= 74))  {mcp4013pulses = 37;}
    if ((analog_in >= 65) &&  (analog_in <= 69))  {mcp4013pulses = 38;}
    if ((analog_in >= 60) &&  (analog_in <= 64))  {mcp4013pulses = 39;}
    //3 apart
    if ((analog_in >= 56) &&  (analog_in <= 59))  {mcp4013pulses = 40;}
    if ((analog_in >= 52) &&  (analog_in <= 55))  {mcp4013pulses = 41;}
    if ((analog_in >= 48) &&   (analog_in <= 51)) {mcp4013pulses = 42;}
    if ((analog_in >= 44) &&   (analog_in <= 47)) {mcp4013pulses = 43;}
    if ((analog_in >=40) &&  (analog_in <= 43))   {mcp4013pulses = 39;}
    if ((analog_in >= 36) &&  (analog_in <= 39))  {mcp4013pulses = 40;}
    if ((analog_in >= 32) &&  (analog_in <= 35))  {mcp4013pulses = 41;}
    if ((analog_in >= 28) &&   (analog_in <= 31))  {mcp4013pulses = 42;}
    if ((analog_in >= 24) &&   (analog_in <= 27))   {mcp4013pulses = 43;}
    if ((analog_in >= 20) &&  (analog_in <= 23))  {mcp4013pulses =44;}
    if ((analog_in >= 16) &&  (analog_in <= 19))  {mcp4013pulses = 45;}
    if ((analog_in >= 12) &&  (analog_in <= 15))  {mcp4013pulses = 46;}
    if ((analog_in >= 8) &&   (analog_in <= 11))   {mcp4013pulses = 47;}
    if (analog_in <= 7)    {mcp4013pulses =48;}
    }

    top_mcp4013();      //top out the mcp4013
    mcp4013_csout = 1;  //disable mcp4013
    mcp4013_csout = 1;
    mcp4013_udout = 0;  //ready to decrement
    mcp4013_udout = 0;
    mcp4013_csout = 0;  //enable mcp4013
    mcp4013_csout = 0;
    for (i== 0; i== mcp4013pulses; i++){
    mcp4013_udout = 1;  //pulse it to the level
    mcp4013_udout = 1;
    mcp4013_udout = 0;
    mcp4013_udout = 0;
    }
    mcp4013_csout = 1;
    mcp4013_csout = 1;  //disable mcp4013

    return;
}

void    set_current_ext_AL(void){
    //This is to set the current in external mode when the 4th dipswitch
    //asks for the 0-10V signal to be "0V = Highest current"
    //["AL" stands for Active Low"]
    //MCP4013pulses will here be the number of downpulses to pulse the digital
    //pot with. (starting from the top of the resistor 'chain')
    //Never go below 11 POT steps (ie, never below 0.176V -> 300mA)
    //Make max current correspond to 0 bits to 9 bits on the 0-10V input
    //(ie anything below 0.3V will be max)
    if (currentint == 2) {
    //12 apart
    if  (analog_in <= 9)             {mcp4013pulses = 31;}
    if ((analog_in >= 10  ) && (analog_in <= 22))  {mcp4013pulses = 32;}
    if ((analog_in >= 23  ) && (analog_in <= 35))  {mcp4013pulses = 33;}
    if ((analog_in >= 36  ) && (analog_in <= 48))  {mcp4013pulses = 34;}
    if ((analog_in >= 49  ) && (analog_in <= 61))  {mcp4013pulses = 35;}
    if ((analog_in >= 62  ) && (analog_in <= 74))  {mcp4013pulses = 36;}
    if ((analog_in >= 75  ) && (analog_in <= 87))  {mcp4013pulses = 37;}
    if ((analog_in >= 88  ) && (analog_in <= 100))  {mcp4013pulses = 38;}
    if ((analog_in >= 101  ) && (analog_in <= 113))  {mcp4013pulses = 39;}
    if ((analog_in >= 114  ) && (analog_in <= 126))  {mcp4013pulses = 40;}
    if ((analog_in >= 127  ) && (analog_in <= 139))  {mcp4013pulses = 41;}
    if ((analog_in >= 140 ) && (analog_in <= 152))  {mcp4013pulses = 42;}
    if ((analog_in >= 153  ) && (analog_in <= 165)) {mcp4013pulses = 43;}
    if ((analog_in >= 166  ) && (analog_in <= 178)) {mcp4013pulses = 44;}
    if ((analog_in >= 179  ) && (analog_in <= 191)) {mcp4013pulses = 45;}
    if ((analog_in >= 192 )  && (analog_in <= 204)) {mcp4013pulses = 46;}
    if ((analog_in >= 205  ) && (analog_in <= 217)) {mcp4013pulses = 47;}
    if (analog_in >= 218  )                         {mcp4013pulses = 48;}

    }
    if (currentint == 3) {
    //7 apart
    if      (analog_in <= 9)     {mcp4013pulses = 17;}
    if ((analog_in >= 10  )  && (analog_in <= 17))   {mcp4013pulses = 18;}
    if ((analog_in >= 18  )  && (analog_in <= 25))   {mcp4013pulses = 19;}
    if ((analog_in >= 26  )  && (analog_in <= 33))   {mcp4013pulses = 20;}
    if ((analog_in >= 34  )  && (analog_in <= 41))   {mcp4013pulses = 21;}
    if ((analog_in >= 42  )  && (analog_in <= 49))   {mcp4013pulses = 22;}
    if ((analog_in >= 50  )  && (analog_in <= 57))   {mcp4013pulses = 23;}
    if ((analog_in >= 58  )  && (analog_in <= 65))   {mcp4013pulses = 24;}
    if ((analog_in >= 66  )  && (analog_in <= 73))   {mcp4013pulses = 25;}
    if ((analog_in >= 74  )  && (analog_in <= 81))   {mcp4013pulses = 26;}
    if ((analog_in >= 82  )  && (analog_in <= 89))   {mcp4013pulses = 27;}
    if ((analog_in >= 90  )  && (analog_in <= 97))   {mcp4013pulses = 28;}
    if ((analog_in >= 98  )  && (analog_in <= 105))  {mcp4013pulses = 29;}
    if ((analog_in >= 106 )  && (analog_in <= 113))  {mcp4013pulses = 30;}
    if ((analog_in >= 114  )  && (analog_in <= 121)) {mcp4013pulses = 31;}
    if ((analog_in >= 122  )  && (analog_in <= 129)) {mcp4013pulses = 32;}
    if ((analog_in >= 130  )  && (analog_in <= 137)) {mcp4013pulses = 33;}
    if ((analog_in >= 138  )  && (analog_in <= 145)) {mcp4013pulses = 34;}
    if ((analog_in >= 146  )  && (analog_in <= 153)) {mcp4013pulses = 35;}
    if ((analog_in >= 154 )  && (analog_in <= 161))  {mcp4013pulses = 36;}
    if ((analog_in >= 162  )  && (analog_in <= 169)) {mcp4013pulses = 37;}
    if ((analog_in >= 170  )  && (analog_in <= 177)) {mcp4013pulses = 38;}
    if ((analog_in >= 178  )  && (analog_in <= 185)) {mcp4013pulses = 39;}
    if ((analog_in >= 186 )  && (analog_in <= 193))  {mcp4013pulses = 40;}
    if ((analog_in >= 194 )  && (analog_in <= 201))  {mcp4013pulses = 41;}
    if ((analog_in >= 202  )  && (analog_in <= 209)) {mcp4013pulses = 42;}
    if ((analog_in >= 210  )  && (analog_in <= 217)) {mcp4013pulses = 43;}
    if ((analog_in >= 218  )  && (analog_in <= 225)) {mcp4013pulses = 44;}
    if ((analog_in >= 226 )  && (analog_in <= 233))  {mcp4013pulses = 45;}
    if ((analog_in >= 234 )  && (analog_in <= 241))  {mcp4013pulses = 46;}
    if ((analog_in >= 242  )  && (analog_in <= 249)) {mcp4013pulses = 47;}
    if (analog_in >= 250  ) {mcp4013pulses = 48;}
    }
    if (currentint == 4)    {
    //4 apart
    if           (analog_in <= 9)    {mcp4013pulses = 4;}
    if ((analog_in >= 10  )  && (analog_in <= 14))   {mcp4013pulses = 5;}
    if ((analog_in >= 15  )  && (analog_in <= 19))   {mcp4013pulses = 6;}
    if ((analog_in >= 20  )  && (analog_in <= 24))   {mcp4013pulses = 7;}
    if ((analog_in >= 25  )  && (analog_in <= 29))   {mcp4013pulses = 8;}
    if ((analog_in >= 30  )  && (analog_in <= 34))   {mcp4013pulses = 9;}
    if ((analog_in >= 35  )  && (analog_in <= 39))   {mcp4013pulses = 10;}
    if ((analog_in >= 40  )  && (analog_in <= 44))   {mcp4013pulses = 11;}
    if ((analog_in >= 45  )  && (analog_in <= 49))   {mcp4013pulses = 12;}
    if ((analog_in >= 50  )  && (analog_in <= 54))   {mcp4013pulses = 13;}
    if ((analog_in >= 55  )  && (analog_in <= 59))   {mcp4013pulses = 14;}
    if ((analog_in >= 60  )  && (analog_in <= 64))   {mcp4013pulses = 15;}
    if ((analog_in >= 65  )  && (analog_in <= 69))  {mcp4013pulses = 16;}
    if ((analog_in >= 70  )  && (analog_in <= 74))   {mcp4013pulses = 17;}
    if ((analog_in >= 75  )  && (analog_in <= 79))   {mcp4013pulses = 18;}
    if ((analog_in >= 80  )  && (analog_in <= 84))   {mcp4013pulses = 19;}
    if ((analog_in >= 85  )  && (analog_in <= 89))   {mcp4013pulses = 20;}
    if ((analog_in >= 90  )  && (analog_in <= 94))   {mcp4013pulses = 21;}
    if ((analog_in >= 95  )  && (analog_in <= 99))   {mcp4013pulses = 22;}
    if ((analog_in >= 100  )  && (analog_in <= 104))   {mcp4013pulses = 23;}
    if ((analog_in >= 105  )  && (analog_in <= 109))   {mcp4013pulses = 24;}
    if ((analog_in >= 110  )  && (analog_in <= 114))   {mcp4013pulses = 25;}
    if ((analog_in >= 115  )  && (analog_in <= 119))   {mcp4013pulses = 26;}
    if ((analog_in >= 120  )  && (analog_in <= 124))   {mcp4013pulses = 27;}
    if ((analog_in >= 125  )  && (analog_in <= 129))   {mcp4013pulses = 28;}
    if ((analog_in >= 130  )  && (analog_in <= 134))   {mcp4013pulses = 29;}
    if ((analog_in >= 135  )  && (analog_in <= 139))   {mcp4013pulses = 30;}
    if ((analog_in >= 140  )  && (analog_in <= 144))   {mcp4013pulses = 31;}
    if ((analog_in >= 145  )  && (analog_in <= 149))   {mcp4013pulses = 32;}
    if ((analog_in >= 150  )  && (analog_in <= 154))   {mcp4013pulses = 33;}
    if ((analog_in >= 155  )  && (analog_in <= 159))   {mcp4013pulses = 34;}
    if ((analog_in >= 160  )  && (analog_in <= 164))   {mcp4013pulses = 35;}
    if ((analog_in >= 165  )  && (analog_in <= 169))   {mcp4013pulses = 36;}
    if ((analog_in >= 170  )  && (analog_in <= 174))   {mcp4013pulses = 37;}
    if ((analog_in >= 175  )  && (analog_in <= 179))   {mcp4013pulses = 38;}
    if ((analog_in >= 180  )  && (analog_in <= 184))   {mcp4013pulses = 39;}
    if ((analog_in >= 185  )  && (analog_in <= 189))   {mcp4013pulses = 40;}
    if ((analog_in >= 190  )  && (analog_in <= 194))   {mcp4013pulses = 41;}
    if ((analog_in >= 195  )  && (analog_in <= 199))   {mcp4013pulses = 42;}
    if ((analog_in >= 200  )  && (analog_in <= 204))   {mcp4013pulses = 43;}
    if ((analog_in >= 205  )  && (analog_in <= 209))   {mcp4013pulses = 44;}
    if ((analog_in >= 210  )  && (analog_in <= 214))   {mcp4013pulses = 45;}
    if ((analog_in >= 215  )  && (analog_in <= 219))   {mcp4013pulses = 46;}
    if ((analog_in >= 220  )  && (analog_in <= 224))   {mcp4013pulses = 47;}
    if  (analog_in >= 225)                              {mcp4013pulses = 48;}

}
    top_mcp4013();      //top out the mcp4013
    mcp4013_csout = 1;  //disable mcp4013
    mcp4013_csout = 1;
    mcp4013_udout = 0;  //ready to decrement
    mcp4013_udout = 0;
    mcp4013_csout = 0;  //enable mcp4013
    mcp4013_csout = 0;
    for (i== 0; i== mcp4013pulses; i++){
    mcp4013_udout = 1;  //pulse it to the level
    mcp4013_udout = 1;
    mcp4013_udout = 0;
    mcp4013_udout = 0;
    }
    mcp4013_csout = 1;
    mcp4013_csout = 1;  //disable mcp4013
return;
}
 

it builds sucesfully, but the pcbs are not ready yet, so I cant yet run it on the hardware
 

Good practice, as well as the other issues I already mentioned, would be to put the two #includes together on adjacent lines. Any source lines in the included files is placed 'in-line' with the program at that point so for sake of neatness and to ease debugging, it is better to keep pre-written code before your own code rather than possibly intermixing it.

for example:
Code:
#include <xc.h>
#include <stdint.h>

As you have only used #pragma directives between them you might be OK but other lines, especially instructions might cause problems.
Why is 'stdint.h' needed by the way? I can't run MPLAB(X) at the moment to find out for myself.

Brian.
 

stdint used because I am using integer variables....uint8_t (8 bit unsigned integer)
 

in XC8 stdint.h uint8_t is defined as an unsigned char
Code:
typedef unsigned char uint8_t;
I tend to use unsigned char if I need an unsigned byte sized variable
 

that's frazzled my grey matter, I never could handle how CHARacters could be used in math expressions, but of course you are right, I should probably have used char.
 

that's frazzled my grey matter, I never could handle how CHARacters could be used in math expressions, but of course you are right, I should probably have used char.
characters are not used in numeric expressions - what happens is inside a computer characters are represented by 8 bit numeric values, e.g. in ASCII character code
character A is represented by 65 decimal (0x41 hexadecimal)
character 6 is represented by 54 decimal (0x36 hexadecimal)

for full details
https://www.asciitable.com/

when you define a char variable in a C statement the compiler converts it to a numeric representation
Code:
char ch = 'A';
printf("character %c is %d decimal", ch, ch);
when you print the character to the screen the display hardware converts it to a human readable from

the above program displays
Code:
character A is 65 decimal

if you are going to explicitly assign numeric values to a char type variable specify if it is unsigned char or signed char, e.g.
Code:
signed char x=-3;
unsigned char z=205;
The C standard does not specify if char is signed or unsigned
 

The C standard does not specify if char signed or unsigned.

More exactly, ANSI C (ISO/IEC 9899) says:
If the value of an object of type char is treated as a signed integer when used in an expression, the value of CHAR_MIN shall be the same as that of SCHAR_MIN and the value of CHAR_MAX shall be the same as that of SCHAR_MAX. Otherwise, the value of CHAR_MIN shall be 0 and the value of CHAR_MAX shall be the same as that of UCHAR_MAX.

But this behaviour isn't necessarily implemented by embedded compilers. Specifying signed or unsigned char explicitely can be considered the safer way.
 

Personally, I always use the native 'unsigned char' for clarity although my compiler typdefs it as 'byte' as well.

Treez, you can save yourself a lot of typing by omitting the 'uint8_t' except for the first instance and separating variables of the same type with commas instead of semicolons. Check first if XC8 allows comments starting with // if you do that, you might have to use the /* */ method instead.

I really wish you would get rid of those 'goto' statements, especially as they cause crossed loops. They can make debugging a nightmare.

Brian.
 

I really wish you would get rid of those 'goto' statements, especially as they cause crossed loops. They can make debugging a nightmare.

Brian.
I agree, in the days of Fortan 4 high level programmers had no choice but to use goto but these days better program control structures are available

e.g. use of while(), continue and break
Code:
void main(void) {
    OSCCON = 0x56;      //4mhz internal oscillator.
    disable_interrupts();
    disable_pullups();
    disable_opendrain();
    disable_comparators();
    setup_adc();
    setup_ports();
    NC_pins_low();  //make all NC pins low.

    here:
    while(1){
    OFF1;
    OFF2;
    OFF3;
    FANOFF;

    read_dips();
    read_temps();
    if (currentint == 1) continue;
    if (boardtemp > triptempboard) continue;

    here_1:
    while(1)
        {
        if (dipsw1 == 1)  pre_internal();  //OFF (actually high) = INTERNAL MODE
        if (currentint == 1) break;
        if (dipsw1 == 1)  internalmode();    //*************************
        if (fault_internal == 1)  {fault_int();}
        if (currentint == 1) break;
        if (boardtemp > triptempboard) break;
        if (dipsw1 == 1) continue;

        if (dipsw1 == 0) pre_external();    //External mode selected
        if (currentint == 1)  break;
        if (dipsw1 == 0) externalmode();    //**************************
        if (fault_external == 1)  {fault_ext();}
        if (currentint == 1)  break;
        if (boardtemp > triptempboard)  break;
        }
    }
    return;
}
 

Fortran 4 !

I detect another 'long in the tooth' programmer - my intro pre-dates that by a long stretch, my first programming was on an Elliot 903 using banks of toggle switches and later a 'high speed' paper tape reader. :-D

Then of course the new fangled microprocesor came out - the Intel 4004 !

Brian.
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
I started with a STC Stantec Zerbra - loading programs via switches on the front and then paper tape
moved on to minicomputers DEC PDP8 & PDP11, Prime, etc and mainframes ICL1904 and CDC73
then microcomputers Motorola MC6800 and MC68000
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
We must be of the same vintage. I too followed the PDP8 then PDP11 route although mostly working on hardware than software. The Elliot computers were mostly transistor gates, ICs were few and far between. I can't remember all the details but the clock speed was in the low KHz and the standard diagnostic routine was to connect a DAC across the data bus and play a hornpipe tune through it to a loudspeaker! I built the 'Wireless World' computer back when the Z80 first came out and remember the long lead times and high prices of 1K x 1-bit RAMS, the venerable 2102 from Mostek. How times have changed. I've probably still got some in my junk box!

Brian.
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
That's a lot of code to review.

can't you make use of a "for" loop instead of those:
Code:
    if (currentint == 2) {
    //9 apart
    if  (analog_in >= 235)            {mcp4013pulses = 31;}
    if ((analog_in >= 225) && (analog_in <= 234)) {mcp4013pulses = 32;}
    if ((analog_in >= 215) && (analog_in <= 224)) {mcp4013pulses = 33;}
    if ((analog_in >= 205) && (analog_in <= 214)) {mcp4013pulses = 34;}
    if ((analog_in >= 195) && (analog_in <= 204)) {mcp4013pulses = 35;}
    if ((analog_in >= 185) && (analog_in <= 194)) {mcp4013pulses = 36;}
    if ((analog_in >= 175) && (analog_in <= 184)) {mcp4013pulses = 37;}
    if ((analog_in >= 165) && (analog_in <= 174)) {mcp4013pulses = 38;}
    if ((analog_in >= 155) && (analog_in <= 164)) {mcp4013pulses = 39;}
    if ((analog_in >= 145) && (analog_in <= 154)) {mcp4013pulses = 40;}
    if ((analog_in >= 135) && (analog_in <= 144)) {mcp4013pulses = 41;}
    if ((analog_in >= 125) && (analog_in <= 134)) {mcp4013pulses = 42;}
    if ((analog_in >= 115) && (analog_in <= 124)) {mcp4013pulses = 43;}
    if ((analog_in >= 105) && (analog_in <= 114)) {mcp4013pulses = 44;}
    if ((analog_in >= 95) && (analog_in <= 104))  {mcp4013pulses = 45;}
    if ((analog_in >= 85) && (analog_in <= 94))   {mcp4013pulses = 46;}
    if ((analog_in >= 75) && (analog_in <= 84))   {mcp4013pulses = 47;}
    if ((analog_in <= 74))                       {mcp4013pulses = 48;}

that would save _A LOT_ of lines of codes without adding complexity and ease debugging.
if your compiler isn't too stupid, it will unroll the for loop and the asm will look exactly as if you had typed all that cruft :)

as of the difference between uint8_t and unsigned char, the difference is quite simple really ... :)

C language defines char as a byte.
remember a byte _IS NOT_ 8 bits, a byte is the smallest addressable unit of memory and is hardware dependent.
The fact that a byte is 8 bits on all architectures today (or, architectures that I know of ... which is not a lot of arch I admit) tends to confuse people... but one could imagine an architecture with a byte of 10 bits or 7 bits ...

using uint8_t guarantees you that the you get a type that is "at least" 8 bits long.
so your code will not work if you keep using "unsigned char" and you somehow port if to an architecture using bytes of 6 bits.
but your code will keep working if you use uint8_t because the compiler will use a bigger type.

note that if you want your code to be portable and your intention is to use a byte (and not 8 bits), you can use the CHAR_BIT #define, which contains, as its name says, the number of bits in a byte (and thus the number of bits in a byte).

I hope all that makes sense to you :D
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
This is untested because I haven't got a compiler at hand:
Code:
char temp = 0;
char limit = 235;
    
    if(currentint == 2)
    {
        do
        {
            if((analog_in >= limit) && (analog_in <= limit + 9)) mcp4013pulses = temp + 31;
            else 
            {
                limit -= 10;
                temp++;
            }
        }while(temp < 17);
       mcp4013pulses = 48;
    }
but you should get the general idea.

Brian.
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
thanks, and thanks for this
using uint8_t guarantees you that the you get a type that is "at least" 8 bits long.
..but its (maybe) not good news, I had intended each variable to be exactly eight bits long..and presumed that was what uint8_t was.
i will have to see how this effects the bitwise logical instructions that i have put in.
 

you can check the number of bits in a byte (CHAR_BIT) and the number of bytes allocated to a type (using sizeof() operator), e.g.
Code:
#include <limits.h>
....
printf("CHAR_BIT %d sizeof(char) %d sizeof(int) %d\n", CHAR_BIT, sizeof(char), sizeof(int));

run on a PC with Code::Blocks gave
Code:
CHAR_BIT 8 sizeof(char) 1 sizeof(int) 4

for more details see
https://en.cppreference.com/w/cpp/types/climits

normaly when working on a new system one would check the sizeof int, long int, etc and the precision of float, double, etc
 
Last edited:
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top