Discussion in "Project Doubts" started by    bagusdj    Jan 23, 2013.
Wed Jan 30 2013, 02:48 pm
#11
// Program to interface TGS2600 using ADC 0809. The output of TGS2600 is displayed on LCD. Controller interrupt is used to generate the clock for driving ADC 0808.
#include<reg52.h>

sbit ale=P1^0;  //address latch enable
sbit oe=P1^3;  //output enable
sbit sc=P1^1;  //start conversion
sbit eoc=P1^2;  //end of conversion
sbit clk=P1^7;  // clock
sbit ADD_A=P1^4;  // Address pins for selecting input channels.
sbit ADD_B=P1^5;
sbit ADD_C=P1^6;
sfr lcd_data_pin=0xA0;  //P2 port
sbit rs=P3^7;
sbit rw=P3^1;
sbit en=P3^6;
sbit triac=P3^0;
sfr input_port=0x80;  //P0 port
unsigned int bitvalue,decimal_value,key,left_value,value,number,ascii1,ascii2,ascii3,flag,key1,lastReading;
void cct_init(void);
void initint0(void);

void timer0() interrupt 1  // Function to generate clock of frequency 500KHZ using Timer 0 interrupt.
{
clk=~clk;
}

void delay(unsigned int count) //delay function in mS
{
unsigned int i;                         
    while(count) {
        i = 115;
                while(i>
0) i--;
        count--;
}}

void cct_init(void)
 {
 P3=0x05;	//triac is on when active low. initialy triac is off.
 }

void initINT0(void)	  //activate int0
 {
 IT0=1;	 //interupted when transition from logic 1 to 0 (zero cross detector)
 EX0=1;
 EA=1;
 }

void external0_isr(void) interrupt 0 //interrupt routine

{
triac=1;
 if((lastReading>
=52) && (lastReading<=77))	//1st condition
      {delay(4);
       triac=0;}

          else if((lastReading>
=77) && (lastReading<=103))	//2nd condition
              {delay(3);
               triac=0;}

             else if((lastReading>
=103) && (lastReading<=128))	//3rd condition
               {delay(2);
                triac=0;}

                else if(lastReading>
128) //4th condition; full power
                  {triac=0;}

delay(1);
triac=1;
EA=0;
EA=1;
}



void lcd_command(unsigned char comm)  //Function to send command to LCD.
{
lcd_data_pin=comm;
en=1;
rs=0;
rw=0;
delay(10);
en=0;
}

void lcd_data(unsigned char disp)  //Function to send data to LCD.
{
lcd_data_pin=disp;
en=1;
rs=1;
rw=0;
delay(10);
en=0;
}

lcd_dataa(unsigned char *disp)  //Function to send string data to LCD.
{
int x;
for(x=0;disp[x]!=0;x++)
{
  lcd_data(disp[x]);
}
}

void lcd_ini()  //Function to inisialize the LCD
{
lcd_command(0x38); 
delay(5);
lcd_command(0x0E); 
delay(5);
lcd_command(0x80);  //Force cursor to blink at line 1 positon 0
delay(5);
}

void BCD()  // Binary to decimal conversion to send the data to LCD
{
  key1++;
  key=0;
  flag=0;
    lastReading=number=input_port;
    number= number*39;
    number= number/100;
    value=number%10;
number=number/10;
ascii1=value+48;
if(number!=0)
{
  value=number%10;
  number=number/10;
  ascii2=value+48;
    flag=1;
}
else
{
   ascii2=48;
   flag=1;
}
if(number!=0)
{
 value=number%10;
    number=number/10;
    ascii3=value+48;
    key=2;
}
else
{
  ascii3=48;
  key=2;
}
if(key==2)
lcd_data(ascii3);
if(flag==1)
lcd_data(ascii2);
lcd_data(ascii1);
if(key1==3)
{
key1=0;
ascii3=0;
ascii2=0;
ascii1=0;
delay(10);
} 
}



void adc()  //Function to drive ADC
{
while(1)
{
  ADD_C=0;  // Selecting input channel 2 using address lines
  ADD_B=0;
  ADD_A=1;
  delay(2);
  ale=1;
  delay(2);
  sc=1;
  delay(1);
  ale=0;
  delay(1);
  sc=0;
  while(eoc==1);
  while(eoc==0);
  oe=1;
  BCD();
  lcd_command(0x88);
  delay(2);
  oe=0;
  }
}


void main()
{
cct_init();
initINT0();
eoc=1;
ale=0;
oe=0;
sc=0;
key1=0;
TMOD=0x02;  //timer0 setting for generating clock of 500KHz using interrupt enable mode.
TH0=0xFD;
IE=0x82;
TR0=1;
lcd_ini();

lcd_dataa("PPM : ");
lcd_command(0x88);
adc();

}


i tried this code but no thing happen. i thing the number is in binary, since i use 8 channels, means the range is 0-255. i multiply it by 0.39 to become 0-99 in lcd.

i just dont get it, why the interrupt is not executed? or at least why if function is not working? the adc reading is normal.


[ Edited Wed Jan 30 2013, 08:02 pm ]
Wed Jan 30 2013, 11:08 pm
#12
Are you getting the right readings on the display ?
Try just toggling the triac pin the interrupt handler to test that the handler is being called.

If not, check your hardware.


[ Edited Wed Jan 30 2013, 11:40 pm ]
Thu Jan 31 2013, 10:42 am
#13
@ bagusdj
in hardware without controller give a high signal to triace is it working or not
if it is not conducting you has to figure out it first
Thu Jan 31 2013, 10:57 am
#14


@ bagusdj
in hardware without controller give a high signal to triace is it working or not
if it is not conducting you has to figure out it first

majoka



with the same circuit layout (ADC+LCD+MCU+triac) i tried thid code and it works. this is the code for triac ONLY:

#include<reg52.h>

 sbit triac=P3^0;
 void cct_init(void);
 void initint0(void);

void delay(unsigned int count)
{
unsigned int i;                         
    while(count) {
        i = 115;
                while(i>
0) i--;
        count--;
}}

void cct_init(void)
 {
 P3=0x05;					 //triac is on when active low
 }


void initINT0(void)
 {
 IT0=1;
 EX0=1;
 EA=1;
 }



void external0_isr(void) interrupt 0
 {
 delay(5);
 triac=0;
 delay(1);
 triac=1;
 EA=0;
 EA=1;
 }
 
 void main(void)
 {
  cct_init();
  initINT0();
 while(1)
 {} 
 
}


in 6ms delay i got 50v rms. for 5 ms (like in program) i got 91vrms, for 4ms i got 132 vrms, for 3ms i got 172, for 2ms i got 204, for 1ms i got 216. by the experiment, my delay before firing triac is affecting the rms. smaller delay=higher vrms. i think i can conclude the triac circuitry is okay.cmiiw
Thu Jan 31 2013, 11:34 am
#15


Are you getting the right readings on the display ?
Try just toggling the triac pin the interrupt handler to test that the handler is being called.

If not, check your hardware.

ExperimenterUK



someone advise me to modify my code in to this:

void initINT0(void)
 {
 IT0=1;
 EX0=1;
 EA=1;
 }

void external0_isr(void) interrupt 0
 {
firing(); 
 }


then in the firing();
void firing(void)								   //conducted if interrupt occurs
{

 if((input_port>
=52) && (input_port<=77))	//1st condition
      {delay(4);
       triac=0;}

          else if((input_port>
=77) && (input_port<=103))	//2nd condition
              {delay(3);
               triac=0;}

             else if((input_port>
=103) && (input_port<=128))	//3rd condition
               {delay(2);
                triac=0;}

                else if(input_port>
128) //4th condition; full power
                  {triac=0;}

delay(1);
triac=1;
EA=0;
EA=1;
}


then calling the firing(); by recall it in ADC();it sounds silly actualy :s.
void adc()  //Function to drive ADC
{
while(1)
{
  ADD_C=0;  // Selecting input channel 2 using address lines
  ADD_B=0;
  ADD_A=1;
  delay(2);
  ale=1;
  delay(2);
  sc=1;
  delay(1);
  ale=0;
  delay(1);
  sc=0;
  while(eoc==1);
  while(eoc==0);
  oe=1;
  BCD();
  lcd_command(0x88);
  delay(2);
  oe=0;
  firing();
}
}


if i delete triac=1 (under delay(1);) ; in firing(); it works. the range of adc reading in if fuction is 20<=x<=30, 30<x<=40,40<x<=50,and x>50. it all works. i mean in between 20-30 fan turned on. but it ignored the delay before firing triac. so the rms for all of the range is 215vrms. approaching full power.as the theory of phase firing, to decrease vrms the triac must be fired after certain ms delay. and then give it time like 1ms and turn triac off. but by this configuration it should delayed first, then fired triac. but my measurement shows 215++ in every range

but if i dont delete that triac=1; the fan is not working.

i dont get it, why i should call the function?. the interrupt0 has higher priority after reset right? if i use interrupt only for triac only program, it works perfectly.

maybe it causes by alignment of the void? of did i miss something? i really confuse now
Fri Feb 01 2013, 03:14 am
#16
I think this is your main problem

main()
{
..
..
IE=0x82;

This resets the EX0 bit you set in initINT0();

try...
//IE=0x82;
ET0=1;


[ Edited Fri Feb 01 2013, 06:06 am ]
Fri Feb 01 2013, 09:52 am
#17


I think this is your main problem

main()
{
..
..
IE=0x82;

This resets the EX0 bit you set in initINT0();

try...
//IE=0x82;
ET0=1;

ExperimenterUK



hmm not working also. what is ET0? do you really mean ET0 or EX0?

updated. i add EX0=1; instead of ET0=1; , the load seems responding. but i havent check it yet using multimeter. i will update the result soon


[ Edited Fri Feb 01 2013, 11:06 am ]
Sun Feb 03 2013, 03:33 am
#18
ET is for timer 0 interrupt and EX0 is external interrupt 0. make sure you set EA = 1, to enable interrupts along with other bits.

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

PedroDug
Sun May 19 2024, 05:39 pm
JewelAmuck
Sun May 19 2024, 03:06 pm
Minniemus
Sun May 19 2024, 07:39 am
Andyhet
Sat May 18 2024, 07:28 am
BrettTibre
Fri May 17 2024, 06:14 pm
Gordonfax
Fri May 17 2024, 10:28 am
Davidspils
Fri May 17 2024, 10:19 am
Patricknoind
Fri May 17 2024, 09:53 am