CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

problem with "printf float" in dspic30f4013

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
alirezatkh2



Joined: 06 Feb 2015
Posts: 3

View user's profile Send private message

problem with "printf float" in dspic30f4013
PostPosted: Fri Feb 06, 2015 8:31 am     Reply with quote

hi everybody.
sometimes when I use printf function for float variables, the MCU has been reseted. for example in the below code when I comment "printf("e:%f\r",e); " everything works properly but when I use it my MCU will reset repeatedly.
I don't know why? Please help....

Code:

#include <30F4013.h>

#device adc=12                 //Use ADC as 12 Bits

#include <stdlib.h>            //Include Serial functions

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD

#FUSES HS2_PLL16//, PR_PLL        //Primary Oscillator with PLL x16 Div /2  **

//Crystal: 14.745600 with PLLx16 /2 => 117964800 Hz
#use delay(clock=117964800)

#use fast_io (B)
#use fast_io (D)

#use rs232(UART1,baud=115200,parity=N,bits=8,stream=A)

signed int16 adc=0;
float e=0;
//-------------------------------------Timers Interrupts------------------------
#int_TIMER1
void  TIMER1_isr(void)
{
      output_high(PIN_D2);
     
      set_adc_channel(0);    //sets the next channel that should be read.
      delay_us(10);          //it is good for most applications
      adc=read_adc();        //reads the value of the setted channel
     
      puts("\r\r\r");
      printf("adc:%Ld\r",adc);       
     
      e=1904-adc;
           
      printf("e:%f\r",e);     
     
      output_low(PIN_D2);
}

void main()
{   
   set_tris_b(0xffff);
   output_b(0x0000);   
     
   set_tris_d(0x0000);
   output_d(0x0000);   
   
   setup_adc(ADC_CLOCK_DIV_16 | ADC_TAD_MUL_8);
   setup_adc_ports(sAN0 | VSS_VDD);

   setup_timer1(TMR_INTERNAL|TMR_DIV_BY_64,0xFFF);  //8.88 ms   
   
   output_high(PIN_D2);
   delay_ms(1000);
   output_low(PIN_D2);

   puts("Start\r");
       
   enable_interrupts(INT_TIMER1);   
   enable_interrupts(INTR_GLOBAL);
 
   while(TRUE)
   {     
   
   }

}


ver 5.012
win 7 x64
pickit2 programmer

Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Fri Feb 06, 2015 9:50 am     Reply with quote

Approach it completely differently. There are several potential problems.
Code:

#include <30F4013.h>

#device adc=12                 //Use ADC as 12 Bits

#include <stdlib.h>            //Include Serial functions

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD

#FUSES HS2_PLL16//, PR_PLL        //Primary Oscillator with PLL x16 Div /2  **
#build (stack=256)
//Crystal: 14.745600 with PLLx16 /2 => 117964800 Hz
#use delay(clock=117964800)

#use fast_io (B)
#use fast_io (D)

#use rs232(UART1,ERRORS,baud=115200,parity=N,bits=8,stream=A,TRANSMIT_BUFFER=32,TXISR)

#define ADC_CLOCK_DIV_40 40
signed int16 adc=0;
int1 have_rdg=FALSE;

//-------------------------------------Timers Interrupts------------------------
#int_TIMER1
void  TIMER1_isr(void)
{   
   adc=read_adc(ADC_READ_ONLY); //reads the ADC value
   read_adc(ADC_START_ONLY); //start the next reading.   
   have_rdg=TRUE;
}

void main()
{   
   float e;
   set_tris_b(0xffff);
   output_b(0x0000);   
     
   set_tris_d(0x0000);
   output_d(0x0000);   
   
   setup_adc(ADC_CLOCK_DIV_40 | ADC_TAD_MUL_8);
   //You are sampling the ADC too fast. Needs 668nSec for single sampling
   //stupidly the CCS setup does not allow the intermediate sampling intevals
   //so have defined one.
   setup_adc_ports(sAN0 | VSS_VDD);
   set_adc_channel(0);
 
   output_high(PIN_D2);
   delay_ms(999);
   read_adc(ADC_START_ONLY); //make sure the ADC has acquired before
   //the timer triggers
   delay_ms(1);
   output_low(PIN_D2);

   puts("Start\r");
   setup_timer1(TMR_INTERNAL|TMR_DIV_BY_64,0xFFF);  //8.88 ms   
       
   enable_interrupts(INT_TIMER1);   
   enable_interrupts(INTR_GLOBAL);
 
   while(TRUE)
   {     
       if (have_rdg)
       {
           //You were using prints and delays both inside and outside
           //the interrupt - not a good idea.
           have_rdg=FALSE;
           output_high(PIN_D2);
           e=1904-adc;
           //why use a float for an integer?.     
           fprintf(A,"\r\r\radc:%Ld \re:%5.0f\r",adc,e);           
           
           output_low(PIN_D2);
       }
   }
}


Now you could do this without even using the timer interrupt (trigger the ADC from a timer event instead). However several things:
First 5.012, may have a fault with serial TX, if interrupts are not used. I have bypassed that by using the software serial buffer. The fault is there in 5.013 (the nearest I have).
Then 5.012, may be early enough that it doesn't expand the stack to 256bytes. This was a common problem on the older compilers, with the stack not being large enough if floating point operations were used in subroutines. Have expanded the stack.
Then you are trying to clock the ADC too fast. Using just one sample and hold, you need 668nSec.
The general rule is _do the least possible in an interrupt_.
I'm letting the ADC read while the code goes on, rather than 'waiting' for the ADC. It samples between each interrupt.
alirezatkh2



Joined: 06 Feb 2015
Posts: 3

View user's profile Send private message

PostPosted: Fri Feb 06, 2015 2:04 pm     Reply with quote

Thank you for your notes.
My problem was solved and stack size was the main problem.

I have another problem with fuses.

When I program the code in MCU, pickit2 say "verification of configuration failed" what is my problem?

In old versions of ccs like 4.084 I could add #fuses PR_PLL then I didn't have any problems but in new version 5.012 there is no fuses such as PR_PLL and if I use this compiler got errors. I don't know what alternative I can use to solve it.

Code is as same as first dialog of Topic!
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Sat Feb 07, 2015 2:06 am     Reply with quote

Use:

#use delay(clock=117964800, crystal=14745600)

which has the same effect
alirezatkh2



Joined: 06 Feb 2015
Posts: 3

View user's profile Send private message

PostPosted: Sat Feb 07, 2015 12:10 pm     Reply with quote

Ttelmah wrote:
Use:

#use delay(clock=117964800, crystal=14745600)

which has the same effect



again compiler got errors:" Option invalid No PLL option"

I think this version is not stable and I should back to old versions.
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Sat Feb 07, 2015 12:27 pm     Reply with quote

Or to a modern version.....

5.012, was close to the earliest working V5 version. The earliest V5 version I actually kept was 5.009, and the earliest I found I could use reliably 5.016.
Generally when CCS releases anything, you can reckon on needing to wait a good few versions before 90% of things work. I'd say you have found a part where V5 has problems on this early version...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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