|
|
View previous topic :: View next topic |
Author |
Message |
Harish
Joined: 02 Aug 2013 Posts: 2
|
SOLVED:Help in INTERRUPT required for PIC16F873A |
Posted: Fri Aug 02, 2013 11:50 pm |
|
|
I am having problem with interrupts in 16f873a, I have 3 interrupts required for Bulb Dimmer project.
Timer0- Used for pulse modulation.
INT_RB-Port on change interrupt to detect zero crossing detect.
Serial INT_RDA- To receive serial data.
My problem is when I enable port on change interrupt serial data is not being received i.e. my serial interrupt doesn't work.
Here is my code.
Please help urgent.
Code: |
#use rs232(xmit=PIN_C6,rcv=PIN_C7,enable=PIN_B0,baud=9600)
#define MINIMUM_FIRING_ENGLE 170
#define MAXIMUM_FIRING_ENGLE 220
//#BYTE PORTB = 0x05
//#BYTE PORTC = 0x07
#define CH1_ON 0x03
#define CH1_OFF 0x04
#define CH2_ON 0x05
#define CH2_OFF 0x06
#define CH3_ON 0x07
#define CH3_OFF 0x08
#define CH1_UP 0x09
#define CH1_DOWN 0x0a
#byte PortB = getenv("SFR:PortB")
void initialize_ports(void);
void initialize_variables(void);
void read_pot_position(void);
void shift_buff(void);
void shift_adc_buff(void);
void change_position(void);
unsigned int8 fire_on_delay;
unsigned int8 firing_angle;
unsigned int1 TRAIC_GATE;
unsigned int8 data;
int8 count;
unsigned int1 ch1_dim=0;//unsigned int8 temp_port_a;
//------------------------------------------------------------------------------
#int_RDA
void RDA_isr(void)
{
data = getc();
// enable_interrupts(INT_RB);
}
//------------------------------------------------------------------------------
#int_RB
void RB_isr(void) // Zero Cross Detect _ to Pin RB5
{
int8 current;
static int last=0;
TRAIC_GATE=1;
disable_interrupts(INT_RB);
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
set_tris_b(0xF0);
current=input_b();
last=current;
enable_interrupts(INT_RB);
}
//------------------------------------------------------------------------------
#int_TIMER0
void TIMER0_isr(void)
{
disable_interrupts(INT_TIMER0); //disable timer0 interrupt
if(TRAIC_GATE)
{
output_low(PIN_A2);
TRAIC_GATE=0;
set_timer0(fire_on_delay);
enable_interrupts(INT_TIMER0);
}
else if(!TRAIC_GATE)
{
output_high(PIN_A2);
TRAIC_GATE=1;
}
}
//------------------------------------------------------------------------------
void main()
{
port_b_pullups(TRUE);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
// setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
TRAIC_GATE=0;
count=145; //MINIMUM_FIRING_ENGLE;
initialize_ports();
initialize_variables();
enable_interrupts(INT_RB);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(TRUE)
{
switch(data)
{
case CH1_ON:
// output_high(PIN_A0);
// output_low(PIN_A2);
count=220;
// fire_valu_calc();
ch1_dim=1;
break;
case CH1_OFF:
// output_low(PIN_A0);
output_high(PIN_A2);
// ch1_on=0;
ch1_dim=0;
break;
case CH2_ON:
output_high(PIN_A0);
break;
case CH2_OFF:
output_low(PIN_A0);
break;
case CH3_ON:
output_high(PIN_A1);
break;
case CH3_OFF:
output_low(PIN_A1);
break;
default:
break;
}
if(!input(PIN_C2))
{
delay_ms(50);
if(! input(PIN_C2))
{
if(count < 220)
{
count++;
}
else
{
count =220;
}
}
}
if(! input(PIN_C3))
{
delay_ms(50);
if(! input(PIN_C3))
{
if(count > 145)
{
count--;
}
else
{
count =145;
}
}
}
initialize_variables();
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void initialize_ports(void)
{
output_low(PIN_A0);
output_low(PIN_A1);
output_high(PIN_A2);
// output_float(PIN_A3);
// output_float(PIN_A4);
// output_float(PIN_A5);
// output_high(PIN_C0);
// output_float(PIN_C1);
// output_high(PIN_C2);
// output_high(PIN_C3);
// output_float(PIN_C4);
// output_high(PIN_B5);
}
//------------------------------------------------------------------------------
void initialize_variables(void)
{
firing_angle = count;
fire_on_delay= 400-firing_angle;
}
//------------------------------------------------------------------------------
| [/b]
Last edited by Harish on Tue Aug 06, 2013 10:11 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sat Aug 03, 2013 5:26 am |
|
|
just a few comments...things you can think over...no particular order...
1) ...
fire_on_delay= 400-firing_angle
...
what's the biggest number an unsigned int8 can have in it?
2) you could 'clean up' the program by assigning all variables as 'global'.you've got lots of RAM for this small program, making it simpler to follow.
3) add comment 'headers' before prototype, variable assignments, etc.,again, just to tidy things up and be organized.The neater a program looks, the faster you'll see mistakes.
4) ISRs must be short and fast.First operation within the INT_RB should be to read the portB.There's no need to disable interupts within an ISR, compiler handles it for you.
5)same hold true for set_tris....let the compiler do it ,automatically.
6) always add 'errors' to the #use rs232(..options..).it keeps the UART from 'locking up'.
7) you've chosen B0 to be the enable pin,presumably for an RS-485 network ? Not required for RS-232.
8) Triac is spelled TRIAC not TRAIC.Again, something to 'tidy up' your program,it can be confusing to another programmer.
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Sun Aug 04, 2013 12:31 am |
|
|
One possibility Change the ISR to:
Code: |
#int_RB
void RB_isr(void) // Zero Cross Detect _ to Pin RB5
{
int8 current;
static int8 current;
current=input(PIN_B5);
if (last!=current)
{
//Here B6 has changed
TRIAC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
last=current;
}
}
|
The comments about INT_RB already made apply.
Then, there is an erratum on some PIC 16's, where a movf from the input port, won't reset the latch (this is what a byte wide input does). I couldn't find it listed for this one, but switching to testing just the one pin, avoids this.
Final one though is that if noise is picked up on the other pins of portB, this could trigger the interrupt at the wrong time. Given the noise likely from a triac circuit, this may be causing your problems....
Best Wishes |
|
|
Harish
Joined: 02 Aug 2013 Posts: 2
|
|
Posted: Mon Aug 05, 2013 12:25 pm |
|
|
Ttelmah wrote: | One possibility Change the ISR to:
Code: |
#int_RB
void RB_isr(void) // Zero Cross Detect _ to Pin RB5
{
int8 current;
static int8 current;
current=input(PIN_B5);
if (last!=current)
{
//Here B6 has changed
TRIAC_GATE=1;
set_timer0(firing_angle);
enable_interrupts(INT_TIMER0); //Enable timer0 interrupt
last=current;
}
}
|
The comments about INT_RB already made apply.
Then, there is an erratum on some PIC 16's, where a movf from the input port, won't reset the latch (this is what a byte wide input does). I couldn't find it listed for this one, but switching to testing just the one pin, avoids this.
Final one though is that if noise is picked up on the other pins of portB, this could trigger the interrupt at the wrong time. Given the noise likely from a triac circuit, this may be causing your problems....
Best Wishes |
Thank you Ttelmah you save the day for me your code applied and it worked thank you again |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Tue Aug 06, 2013 9:28 am |
|
|
Thanks for posting back - you might like to flag the thread as 'solved'.
It makes it much more useful for other people looking in the future.
It is annoying when the thread just 'dies' without knowing what did/didn't work.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|