View previous topic :: View next topic |
Author |
Message |
cbkulatunge
Joined: 22 Oct 2009 Posts: 12
|
#int_RDA not working |
Posted: Thu Apr 28, 2011 3:20 am |
|
|
I'm receiving serial data from external loadcell amplifier via usart.
it works fine without external int. rda clash when i enable #int_ext
working code
processor;
Code: |
#include <18F452.h>
#fuses hs,nowdt,noprotect,brownout,noput
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
|
main;
Code: |
void main(){
initz();
kbd_init();
lcd_init();
output_high(alarm);
output_low(w_ok);
delay_ms(100);
default_display();
while(true){
delay_ms(500);
disable_interrupts(int_rda);
display_weight();
enable_interrupts(int_rda);
}
}
|
interrupt;
Code: |
#int_EXT
void EXT_isr(void)
{
output_low(h_open);
output_low(h_close);
}
#int_RDA
void RDA_isr(void){
rxda=getc();
if(rxda!='g'){
rxdbuf[r_count]=rxda;
r_count++;
}else{
r_count=0;
weight=0;
multiplier=1;
for(s=18;s>0;s--){
if((rxdbuf[s]>47)&(rxdbuf[s]<58)){
weight+=(rxdbuf[s]-48)*multiplier;
multiplier*=10;
}
}
output_high(pin_d0);
}
}
|
above code work fine until this
Code: |
#int_EXT
void EXT_isr(void)
{
output_low(h_open);
output_low(h_close);
delay_ms(100);
}
|
error occur in any function calls
please help! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Apr 28, 2011 5:01 am |
|
|
Rule number one. Code inside ISRs MUST be short
Rule Number two. NEVER use delay_ms() in any ISR.See rule number one!
Rule Number three. ALWAYS add 'errors' to the use rs232() dirrective.
That's 3 ideas from me..others can help point out other code flaws.. |
|
|
cbkulatunge
Joined: 22 Oct 2009 Posts: 12
|
|
Posted: Thu Apr 28, 2011 9:30 am |
|
|
thanx for reply bro.
i'v already tried with 'errors' directive with rs232 which no effect on this matter. i couldn't find any way to shorten the code inside isr |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Apr 28, 2011 10:40 am |
|
|
Quote: | for(s=18;s>0;s--){
if((rxdbuf[s]>47)&(rxdbuf[s]<58)){
weight+=(rxdbuf[s]-48)*multiplier;
multiplier*=10;
}
|
Put this code in your main() and simply set a flag in the ISR and evaluate that flag in main to do that for() loop. This for() is just as bad as a delay() and will cause you problems. The for() loop could be taking up too much time and you could miss a character coming in.
Ronald |
|
|
pic_micro
Joined: 07 Feb 2011 Posts: 26
|
|
Posted: Thu Apr 28, 2011 10:53 am |
|
|
I think you miss the enable_interrupts(GLOBAL); |
|
|
cbkulatunge
Joined: 22 Oct 2009 Posts: 12
|
|
Posted: Thu Apr 28, 2011 8:24 pm |
|
|
Code: |
void initz(){
//ports
output_a(0);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
PORT_b_PULLUPS(true);
set_tris_e(0);
bit_set(trisb,0);
bit_set(trisb,1);
bit_set(trisb,2);
bit_clear(trisb,3);
bit_clear(trisc,5);
EXT_INT_EDGE(0,h_to_l);
EXT_INT_EDGE(1,h_to_l);
EXT_INT_EDGE(2,h_to_l);
enable_interrupts(int_rda);
enable_interrupts(global);
}
|
|
|
|
cbkulatunge
Joined: 22 Oct 2009 Posts: 12
|
|
Posted: Thu Apr 28, 2011 8:33 pm |
|
|
@rnielsen
i thought so. but conversion must be continues. original main function more complex than i posted. i do few calculations and comparison using 'weight' variable.
this is a one of my function within main()
Code: | void fill_high(){
int32 closepoint,limit1_point,limit2_point,add_w,sub_w;
int limit1_factor,lastbit;
lastbit=read_eeprom(0x2E);
read_setpoint();
add_w=get_eeprom(0x25,2);
sub_w=get_eeprom(0x27,2);
limit1_factor=read_eeprom(0x2c);
limit2_point=get_eeprom(0x29,2);
if(limit1_factor>99){limit1_factor=10;}
closepoint=(setpoint + add_w) - sub_w;
limit2_point=closepoint-limit2_point;
limit1_point=(int32) ((limit1_factor * limit2_point)/100.);
get_delays();
dir=0;
output_high(h_open);
delay_ms(hodl);
output_low(h_open);
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
dir=1;
do{
}while(weight<limit1_point);
output_high(h_close);
do{
}while(weight<limit2_point);
output_low(h_open);
output_high(h_close);
lastpoint=1;
do{
}while(weight<closepoint-lastbit);
output_high(h_close);
delay_ms(afcd);
output_low(h_close);
if(weight<closepoint){
output_high(h_open);
delay_ms(afod);
output_low(h_open);
output_high(h_close);
delay_ms(afcd);
output_low(h_close);
}
lastpoint=0;
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
display_weight();
output_high(w_ok);
output_high(buzer);
delay_ms(400);
output_low(buzer);
delay_ms(400);
output_high(buzer);
delay_ms(400);
output_low(buzer);
} |
|
|
|
|