Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Please check this C code (microchip XC8 compiler)

Status
Not open for further replies.

Flyback

Well-Known Member
This code is for pic18f65k22 and written in mplab.x
It turns led drivers on and off depending on switch presses, overtemperature, or the led connector getting pulled apart.

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;
}
 
Hi,

Yup, looks like all 1064 lines of code and comments are there :D

Have you tried running the code on the hardware with debugger and seeing if it performs as expected ?
 
Hi,

If hardwares not there yet, what about running/debugging it in a Simulator, you have nothing too unusual on the inputs.
Expect you have access to some quality simulators there ..?
 
Looks like you have done a lot of work writing that code. Some parts of the code is very repeating.. very "labor intensive" to write that kind of code.

I scrolled the code fast and spotted mistakes in the "void read_dips(void)" function:

if (dip1pin) {dipsw1 = 0x01; dip8 = dip8 || 0x01;}
You have logic OR (||) there: dip8 = dip8 || 0x01;

Should that be bitwise OR (|).. i.e. you want to set the bit number zero to 1?:
if (dip1pin) {dipsw1 = 0x01; dip8 = dip8 | 0x01;}
 
What is this supposed to do.. very strange piece of code:
C:
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;
}

If the idea is to generate fast pulses (How fast?), then you may not get the desired results with that code. The compiler will possibly optimize some of that code away. Maybe you should control the timing with delays.
EDIT: Ok.. the (bit) variables are probably "volatile", so maybe that piece of code is ok.. if you have calculated the timing.
 
Last edited:
Thankyou very much misterT, you are brilliant, I would never have spotted the bitwise or thing...you are exactly right, it is bitwise or that is required.
The comments about the MCP4013 code you make are correct, it is just code to move the wiper of a mcp4013 digital pot with up/down protocol.....it needs to be done as quickly as possible, but with the pulses being maximum 400KHz in frequency.
 
Be honest Flyback, is this your code, or have you just copied and pasted from somewhere else? :p
 
The code is overly verbose. e.g. in the set_current_ext_AL function, the 106 lines to set the mcp4013pulses value could be replaced with just 6 lines:
Code:
if (currentint == 2)
    mcp4013pulses = 31 + (analog_in + 3) / 13;
else if (currentint == 3)
    mcp4013pulses = 17 + (analog_in - 2) / 8;
else if (currentint == 4)
    mcp4013pulses = 4 + (analog_in - 5) / 5;
The same would go for set_current_ext_AH.
Also, every time you read the ADC you manually inline the function; why don't you just write a method "uintX_t get_adc(uint8_t channel)" and call it. This code doesn't follow standard programming practices, you don't use a single local variable, or a single function that takes a parameter or returns a value; every function relies solely on global variables.
 
it is my code, I don't think you can find code on the web, not long programs anyway.
I see your point about the ...AH and ...AL functions.....I see you use divide , which I worried would cause poorly optimized code in the free xc8 compiler?
 
it is my code, I don't think you can find code on the web, not long programs anyway.
I see your point about the ...AH and ...AL functions.....I see you use divide , which I worried would cause poorly optimized code in the free xc8 compiler?
Going through ~30 if-statements with two comparisons is not very efficient either. You could at least use "else if".

if (currentint == 2) {
//9 apart
if (analog_in > 234) {mcp4013pulses = 31;}
else if (analog_in > 224) {mcp4013pulses = 32;}
else if (analog_in > 214) {mcp4013pulses = 33;}
else if (analog_in > 204) {mcp4013pulses = 34;}
etc...

This way the the function can exit as soon as the "right slot" is found.
 
I wouldn't expect the built-in functions (like divide) to be too bad. You may find it's smaller than your original version due to the amount of garbage the free compiler inserts in the assembler output.

You could always get someone with the PRO compiler to compile it for you, or use the PRO demo version (if they still offer it).
 
Division can be replaced by multiplication.

I don't think it's a good idea to top mcp4013 every time you want to change it. Remember the position, and, if what you need is different from the current position move it up or down accordingly. Or, better yet, sense the output of mcp4013.

If you run at 20MHz then it's a good chance that your pulses will go out faster than 400kHz.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top