|
|
View previous topic :: View next topic |
Author |
Message |
mojsa2000
Joined: 18 May 2010 Posts: 78
|
a problem after compiling a program |
Posted: Fri Jul 02, 2010 8:00 am |
|
|
Hi
I've made a program with these options:
timer0(RTCC)
using I2C for 2EEPROM and DS1307
using LCD(16*2)
When I compile the program there are no errors but some warnings occur
and my program doesn't work.
The warnings are:
Code: |
>>> Warning 216 "sana.c" Line 308(0,1): Interrupts disabled during call to prevent re-entrancy: (@DIV88)
>>> Warning 216 "sana.c" Line 308(0,1): Interrupts disabled during call to prevent re-entrancy: (@MULFF)
>>> Warning 216 "sana.c" Line 308(0,1): Interrupts disabled during call to prevent re-entrancy: (@ADDFF)
Memory usage: ROM=64% RAM=30% - 42%
0 Errors, 5 Warnings.
|
Why these warning take place? and how I solve the problem? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Jul 02, 2010 8:34 am |
|
|
The warnings are because you are doing a lot of stuff in one or more of the interrupts. You have significant arithmetic going on somewhere inside an interrupt. Probably _not_ what is causing the code not to work, but it won't be helping.
Examples of things that cause this, using the CCS SISR.C example, and changing the buffer size to a 'non binary' value (so having a buffer size of (say) 20, rather than 16, 32, 64). This results in having to perform a division in the IRQ - with the binary size, the same result can be obtained without this.
Post the interrupt code (provided it is not too large), and we may be able to tell you what is actually causing the problem here.
However, as I say, this is almost certainly not what is stopping the code working....
Best Wishes |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Fri Jul 02, 2010 8:35 am |
|
|
You are using functions and/or operators in your interrupts which are also used in your main code. Because the PIC can not handle re-entrancy (call to a function whils't in the function i.e. from an interrupt) the compiler disables interrupts for these routines.
It may not appear to be a function call but if a routine is required to do what you want then it will use a function call to do it. This will depend on what pic you are using. For instance if the pic does not have built in maths processing then a multiplication in your interrupt will require a function call to do it. This also goes for a divide.
The DIV88 references an int8/int8 call
The MULFF is a multiply.
The ADDFF not sure with out looking at the data sheet but as we don't know what PIC you are using... |
|
|
mojsa2000
Joined: 18 May 2010 Posts: 78
|
|
Posted: Fri Jul 02, 2010 10:07 am |
|
|
Some information about my program:
Code: |
#include <16f877a.h>
#DEVICE ADC=10
#use delay (clock=4000000)
|
Code: |
//**************************************************************
//************************* RTCC INT START ******************
//**************************************************************
#int_RTCC
void RTCC_isr(void)
{
half_min_counter++;
one_min_counter++;
if (min%5==0)
{
if(!first_time_flag_check)
{
five_min_write_to_eeprom=1;
first_time_flag_check=1;
break;
}
}
else
first_time_flag_check=0;
//**************************************
if (min==0)
{
if(!first_time_flag_check_for_hour)
{
hour_write_to_eeprom=1;
first_time_flag_check_for_hour=1;
}
}
else
first_time_flag_check_for_hour=0;
//****************************************
if(hour==0)
{
if(!first_time_flag_check_for_day)
{
day_write_to_eeprom=1;
first_time_flag_check_for_day=1;
}
}
else
first_time_flag_check_for_hour=0;
//****************************************
if(half_min_counter==30)
{
half_min_flag=1;
half_min_counter=0;
}
if(one_min_counter==60)
{
one_min_flag=1;
one_min_counter=0;
}
}
//*****************************************************
//******************** RTCC INT END *******************
//*****************************************************
|
I've defined some flags in my RTCC int routine.
Please tell me how I can correct my faults. |
|
|
mojsa2000
Joined: 18 May 2010 Posts: 78
|
|
Posted: Sun Jul 04, 2010 5:24 am |
|
|
Hi
this is the my program:::
please help me if you can.
Code: |
#include <16f877a.h>
#DEVICE ADC=10
#use delay (clock=4000000)
#include <I:\ELECTRONICS\PIC\My sources\ds1307.c>
#include <I:\ELECTRONICS\PIC\My sources\24c512.c>
#include <I:\ELECTRONICS\PIC\My sources\memory_pointers_maker.c>
#include <lcd.c>
#define use_lcd_portd true //set port D to use LCD
float read_AD,v_average=0,i_average=0;
float hourly_v=0,hourly_i=0;
float daily_v=0,daily_i=0;
float hourly_positive_power=0,hourly_negative_power=0;
float daily_positive_power=0,daily_negative_power=0;
float hourly_VI_value=0;
float daily_VI_value=0;
float v_dc_ave,i_dc_ave;
//********************* All flags *******************************************
int1 half_min_flag;//a flag for checking that 30 seconds are passed
int1 one_min_flag;
int1 five_min_write_to_eeprom;
int1 hour_write_to_eeprom;
int1 day_write_to_eeprom;
int1 first_time_flag_check=0;
int1 first_time_flag_check_for_hour=0;
int1 first_time_flag_check_for_day=0;
//*****************************************************************************
unsigned int8 half_min_counter=0;
unsigned int8 one_min_counter=0;
unsigned int16 v_memory_pointer,i_memory_pointer;
unsigned int16 hourly_pos_VI_memory_pointer,hourly_neg_VI_memory_pointer;
unsigned int16 daily_pos_VI_memory_pointer,daily_neg_VI_memory_pointer;
int8 shift_to_right_counter;
//**************** setting up ds1307 ******************
//*****************************************************
byte sec;
BYTE min;
BYTE hour;
BYTE day;
BYTE month;
BYTE year;
BYTE dow;
//*
int channel;
#int_AD
void AD_isr(void)
{
channel++;//choose wich cannel is reading
read_AD=read_adc(ADC_READ_ONLY);
if (channel==1)//read channel(0)_reserved for voltage
{
v_average=(read_AD+v_average)/2; //make an average of voltage
v_dc_ave=v_average*5/1023;
//make true voltage from its formul
}
if(channel==2)//read channel(1)__reserved for current
{
i_average=(read_AD+i_average)/2;//make an average of current
i_dc_ave=i_average*5/1023;
channel=0;
}
}
//**************************************************************
//************************* RTCC INT START ******************
//**************************************************************
#int_RTCC
void RTCC_isr(void)
{
half_min_counter++;
one_min_counter++;
if (min%5==0)
{
if(!first_time_flag_check)
{
five_min_write_to_eeprom=1;
first_time_flag_check=1;
break;
}
}
else
first_time_flag_check=0;
//**************************************
if (min==0)
{
if(!first_time_flag_check_for_hour)
{
hour_write_to_eeprom=1;
first_time_flag_check_for_hour=1;
}
}
else
first_time_flag_check_for_hour=0;
//****************************************
if(hour==0)
{
if(!first_time_flag_check_for_day)
{
day_write_to_eeprom=1;
first_time_flag_check_for_day=1;
}
}
else
first_time_flag_check_for_hour=0;
//****************************************
if(half_min_counter==30)
{
half_min_flag=1;
half_min_counter=0;
}
if(one_min_counter==60)
{
one_min_flag=1;
one_min_counter=0;
}
}
//*****************************************************
//******************** RTCC INT END *******************
//*****************************************************
void shifting_to_right()
{
for(shift_to_right_counter=0;shift_to_right_counter<16;shift_to_right_counter++)
{
shift_to_right();
delay_ms(800);
}
}
float read_hourly_vi(int8 hour)
{
hourly_pos_VI_memory_pointer_func(hour);
hourly_positive_power=eeprom_read(hourly_pos_VI_memory_pointer);
hourly_neg_VI_memory_pointer_func(hour);
hourly_negative_power=eeprom_read(hourly_neg_VI_memory_pointer);
return hourly_positive_power ,hourly_negative_power;
}
float read_daily_vi(int8 day)
{
daily_pos_VI_memory_pointer_func(day);
daily_positive_power=eeprom_read(daily_pos_VI_memory_pointer);
daily_neg_VI_memory_pointer_func(day);
daily_negative_power=eeprom_read(daily_neg_VI_memory_pointer);
return daily_positive_power,daily_negative_power;
}
void main()
{
enable_interrupts(INT_AD);
enable_interrupts(INT_EXT);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_CLOCK_DIV_8);
ext_int_edge( H_TO_L );
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
setup_timer_0(RTCC_EXT_H_TO_L|RTCC_DIV_32);
set_timer0(0);
ds1307_init();
// Set date for -> 15 July 2005 Tuesday
// Set time for -> 15:20:55
ds1307_set_date_time(15,7,10,6,15,20,0);
ds1307_get_date(day,month,year,dow);
ds1307_get_time(hour,min,sec);
while(1)
{
printf(lcd_putc,"this is a test" );
shifting_to_right();
//********* set up the A/D module *************
set_adc_channel(0);
read_adc(ADC_START_ONLY);
delay_ms(2);
set_adc_channel(1);
read_adc(ADC_START_ONLY);
delay_ms(2);
////**********************************************
if(half_min_flag)
{
ds1307_get_date(day,month,year,dow);
ds1307_get_time(hour,min,sec);
half_min_flag=0;
//**********************
if (five_min_write_to_eeprom)
{
v_memory_pointer=((hour*12)+(min/5))*4;
eeprom_write(v_dc_ave,v_memory_pointer);
i_memory_pointer=(((hour*12)+(min/5))*4)+1152;
eeprom_write(i_dc_ave,i_memory_pointer);
hourly_v+=v_dc_ave;
hourly_i+=i_dc_ave;
five_min_write_to_eeprom=0;
//********************************
if(hour_write_to_eeprom)
{
hourly_VI_value=hourly_v*hourly_i;
daily_v+=hourly_v;
daily_i+=hourly_i;
hourly_v=0;
hourly_i=0;
if(hourly_VI_value>=0)
{
hourly_pos_VI_memory_pointer_func(hour);
eeprom_write(hourly_VI_value,hourly_pos_VI_memory_pointer);
}
//*****************************************
if(hourly_VI_value<0)
{
hourly_neg_VI_memory_pointer_func(hour);
eeprom_write(hourly_VI_value,hourly_neg_VI_memory_pointer);
}
hour_write_to_eeprom=0;
read_hourly_vi(hour);
//******************************************************************
//*****************************************************************
}
if(day_write_to_eeprom)
{
daily_VI_value=daily_v*daily_i;
daily_v=0;
daily_i=0;
if(daily_VI_value>=0)
{
daily_pos_VI_memory_pointer_func(day);
eeprom_write(daily_VI_value,hourly_pos_VI_memory_pointer);
}
if(daily_VI_value<0)
{
daily_neg_VI_memory_pointer_func(day);
eeprom_write(daily_VI_value,hourly_neg_VI_memory_pointer);
}
day_write_to_eeprom=0;
///////////////////////////////////99999999
}
}
}
if(one_min_flag)
{
lcd_clear();
lcd_gotoxy(1,1);
printf(lcd_putc,"date: 20%u/%u/%u",year,month,day);
delay_ms(3000);
shifting_to_right();
lcd_gotoxy(1,1);
printf(lcd_putc,"time: %02u:%02u:%02u",hour,min,sec);
delay_ms(3000);
shifting_to_right();
lcd_gotoxy(1,2);
printf(lcd_putc,"cons/h: %5.3f",hourly_positive_power);
delay_ms(3000);
shifting_to_right();
lcd_gotoxy(1,2);
printf(lcd_putc,"supply/h:%5.3f",hourly_negative_power);
delay_ms(3000);
shifting_to_right();
lcd_gotoxy(1,2);
printf(lcd_putc,"cons/d:%5.3f",daily_positive_power);
delay_ms(3000);
shifting_to_right();
lcd_gotoxy(1,2);
printf(lcd_putc,"supply/d:%5.3f",daily_negative_power);
delay_ms(3000);
shifting_to_right();
one_min_flag=0;
}
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sun Jul 04, 2010 2:48 pm |
|
|
A lot of things.
Don't convert the ADC value in the IRQ. Do this in the main code outside. The division by 1023, is one part of the problem.
In fact your ADC IRQ, is wildly pointless. You are starting the ADC, and letting the interrupt trigger, which takes longer to do, than just taking the reading.
The _only_ reasons to use the ADC IRQ, are:
1) If you are stopping the processor to perform the reading, or
2) You are starting the ADC, with the CTC.
Get rid of this, and just take the ADC reading.
Then, you have an external RTC module, but are using INT_RTCC. INT_RTCC, is for an internal RTCC. It seems a total waste to have an external RTCC chip, and also use the RTCC ability of the PIC. Have you actually got an external clock being fed into the Timer0 input?. If not, this won't work at all
Don't use the %5 operator in the RTCC. You seem to just be using this to give you an operation every five minutes?. If so, remember the hardware RTCC, returns originally a BCD value. Just set a flag, if the low byte of the minute value, is 0, or 5. Or, if you have got an external clock on timer0, run a counter in the RTCC interrupt, to give a 5 minute interval.
Quite a few other things 'worrying'. You have a function called 'shift_to_right' (not shown). You are aware that you can't 'shift' float values, except my multiplication?. This will take a lot of processor time. Always better results to use integers for anything involving moving values like this....
You have SPI initialised, but no sign you are using it.
Best Wishes |
|
|
mojsa2000
Joined: 18 May 2010 Posts: 78
|
|
Posted: Mon Jul 05, 2010 1:41 pm |
|
|
Hi
I found the problem.
The program was worked but in Proteus simulating there was wrong thing.
I used the SQW pin of DS1307 to make a pulse wave and connected it to micro to trig the RTCC int. But in Proteus SQW pin of ds1307 didn't work.
Thus I used a pulse wave and my program works now.
Anyway thanks for your attention.
|
|
|
|
|
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
|