#include<htc.h>
#include<pic.h>
#include<conio.h>
#include<stdio.h>
#include<math.h>
__CONFIG(FOSC_INTRC_CLKOUT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & LVP_OFF);
//__CONFIG(WDTDIS & INTIO & UNPROTECT & PWRTEN & LVPDIS & BORDIS);
unsigned int ADCRead(unsigned char channel);
#define V52 969 // x = (1024 * voltage_devider voltage) / 5
#define V48 893
#define V26 484
#define V11 205 // in case of network fault
void main (void)
{
unsigned int Vadc0; // Vin in charge
unsigned int Vadc1; // Vout in charge and Vin in discharge
double dutyCycle = 0.0, square = 0.0;
double K = 0.0, K_Critical = 0.0;
PORTA=0;
OSCCON = 0b01110101; // 8 Mhz, internal oscillator
ADCON1 = 0b10000000; // right justified, uses Vdd and Vss
TRISA = 0b00000011; // 2 ports defined as input (RA0, RA1)
ANSEL = 0b00000011; // 2 ports defined as input (ANS0, ANS1)
PR2 = 0b00001001; // =9, maximum counter value
T2CON = 0b00000101; // =5,
CCP1CON = 0b00000000;
CCP2CON = 0b00000000;
// ADCON0 = 0b10000001;// | (channel << 3); //Change channel
while(1)
{
Vadc0 = ADCRead(0); //Gets reading from channel 0
//__delay_ms(10000); // request a delay in milliseconds
Vadc1 = ADCRead(1); //Gets reading from channel 1
TMR2IF=0; // reset TMR2
if (Vadc0 > V11) { // Vadc0=Vdd, Charging
if ((Vadc0 > V26) && (Vadc1 <= V48)) { // Buck
dutyCycle = Vadc1 / (Vadc0 - 0.0177);
K = (5.585454545 * 15) / Vadc1;
K_Critical = 1 - dutyCycle;
if (K_Critical > K) {
square = ((2 * Vadc0 - Vadc1) / Vadc1)^2;
dutyCycle = sqrt((4 * K)/(square - 1));
}
CCPR1L = (unsigned int)(dutyCycle * 40) >> 2;
CCPR2L = 0b00001010;
}else if ((Vadc0 >= V48) && (Vadc1 < V52)) { // Boost
dutyCycle = ((Vadc1 + 0.0177 - Vadc0) / Vadc1) + 0.0253;
CCPR2L = (unsigned int)(dutyCycle * 40) >> 2;
CCPR1L = 0b00001010;
}else if ((Vadc0 < V26) || (Vadc1 > V52)) {
CCPR1L = 0b00001010; //zero duty cycle
CCPR2L = 0b00001010;
}
}else { // Vdd = 0; discharging
if ((Vadc0 > V26) && (Vadc1 < V48)) { // Boost
dutyCycle = ((Vadc0 + 0.0177 - Vadc1) / Vadc0) + 0.0253;
K = (5.585454545 * 15) / Vadc0;
K_Critical = dutyCycle * (1 - dutyCycle) * (1 - dutyCycle);
if (K_Critical > K) {
square = ((2 * Vadc0 - Vadc1) / Vadc1)^2;
dutyCycle = sqrt((square * K - K) / 4);
}
CCPR1L = (unsigned int)(dutyCycle * 40) >> 2;
CCPR2L = 0b00001010;
}else if ((Vadc0 > V48) && (Vadc1 < V52)) { // Buck
dutyCycle = Vadc0 / (Vadc1 - 0.0177);
CCPR2L = (unsigned int)(dutyCycle * 40) >> 2;
CCPR1L = 0b00001010;
}else if ((Vadc0 < V26) || (Vadc1 > V52)) {
CCPR1L = 0b00001010;
CCPR2L = 0b00001010;
}
}
}
}
unsigned int ADCRead(unsigned char channel){
unsigned char l_byte, h_byte;
unsigned int ADR;
ADCON0 = 0b10000001 | (channel << 2); //Change channel
__delay_ms(1); // request a delay in milliseconds
GO_DONE = 1; //Set GO_DONE bit to start conversion
while (GO_DONE ); //Wait for bit to be cleared
//If bit is cleared, this means conversion is over
l_byte = ADRESL;
h_byte = ADRESH;
ADR = (h_byte<<8)|l_byte;
return ADR;
}