View previous topic :: View next topic |
Author |
Message |
spilz
Joined: 30 Jan 2012 Posts: 219
|
[closed] Big array issue ??? |
Posted: Tue Dec 06, 2016 7:44 am |
|
|
hello,
I'm working on a project using 18F47J53, and I get Something very Strange :
Here is an example of my code : Code: | #include <18F47J53.h>
#device ADC=16
#fuses HSPLL,SOSC_HIGH,NOCLOCKOUT,NOFCMEN
#fuses WDT128,PLL1,PLLEN,STVREN,NODEBUG,NOCPUDIV
#use delay(clock=48 MHz,crystal=4 MHz,restart_wdt)
#define LED_G_pin pin_B2
#define LED_R_pin pin_D4
#define LED_G(x) output_bit(LED_G_pin,x)
#define LED_R(x) output_bit(LED_R_pin,x)
// int DISPLAY [1024];
int32 TIMER0_Seconde = 0;
#INT_TIMER0
void TIMER0_isr(void)
{
set_timer0(18661); // 1s overflow
TIMER0_Seconde++;
}
void blink(){
LED_R(1);
delay_ms(100);
LED_R(0);
delay_ms(100);
}
int sequence_B_state = -1;
int32 sequence_B_Seconde_last = 0;
void sequence_B(void){
int32 delta = 0;
if(TIMER0_Seconde<sequence_B_Seconde_last)
sequence_B_Seconde_last = TIMER0_Seconde;
delta = (TIMER0_Seconde-sequence_B_Seconde_last);
if(delta >= 7){
blink();
sequence_B_Seconde_last = TIMER0_Seconde;
}
}
void main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //1,4 s overflow
setup_wdt(WDT_OFF);
LED_R(0);
LED_G(0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
sequence_B_state = 1;
while(true){
restart_wdt();
// Sequences
sequence_B();
}
reset_cpu();
}
|
with this code, the red led should blink every 7s.
like this it works.
bit if I uncomment: Code: | int DISPLAY [1024]; |
the led become crazy
So I guess the issue is from using a big array, but I don't understand what is the problem here ...
someone has an idea ?
someone else experiment this issue ?
I'm using V5.064
thanks for your help
Last edited by spilz on Wed Dec 07, 2016 7:57 am; edited 1 time in total |
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 8:25 am |
|
|
by the way, this code never works on V5.008
I don't know why ... |
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 8:41 am |
|
|
it's OK for or less
if it can help ... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Tue Dec 06, 2016 9:20 am |
|
|
There is a generic problem with what you are trying to do. Maths on a 32bit value that is updated by an interrupt. If an interrupt occurs during the maths, the results will be totally screwed.
You need to either disable interrupts during the maths, or copy the value to a local version, and verify this is right before proceeding.
Why it should change with the array, is probably 'incidental'. I'd suspect the variables are being placed into a later bank, and so become slower to access, and increase the likelyhood of problems. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Tue Dec 06, 2016 9:29 am |
|
|
re V5.008 was real early and had a lot of 'bugs' in it.... |
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 9:30 am |
|
|
What do you mean by "maths" ?
I don't understand what you suggest to do to verify with local variable |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Tue Dec 06, 2016 9:47 am |
|
|
I have to agree with Temtronic. 5.008, was 'beta' at best.
Unfortunately, it is also one of the 'ripped off' versions of CCS that is commonly on the web. Nasty suspicion that this may be a lot of your problems.
On variables, anything larger than an int8, must always be treated for anything arithmetic (this includes comparisons), as if it may change during the maths.
Code: |
int32 local_copy;
do {
local_copy=value_updated_by_interrupt;
} while (local_copy!=value_updated_by_interrupt);
//or
disable_interrupts(GLOBAL);
local_copy=value_updated_by_interrupt; //or do the maths here
enable_interrupts(GLOBAL);
|
|
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 9:53 am |
|
|
Oh i see,
I understand better
I'm going to try it |
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 10:03 am |
|
|
I tried both, but Nothing works :( |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Tue Dec 06, 2016 10:14 am |
|
|
Does that include having changed the compiler?.
I'm very puzzled, since in another thread you talk about using a 5.05x version. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 10:19 am |
|
|
the PC I'm using right now has V5.064 (no more V5.05x)
I tried V5.008 on an other PC from a friend, just to test |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 06, 2016 11:13 am |
|
|
Quote: | I tried both, but Nothing works :( |
I think you should post your revised program. We don't know for sure
if you implemented Ttelmah's suggestion correctly. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 12:34 pm |
|
|
I tried this : Code: | #include <18F47J53.h>
#device ADC=16
#fuses HSPLL,SOSC_HIGH,NOCLOCKOUT,NOFCMEN
#fuses WDT128,PLL1,PLLEN,STVREN,NODEBUG,NOCPUDIV
#use delay(clock=48 MHz,crystal=4 MHz,restart_wdt)
#define LED_G_pin pin_B2
#define LED_R_pin pin_D4
#define LED_G(x) output_bit(LED_G_pin,x)
#define LED_R(x) output_bit(LED_R_pin,x)
int DISPLAY [1024];
int32 TIMER0_Seconde = 0;
#INT_TIMER0
void TIMER0_isr(void)
{
set_timer0(18661); // 1s overflow
TIMER0_Seconde++;
}
void blink(){
LED_R(1);
delay_ms(100);
LED_R(0);
delay_ms(100);
}
int sequence_B_state = -1;
int32 sequence_B_Seconde_last = 0;
void sequence_B(void){
int32 delta = 0;
int32 TIMER0_Seconde_loc;
do{
TIMER0_Seconde_loc = TIMER0_Seconde;
}while(TIMER0_Seconde_loc != TIMER0_Seconde);
if(TIMER0_Seconde_loc<sequence_B_Seconde_last)
sequence_B_Seconde_last = TIMER0_Seconde_loc;
delta = (TIMER0_Seconde_loc-sequence_B_Seconde_last);
if(delta >= 7){
blink();
sequence_B_Seconde_last = TIMER0_Seconde_loc;
}
}
void main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //1,4 s overflow
setup_wdt(WDT_OFF);
LED_R(0);
LED_G(0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
sequence_B_state = 1;
while(true){
restart_wdt();
sequence_B();
}
reset_cpu();
}
|
and this : Code: | #include <18F47J53.h>
#device ADC=16
#fuses HSPLL,SOSC_HIGH,NOCLOCKOUT,NOFCMEN
#fuses WDT128,PLL1,PLLEN,STVREN,NODEBUG,NOCPUDIV
#use delay(clock=48 MHz,crystal=4 MHz,restart_wdt)
#define LED_G_pin pin_B2
#define LED_R_pin pin_D4
#define LED_G(x) output_bit(LED_G_pin,x)
#define LED_R(x) output_bit(LED_R_pin,x)
int DISPLAY [1024];
int32 TIMER0_Seconde = 0;
#INT_TIMER0
void TIMER0_isr(void)
{
set_timer0(18661); // 1s overflow
TIMER0_Seconde++;
}
void blink(){
LED_R(1);
delay_ms(100);
LED_R(0);
delay_ms(100);
}
int sequence_B_state = -1;
int32 sequence_B_Seconde_last = 0;
void sequence_B(void){
int32 delta = 0;
int32 TIMER0_Seconde_loc;
disable_interrupts(GLOBAL);
TIMER0_Seconde_loc = TIMER0_Seconde;
enable_interrupts(GLOBAL);
if(TIMER0_Seconde_loc<sequence_B_Seconde_last)
sequence_B_Seconde_last = TIMER0_Seconde_loc;
delta = (TIMER0_Seconde_loc-sequence_B_Seconde_last);
if(delta >= 7){
blink();
sequence_B_Seconde_last = TIMER0_Seconde_loc;
}
}
void main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //1,4 s overflow
setup_wdt(WDT_OFF);
LED_R(0);
LED_G(0);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
sequence_B_state = 1;
while(true){
restart_wdt();
sequence_B();
}
reset_cpu();
}
|
don't forget I have no issue if I comment Code: | int DISPLAY [1024]; |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 06, 2016 3:17 pm |
|
|
I'm trying to duplicate your problem in hardware.
Can you tell me what rate or pattern "LED_R_pin" is supposed to blink at ?
Describe it in detail, because I'm getting strange results with the array
commented out.
Also, I have to go out now and won't be back for 3-4 hours. If it isn't
fixed during that time, I'll work on it when I get back. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 219
|
|
Posted: Tue Dec 06, 2016 3:33 pm |
|
|
It's :
pin -> resistor 100 ohm -> led red -> ground |
|
|
|