|
|
View previous topic :: View next topic |
Author |
Message |
nicotec
Joined: 07 Nov 2008 Posts: 60
|
pic24f always in reset |
Posted: Sat Sep 11, 2010 8:10 am |
|
|
Hi everyone,
I need of your help since my pic24fj16ga002 run on autoreset when printf for floating is not commented; I attach here my code and I use version 4.110; Proteus simulation also include that Tad time is wrong about 31ns and minimum is 75ns but I have already checked wuith mplab sim and appear ok; thanks in advance and regards
Code: |
#include <24FJ16GA002.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES ICSP3 //ICD uses PGC3/PGD3 pins
#FUSES IOL1WAY //Allows only one reconfiguration of peripheral pins
#FUSES WINDIS //Watch Dog Timer in non-Window mode
#FUSES IESO //Internal External Switch Over mode enabled
//#FUSES FRC //Internal Fast RC Oscillator
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO //OSC2 is clock output
#FUSES NOPR //Pimary oscillaotr disabled
#FUSES I2C1SELD
#FUSES SOSC_SEC
#FUSES WUT_DEFAULT
#use delay(clock=32M,internal=8M)
#pin_select OC1=PIN_B0 //OUTPUT OF PWM PIN 4
#pin_select OC2=PIN_B1 //OUTPUT OF PWM PIN 5
#pin_select U1TX=PIN_B10 //RS-232 TX PIN 21
#pin_select U1RX=PIN_B11 //RS-232 RX PIN 22
#BYTE ODCB=0x02CE //INDIRIZZO DEFINIZIONE PULL-UP
#use rs232(UART1,baud=57600,parity=N,bits=8)
float Vx_rate=0;
int16 x_cnt=0;
#int_TIMER3
void TIMER3_isr(void)
{
output_toggle(PIN_B4);
//Reading channel 9 counts for X angle rate
set_adc_channel(9);
delay_us(20);
x_cnt = Read_ADC(); //read_adc(ADC_READ_ONLY);
}
#int_RDA
void RDA_isr(void)
{
//cmd=getc();
}
void main()
{
ODCB=0b00000011; //set pull-up pin
setup_compare(1,COMPARE_PWM | COMPARE_TIMER2 );
setup_compare(2,COMPARE_PWM | COMPARE_TIMER2 );
setup_spi( FALSE );
setup_spi2( FALSE );
setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
setup_timer2(TMR_DISABLED);
//setup_timer2(TMR_INTERNAL |TMR_DIV_BY_8 ,20000);
setup_timer4(TMR_DISABLED |TMR_DIV_BY_1 ,0);
setup_timer3(TMR_INTERNAL |TMR_DIV_BY_8,20000);
setup_timer5(TMR_DISABLED |TMR_DIV_BY_1 ,0);
setup_adc_ports( sAN9, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL | ADC_CLOCK_DIV_16| ADC_TAD_MUL_31);
//set_pwm_duty(1,781);
//set_pwm_duty(2,855);
setup_wdt(WDT_OFF);
disable_interrupts(INT_RDA);
printf("nel main\r");
enable_interrupts(INT_TIMER3);
while(true)
{
output_high(PIN_B3);
delay_ms(1);
output_low(PIN_B3);
delay_ms(1);
printf("%f\r",Vx_rate);
}
}
|
|
|
|
nicotec
Joined: 07 Nov 2008 Posts: 60
|
pic24 reset using prinf("%f"... |
Posted: Sat Sep 11, 2010 12:18 pm |
|
|
Please help me!!! |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sat Sep 11, 2010 1:38 pm |
|
|
.. _________________ Google and Forum Search are some of your best tools!!!!
Last edited by dyeatman on Mon Sep 13, 2010 6:03 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Sat Sep 11, 2010 2:58 pm |
|
|
As a comment, before trying anything else, Move the fuses, and clock definition above the library includes. Sequence should be:
Processor include
Fuses
Clock definition
RS232 definition
Other includes
code.
You _can_ often get away with including library files higher in the file, but if any of them use RS232 or timings, (both stdlib, and stdio do), the results will not work correctly....
Best Wishes |
|
|
nicotec
Joined: 07 Nov 2008 Posts: 60
|
still not working |
Posted: Sun Sep 12, 2010 2:14 am |
|
|
Thanks for your help, I moved include library but when I use a printf("%f... (floating point) pic reset forever; this is visible in simulation mode and confirmed because I'm testing hardware.
I do know if there is a problem with conversion type but it appear impossible to discover.
Any help will be appreciated.
Thanks in advance and regards
p.s.: here below the last code tested:
Code: |
#include <24FJ16GA002.h>
#DEVICE ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES ICSP3 //ICD uses PGC3/PGD3 pins
#FUSES IOL1WAY //Allows only one reconfiguration of peripheral pins
#FUSES WINDIS //Watch Dog Timer in non-Window mode
#FUSES NOIESO //Internal External Switch Over mode enabled
//#FUSES FRC //Internal Fast RC Oscillator
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO //OSC2 is clock output
#FUSES NOPR //Pimary oscillaotr disabled
#FUSES I2C1SELD
#FUSES SOSC_SEC
#FUSES WUT_DEFAULT
#use delay(clock=32M,internal=8M)
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#pin_select OC1=PIN_B0 //OUTPUT OF PWM PIN 4
#pin_select OC2=PIN_B1 //OUTPUT OF PWM PIN 5
#pin_select U1TX=PIN_B10 //RS-232 TX PIN 21
#pin_select U1RX=PIN_B11 //RS-232 RX PIN 22
#BYTE ODCB=0x02CE //INDIRIZZO DEFINIZIONE PULL-UP
#use rs232(UART1,baud=9600,parity=N,bits=8)
float Vx_rate=3.25;
int16 x_cnt=0;
#int_TIMER3
void TIMER3_isr(void)
{
output_toggle(PIN_B4);
//Reading channel 9 counts for X angle rate
set_adc_channel(9);
delay_us(20);
x_cnt = Read_ADC(); //read_adc(ADC_READ_ONLY);
}
#int_RDA
void RDA_isr(void)
{
//cmd=getc();
}
void main()
{
ODCB=0b00000011; //set pull-up pin
setup_compare(1,COMPARE_PWM | COMPARE_TIMER2 );
setup_compare(2,COMPARE_PWM | COMPARE_TIMER2 );
setup_spi( FALSE );
setup_spi2( FALSE );
setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
setup_timer2(TMR_DISABLED);
//setup_timer2(TMR_INTERNAL |TMR_DIV_BY_8 ,20000);
setup_timer4(TMR_DISABLED |TMR_DIV_BY_1 ,0);
setup_timer3(TMR_INTERNAL |TMR_DIV_BY_8,20000);
setup_timer5(TMR_DISABLED |TMR_DIV_BY_1 ,0);
setup_adc_ports( sAN9, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31);
//set_pwm_duty(1,781);
//set_pwm_duty(2,855);
setup_wdt(WDT_ON);
disable_interrupts(INT_RDA);
printf("nel main\r");
enable_interrupts(INT_TIMER3);
while(true)
{
output_high(PIN_B3);
delay_ms(10);
output_low(PIN_B3);
delay_ms(10);
printf("%f\r",Vx_rate);
}
}
|
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Sep 12, 2010 2:18 am |
|
|
Generally, the reset reason can be determined with PIC processors. Most likely, it's an unhandled trap interrupt. There are previous discussions at CCS forum about how to monitor unexpected traps. A known issue is stack overflow with float arithmetic, although your code seems too small to me to cause stack overflow. But you can try the respective suggestions (increasing the assigned stack) for test.
Most problems of this kind reveal when running the code under a hardware debugger in MPLAB.
P.S.: I forgot to mention, that I run your first code example in MPLAB SIM and didn't see the reset. But I wasn't sure if it depends on certain input conditions. Also I used most recent PCD V4.112, there may be a change. |
|
|
nicotec
Joined: 07 Nov 2008 Posts: 60
|
increase stack |
Posted: Sun Sep 12, 2010 4:16 am |
|
|
Could You explain how to increase the stack and verify it?
Thanks. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Sep 12, 2010 4:42 am |
|
|
Sorry, I'm a bit busy with my projects right now. Is it asking too much to search the forum for previous discussions or consult the manual? There's a #build(stack= xxx) statement. |
|
|
nicotec
Joined: 07 Nov 2008 Posts: 60
|
ok, tanks |
Posted: Sun Sep 12, 2010 11:21 am |
|
|
Ok, thanks for your help
Regards |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon Sep 13, 2010 2:04 am |
|
|
In your initial code you turned the WDT OFF, now you are turning it on without resetting it within your while loop:-
Code: |
setup_wdt(WDT_ON); // <<<<<<<<<<<<<<<<<<<<<
disable_interrupts(INT_RDA);
printf("nel main\r");
enable_interrupts(INT_TIMER3);
while(true)
{
output_high(PIN_B3);
delay_ms(10);
output_low(PIN_B3);
delay_ms(10);
printf("%f\r",Vx_rate);
}
|
Even if you put a WDT reset in your loop you may find the printf is taking too long to execute because it is converting the float to ascii. You havn't specified the WDT timeout anywhere so I think it defaults to the shortest time. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Sep 13, 2010 2:14 am |
|
|
Quote: | In your initial code you turned the WDT OFF, now you are turning it on without resetting it within your while loop |
Right. You can use restart_wdt for automatic reset. In the originally posted code, the watchdogg has been turned off, by the way. So I wonder what you intend here.
Code: | #use delay(clock=32M,internal=8M,restart_wdt) |
|
|
|
nicotec
Joined: 07 Nov 2008 Posts: 60
|
probaby printf("%f... is my problem |
Posted: Mon Sep 13, 2010 12:24 pm |
|
|
Thanks for your suggestion, I checked the code and now I have it running ok only when the line "printf("%f\r",Vx_rate);" in the while is commented otherwise the pic reset always, so probably I have some problem with printf; I don't know if %f is referenced to float32 or float64.
Any suggestion will be appreciated.
Thanks and regards.
p.s.: here attached code revised
Code: |
#include <24FJ16GA002.h>
#DEVICE ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES ICSP3 //ICD uses PGC3/PGD3 pins
#FUSES IOL1WAY //Allows only one reconfiguration of peripheral pins
#FUSES WINDIS //Watch Dog Timer in non-Window mode
#FUSES NOIESO //Internal External Switch Over mode enabled
//#FUSES FRC_PLL //Internal Fast RC Oscillator
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO //OSC2 is clock output
#FUSES NOPR //Pimary oscillaotr disabled
#FUSES I2C1SELD
#FUSES SOSC_SEC
#FUSES WUT_DEFAULT
#use delay(clock=32M,internal=8M)
//#include <string.h>
//#include <stdlib.h>
#include <stdio.h>
#pin_select OC1=PIN_B0 //OUTPUT OF PWM PIN 4
#pin_select OC2=PIN_B1 //OUTPUT OF PWM PIN 5
#pin_select U1TX=PIN_B10 //RS-232 TX PIN 21
#pin_select U1RX=PIN_B11 //RS-232 RX PIN 22
#BYTE ODCB=0x02CE //INDIRIZZO DEFINIZIONE PULL-UP
#use rs232(UART1,baud=9600,parity=N,bits=8)
float64 Vx_rate=0;
int16 x_cnt=0;
#int_TIMER3
void TIMER3_isr(void)
{
output_toggle(PIN_B4);
//Reading channel 9 counts for X angle rate
set_adc_channel(9);
delay_us(20);
x_cnt = Read_ADC(); //read_adc(ADC_READ_ONLY);
delay_us(50);
Vx_rate=(float64)x_cnt;
}
#int_RDA
void RDA_isr(void)
{
//cmd=getc();
}
void main()
{
ODCB=0b00000011; //set pull-up pin
setup_compare(1,COMPARE_PWM | COMPARE_TIMER2 );
setup_compare(2,COMPARE_PWM | COMPARE_TIMER2 );
setup_spi( FALSE );
setup_spi2( FALSE );
setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
setup_timer2(TMR_DISABLED);
setup_timer2(TMR_INTERNAL |TMR_DIV_BY_8 ,20000);
setup_timer4(TMR_DISABLED |TMR_DIV_BY_1 ,0);
setup_timer3(TMR_INTERNAL |TMR_DIV_BY_8,20000);
setup_timer5(TMR_DISABLED |TMR_DIV_BY_1 ,0);
setup_adc_ports( sAN9, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31);
set_pwm_duty(1,781);
set_pwm_duty(2,855);
disable_interrupts(INT_RDA);
printf("nel main\r");
enable_interrupts(INT_TIMER3);
while(true)
{
/*output_high(PIN_B3);
delay_ms(10);
output_low(PIN_B3);
delay_ms(10);*/
printf("%f\r",Vx_rate); //if this line commented no reset
}
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Sep 13, 2010 3:22 pm |
|
|
A general comment: when posting code, keep the code as small and clean as possible. This makes it easier for us to read your program and you will get more and better responses.
For example there are:
- 6 lines of code in comment. Remove these.
- INT_RDA is not used so remove the 4 lines of code associated with this
- You are disabling and then enabling Timer 2 when only enabling would have been enough.
- Does your error occur when the PWM code is removed? If yes, then your program can be stripped down even more.
- Same for comparator and all non-used timers.
- What happens when you replace the code for AD conversion by a fixed constant? The program then becomes smaller again.
By removing all this obsolete code it becomes more clear where the real problem is and everybody can focus on that.
Code: | printf("%f\r",Vx_rate); //if this line commented no reset
| A bug here is that your code is accessing a floating point variable that will also be modified by the interrupt routine at unpredictable moments. It is very well possible the print routine is busy converting the float to ASCII when the Timer3 interrupt fires.
In situations like this it is required to disable the interrupts while accessing the shared data variables.
Code: | disable_interrupts(INT_TIMER3);
printf("%f\r",Vx_rate); //if this line commented no reset
enable_interrupts(INT_TIMER3) |
In order to disable the interrupt as short as possible this can be improved by copying the float variable to a temporary variable: Code: | float64 temp;
disable_interrupts(INT_TIMER3);
temp = Vx_rate;
enable_interrupts(INT_TIMER3)
printf("%f\r", temp); //if this line commented no reset
|
|
|
|
nicotec
Joined: 07 Nov 2008 Posts: 60
|
Ok, suggestion but... |
Posted: Tue Sep 14, 2010 12:24 am |
|
|
Hi, thanks for your suggestion that I have applied but the following error occured during MPLAB simulation:
CORE-E0001: Trap due to stack error, occurred from instruction at 0x0002b0
CORE-E0003: Trap due to unimplemented RAM memory access, occurred from instruction at 0x0002b0
CORE-E0003: Trap due to unimplemented RAM memory access, occurred from instruction at 0x0002b0
CORE-E0003: Trap due to unimplemented RAM memory access, occurred from instruction at 0x000216
CORE-E0003: Trap due to unimplemented RAM memory access, occurred from instruction at 0x000216
CORE-E0004: Trap due to unimplemented FLASH memory access, occurred from instruction at 0x000216
CORE-E0004: Trap due to unimplemented FLASH memory access, occurred from instruction at 0x000216
CORE-E0004: Trap due to unimplemented FLASH memory access, occurred from instruction at 0x000216
Any help will be appreciated, thanks in advance and regards. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Sep 14, 2010 12:31 am |
|
|
Unfortunately, we get new code versions presented which each post. Using float interrupt is a new and actually dubious achievement of the latest version. But it hasn't been there originally, so it should be expected, that it's not primarly causing the reset.
ckielstra has pointed out the problem of data consistency across interrupts. But it can't explain spontaneous resets, I think. Float processing in interrupts would however tighten the stack utilization.
I would like to emphasize too the demand for minimal and clear examples, that allow to reproduce the problem.
P.S.: After the first fatal error in MPLAB simulation, the succeeding can be simply ignored. You may want to find out what's the nature of the stack error by reviewing the assmembly code. Apart from stack overflows caused by too low stack assingment, there may be also a compiler bug behind it. Did you already try to increase the stack assignment?
P.P.S.: Not too surprizing, I found that the stack error in simulation can be abandoned by increasing the stack to 256, but also by commenting the floating point operation from interrupt. |
|
|
|
|
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
|