electronicnoob
Junior Member level 1
Hi, I'm doing a project which is an etching tank. I'm using a PIC16F887 and a RTC 3231 to keep time. I plan to control the temperature by controlling the phase firing delay. I am using IOC on pin RB2 to read the zero crossing circuit and sending a pulse to RB3 to turn on the heater. I am also using external interrupt on pin RB0 to turn on/off the air pump for agitation connected to a relay with the output at RB1. I am monitoring the temperature using a lm35 temperature sensor and ADC on pin RA5. I have more code on the matrix keypad but I don't have any problem with it.
However, when programmed an turned on, the code sometimes freezes after I run the CheckCurrentTemp(), for the first time. I am still able to turn on and off the air pump via RB) interrupt but other than that the program isn't running. By that time, the program doesn't even check the time and keep on running even though the time is supposed to be over. For now, my duration is set in seconds instead of minutes because for testing purposes.
Thank you for your time and I would really appreciate your help. Thanks in advance.
C:
#pragma config CONFIG1 = 0x2CD2
#pragma config CONFIG2 = 0x0700
#include <xc.h>
#define _XTAL_FREQ 20000000
#include <stdint.h> // include stdint header
#include "LCD_Lib.c" // include LCD driver source file
// variables declaration
uint8_t i, second, minute, hour, m_day, month, year;
int mintemp, maxtemp, midtemp;
uint8_t templvl;
uint16_t duration = 0;
uint32_t StartTime, TimeNow, EndTime;
static int td = 0;
uint16_t AN0RES=0;
int Temp;
char TempSTR[16];
static char TempPrint[] = " \337C";
int a,b,c,d,t,u;
void RTC()
{
// convert data from BCD format to decimal format
second = bcd_to_decimal(second);
minute = bcd_to_decimal(minute);
hour = bcd_to_decimal(hour);
m_day = bcd_to_decimal(m_day);
month = bcd_to_decimal(month);
year = bcd_to_decimal(year);
// end conversion
TimeNow = (hour*3600)+(minute*60)+second;
}
void CheckCurrentTime(void)
{
I2C_Init(100000); // initialize I2C bus with clock frequency of 100kHz
// read current time and date from the RTC chip
I2C_Start(); // start I2C
I2C_Write(0xD0); // RTC chip address
I2C_Write(0); // send register address
I2C_Repeated_Start(); // restart I2C
I2C_Write(0xD1); // initialize data read
second = I2C_Read(1); // read seconds from register 0
minute = I2C_Read(1); // read minutes from register 1
hour = I2C_Read(1); // read hour from register 2
I2C_Read(1); // read day from register 3 (not used)
m_day = I2C_Read(1); // read date from register 4
month = I2C_Read(1); // read month from register 5
year = I2C_Read(0); // read year from register 6
I2C_Stop(); // stop I2C
RTC(); // print time & date
}
/************************** end RTC chip functions ***************************/
/*************************** Phase Firing Functions ***************************/
void initPhase(void);
void Pause(int);
void initPhase(void)
{
PORTB = 0;
ANSELH = 0x00;
TRISBbits.TRISB0 = 1;
TRISBbits.TRISB2 = 1;
TRISBbits.TRISB3 = 0;
WPUB = 0b00000001;
IOCB = 0x04;
OPTION_REGbits.nRBPU = 1; // clear RBPU bit (OPTION_REG.7)
OPTION_REGbits.INTEDG = 1;
INTCONbits.GIE = 1; //global interrupt enable
INTCONbits.PEIE = 0; //disable peripheral interrupts (PEIE)
INTCONbits.RBIE = 1;
INTCONbits.INTE = 1;//For external interrupt (RB0/INT)PORTB = 0;
}
void light(int X)
{
Pause(X);
PORTBbits.RB3 = 1;
__delay_ms(0.5);
PORTBbits.RB3 = 0;
}
void Pause(int microseconds)
{
while(microseconds > 0)
{
__delay_us(100);
microseconds = microseconds - 100;
}
}
void __interrupt () isr()
{
if (INTCONbits.RBIF == 1)
{
if (PORTBbits.RB1 == 1)
{
__delay_ms(1);
light(td);
}
else
light(td);
}
if (INTCONbits.INTF == 1)
{
if(PORTBbits.RB1 == 1)
{
PORTBbits.RB1 = 0;
}
else if (PORTBbits.RB1 == 0)
{
PORTBbits.RB1 = 1;
}
INTCONbits.INTF = 0;
}
}
/************************* End Phase Firing Functions *************************/
/************************* Temperature ADC Functions *************************/
void InitADC(void);
uint16_t ADC_Read(void);
void CheckCurrentTemp(void);
void InitADC(void)
{
ADCON0 = 0x91;
ADCON1 = 0x80;
PORTA = 0x00;
TRISA = 0x20;
ANSEL = 0x10;
}
uint16_t ADC_Read(void)
{
ADCON0 = 0x91;
__delay_us(30);
GO_DONE = 1; // Start A/D Conversion
while(ADCON0bits.GO_DONE); // Polling GO_DONE Bit
return ((ADRESH<<8)+ADRESL);
}
void CheckCurrentTemp(void)
{
AN0RES = ADC_Read(); // Read Analog Channel 4
Temp = AN0RES * 48.828;
Temp = Temp + 200;
sprintf(TempSTR, "%4d", Temp); // Convert The Temperature From Float To String
LCD_Cmd(LCD_CLEAR);
TempPrint[0]=TempSTR[0];
TempPrint[1]=TempSTR[1];
TempPrint[2]= '.';
TempPrint[3]=TempSTR[2];
TempPrint[4]=TempSTR[3];
LCD_Goto(1, 1);
LCD_Print("Temperature");
LCD_Goto(1, 2);
LCD_Print(TempPrint);
}
/************************* Temperature ADC Functions *************************/
void main(void)
{
a = b = t = c = d = 0;
templvl = 10;
static char Duration[3];
static char TempLVL[16];
char Key = 'n';
LCD_Begin();
Clock();
InitKeypad();
LCD_Cmd(LCD_CLEAR);
// enter etching temperature
while (templvl > 3)
{
c = 0;
LCD_Cmd(LCD_CLEAR);
LCD_Goto(1, 1);
LCD_Print("Set Temp level");
LCD_Goto(1, 2);
LCD_Print(" 0 , 1 , 2 , 3 ");
Key = switch_press_scan_num();
TempLVL[0] = Key;
LCD_Cmd(LCD_CLEAR);
LCD_Goto(1, 1);
LCD_Print("Set Temp level");
LCD_Goto(1, 2);
LCD_Print(TempLVL);
__delay_ms(750);
LCD_Cmd(LCD_CLEAR);
templvl = atoi(TempLVL);
if (templvl >= 4)
{
LCD_Goto(1, 1);
LCD_Print("Invalid Input");
__delay_ms(750);
while (c<=1)
{
TempLVL[c]=' ';
c++;
}
continue;
}
}
LCD_Cmd(LCD_CLEAR);
if (templvl == 0)
{
LCD_Goto(1,1);
LCD_Print("Please turn OFF");
LCD_Goto(1,2);
LCD_Print("the Heater");
__delay_ms(1000);
LCD_Cmd(LCD_CLEAR);
}
// end etching temperature input
if(templvl == 1)
{
mintemp = 3500; // minimum temp of Temperature Level 1
midtemp = 3600;
maxtemp = 3800;
td = 5100;
}
if(templvl == 2)
{
mintemp = 3900;
midtemp = 4000;
maxtemp = 4100;
td = 5800;
}
if(templvl == 3)
{
mintemp = 4200;
midtemp = 4300;
maxtemp = 4500;
td = 6200;
}
// enter etching duration
LCD_Goto(1, 1);
LCD_Print("Enter Duration");
while(t<2){
Key = switch_press_scan_num();
if ((Key == '#')&&(t>0))
{
Duration[t-1]=' ';
LCD_Goto(1, 2);
LCD_Printr(Duration);
__delay_ms(200);
t--;
}
else if (Key != '#')
{
LCD_Goto(1, 2);
Duration[t] = Key;
LCD_Printr(Duration);
__delay_ms(200);
t++;
}
}
//end etching duration input
duration = atoi(Duration);
duration = duration * 60;
LCD_Cmd(LCD_CLEAR);
CheckCurrentTime();
StartTime = TimeNow;
EndTime = StartTime + duration;
LCD_Goto(1,1);
LCD_Print("Starting Etching");
LCD_Goto(1,2);
LCD_Print("Process");
__delay_ms(1000);
InitADC();
PORTBbits.RB1 = 0; //turn on air pump
LCD_Cmd(LCD_CLEAR);
CheckCurrentTemp();
/*while((Temp <= midtemp)&&(TimeNow <= EndTime))
{
PORTBbits.RB3 = 1;
__delay_ms(1000);
CheckCurrentTemp();
}
PORTBbits.RB3 = 0;
while((Temp >= midtemp)&&(TimeNow <= EndTime))
{
PORTBbits.RB3 = 0;
__delay_ms(1000);
CheckCurrentTemp();
}*/
PORTBbits.RB3 = 0;
initPhase();
while (TimeNow <= EndTime)
{
d = 0;
while((d<=200)&&(TimeNow <= EndTime))
{
CheckCurrentTime();
__delay_ms(100);
d++;
}
CheckCurrentTemp();
if (Temp > maxtemp)
{
td -= 100;
}
else if (Temp < maxtemp)
{
td += 100;
}
else
{
td = td;
}
CheckCurrentTime();
}
INTCONbits.GIE = 0;
PORTBbits.RB1 = 1; //turn off air pump
LCD_Goto(1,1);
LCD_Print("Etching Process");
LCD_Goto(1,2);
LCD_Print("Complete");
However, when programmed an turned on, the code sometimes freezes after I run the CheckCurrentTemp(), for the first time. I am still able to turn on and off the air pump via RB) interrupt but other than that the program isn't running. By that time, the program doesn't even check the time and keep on running even though the time is supposed to be over. For now, my duration is set in seconds instead of minutes because for testing purposes.
Thank you for your time and I would really appreciate your help. Thanks in advance.