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

printf not working with for loop

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



Joined: 18 Apr 2008
Posts: 9

View user's profile Send private message

printf not working with for loop
PostPosted: Thu May 20, 2010 8:12 am     Reply with quote

When I add for loops to my code ALL my printf functions cease to function. Even the printf functions that come before the for loops. But the rest of the code works fine. If I remove the for loops, the printf functions work.

What is going on?!


This is a fragment of the main code .. it receives some values on interrupt and sets some command flags that drives the case structure.


Code:
#include <C:\Program files\PICC\devices\16f876a.H>
#include <C:\Program files\PICC\drivers\stdio.h>
#fuses    HS,NOWDT,NOPROTECT,NOLVP, NOBROWNOUT
#use    delay(clock=20000000)
#use   RS232(Baud=9600,XMIT=PIN_C6,RCV=PIN_C7, ERRORS)


void main(void)
{
   current_state = STOPPED;
   initialise_pic();         
   pulse_width = 40;       
         printf("\tTest \n\n\r");

while (true)
{
   if(command_status)
     {
   get_pc_command();   
   command_status = NO_COMMAND;
    } 
   
                switch(current_state)
   {
   printf("\t current_state %s\n\n\r", current_state);

   case STIMULATING :      
   
                printf("\t Stimulating   \n\n\r");      
   output_high(PIN_C2);      //Blue LED
   
   output_high(PIN_B7);      //test pin
   for(i=0;i<pulse_width;++i)
   {
   delay_us(1);
   }
   output_low(PIN_B7);         //test pin
   for(n=0;n<off_time;++n)
   {
   delay_us(1);
   }
   break;
   
   case STOPPED :
   printf("\t Stopped \n\n");
   output_low(PIN_B7);         //test pin
   output_low(PIN_C2);         //Blue LED

   break;
      
   case ILLEGAL_COMMAND :
   printf("\t illegal command \n\n\r");
   break;
   }
   
}
Graham Webb



Joined: 18 Apr 2008
Posts: 9

View user's profile Send private message

PostPosted: Thu May 20, 2010 8:26 am     Reply with quote

I didn't have data direction registers! But how that should be altered with for loops defeats me.
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu May 20, 2010 8:32 am     Reply with quote

You should post a _compilable_ code in case we want to check things out ourselves. You don't show what initialise_pic() does. This code may not be necessary but I always insert some initializing code:

Code:
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);


Plus, I would have an interrupt routine for your serial port:

Code:
#int_RDA
RDA_isr()
{

}


That may be why things hang up because you don't have that ISR defined.

Ronald
Graham Webb



Joined: 18 Apr 2008
Posts: 9

View user's profile Send private message

PostPosted: Thu May 20, 2010 8:41 am     Reply with quote

That was a fragment, this is the complete code. The problem still exists :-(

Not very tidy, but I think it's all there ..



Code:

#include <C:\Program files\PICC\devices\16f876a.H>
#include <C:\Program files\PICC\drivers\stdio.h>

#fuses    HS,NOWDT,NOPROTECT,NOLVP, NOBROWNOUT
#use    delay(clock=20000000)
#use   RS232(Baud=9600,XMIT=PIN_C6,RCV=PIN_C7, BRGH1OK)

/***************************************************************************************************
FUNCTION PROTOTYPES
***************************************************************************************************/
void initialise_pic(void);
void get_pc_command(void);
int decimal_adjust_int(void);
long decimal_adjust_int16(void);
long decimal_adjust_int32(void);
/***************************************************************************************************
DECLARATIONS
***************************************************************************************************/
#define GD00   PIN_C0   //pin C0      = out
#define GD02   PIN_C1   //pin C1      = out
#define SPI_CS   PIN_C2   //pin C2      = out
#define SPI_CLK   PIN_C3   //pin C3      = out
#define SPI_DI   PIN_C4   //pin C4      = out
#define SPI_DO   PIN_C5   //pin C5      = out
#define TX      PIN_C6   //pin C6      = out RS232 Tx
#define RX      PIN_C7   //pin C7      = inp RS232 Rx

#define PORTA_DIRECTION 0b00000000       
#define PORTB_DIRECTION 0b00000000    
#define PORTC_DIRECTION 0b00000001      

SET_TRIS_A(PORTA_DIRECTION);
SET_TRIS_B(PORTB_DIRECTION);
SET_TRIS_C(PORTC_DIRECTION);
   
char command_string[8];

byte status          = 0;
#BIT COMMAND_STATUS    = status.0   

int current_state;
#define STIMULATING       0
#define STOPPED          1
#define ILLEGAL_COMMAND      3

#define NEW_COMMAND         1
#define NO_COMMAND         0

#define ON   1
#define OFF   0

int montage;      //m
int intensity;       //i
long pulse_width;   //p
long off_time;       //b
long i, n;


/***************************************************************************************************
FUNCTION main
***************************************************************************************************/
void main(void)
{
   current_state = STOPPED;
   initialise_pic();         
   pulse_width = 40;       

   while (true)
   {

      if(command_status)
        {
          get_pc_command();   
          command_status = NO_COMMAND;
         } 

      switch(current_state)
      {
         printf("\t current_state %s\n\n\r", current_state);

         case STIMULATING :      
            printf("\t Stimulating   \n\n\r");      
            output_high(PIN_C2);      //Blue LED
            
            output_high(PIN_B7);      //test pin
            for(i=0;i<pulse_width;++i)
               {
               delay_us(1);
               }
            output_low(PIN_B7);         //test pin
            for(n=0;n<off_time;++n)
               {
               delay_us(1);
               }
         break;
   
         case STOPPED :
         //   printf("\t Stopped \n\n");
            output_low(PIN_B7);         //test pin
            output_low(PIN_C2);         //Blue LED

         break;
      
         case ILLEGAL_COMMAND :
            printf("\t illegal command \n\n\r");
         break;
      }
   
   }
}

/***************************************************************************************************
FUNCTION    :    ISRs
Arguments   :   none
Return Value:   none
Purpose      :    handles interrupts
***************************************************************************************************/
#INT_RDA
RS232_receive()    
{
   output_high(PIN_C1);      //Green LED
   gets(command_string);   
   command_status = NEW_COMMAND;
   output_low(PIN_C1);         //Green LED
}
/***************************************************************************************************
FUNCTION    :     get_pc_command
Arguments   :   none
Return Value:   none
Purpose      :    

start       s
stop        x
intensity   ixxx     int   
pulse width pxxxxx   long
montage    mxxxxx   long
off time     bxxxxxx long long?   
***************************************************************************************************/
void get_pc_command(void)
{

   switch(command_string[0])
    {
         case 's' :         
            current_state = STIMULATING;
         printf("\t state change stimulating \n\n\r");
         COMMAND_STATUS = NO_COMMAND;
         break;
       
         case 'x' :            
            current_state = STOPPED;
         printf("\t state change stopped \n\n\r");
         COMMAND_STATUS = NO_COMMAND;
         break;

      case 'm' :         
          montage = decimal_adjust_int();
         printf("\t new value montage %i\n\n\r", montage);
         COMMAND_STATUS = NO_COMMAND;
       break;

      case 'i' :   
            intensity = decimal_adjust_int();
         printf("\t new value intensity %i\n\n\r", intensity);
         COMMAND_STATUS = NO_COMMAND;
       break;

      case 'p' :   
          pulse_width = decimal_adjust_int16();
         printf("\t new value pulse_width %lu\n\n\r", pulse_width);
         COMMAND_STATUS = NO_COMMAND;
       break;

      case 'b' :         
          off_time = decimal_adjust_int32();
         printf("\t new value off time %lu\n\n\r", off_time);
         COMMAND_STATUS = NO_COMMAND;
       break;
      
      default :
            current_state = ILLEGAL_COMMAND;
         printf("\t state change ILLEGAL_COMMAND \n\n\r");
         COMMAND_STATUS = NO_COMMAND;
        break;
    }
}
/***************************************************************************************************
FUNCTION    :    decimal_adjust_int
Arguments   :   3 chars
Return Value:   int8
Purpose      :    used for intensity
***************************************************************************************************/
int decimal_adjust_int(void)
{
      return ((command_string[1] - 0x30) * 100) +
             ((command_string[2] - 0x30) * 10) +
              (command_string[3] - 0x30);
}
/***************************************************************************************************
FUNCTION    :    decimal_adjust_int16
Arguments   :   5 chars
Return Value:   int16
Purpose      :    used for pulse_width
***************************************************************************************************/
long decimal_adjust_int16(void)
{
   long temp;
   long temp2 = 0;
   
   temp = command_string[1] - 0x30;
   temp2 += temp * 10000;
   temp = command_string[2] - 0x30;
   temp2 += temp * 1000;
   temp = command_string[3] - 0x30;
   temp2 += temp * 100;
   temp = command_string[4] - 0x30;
   temp2 += temp * 10;   
   temp = command_string[5] - 0x30;
   temp2 += temp;
   return(temp2);
}
/***************************************************************************************************
FUNCTION    :    decimal_adjust_int32
Arguments   :   6 chars
Return Value:   int32
Purpose      :    Used for off_time
***************************************************************************************************/
long decimal_adjust_int32(void)
{
   long temp3;
   long temp4 = 0;
   
   temp3 = command_string[1] - 0x30;
   temp4 += temp3 * 100000;
   temp3 = command_string[2] - 0x30;
   temp4 += temp3 * 10000;
   temp3 = command_string[3] - 0x30;
   temp4 += temp3 * 1000;
   temp3 = command_string[4] - 0x30;
   temp4 += temp3 * 100;
   temp3 = command_string[5] - 0x30;
   temp4 += temp3 * 10;   
   temp3 = command_string[6] - 0x30;
   temp4 += temp3;
   return(temp4);
}
/***************************************************************************************************
FUNCTION    :    Initialise_PIC
Arguments   :   none
Return Value:   none
Purpose      :    Initialises PIC
***************************************************************************************************/
void initialise_pic(void)
{
   ENABLE_INTERRUPTS(GLOBAL);
   ENABLE_INTERRUPTS(INT_RDA);      

   printf("\t--------------------------   \n\r");
   printf("\tStimulator Controller       \n\r");
   printf("\t--------------------------   \n\r");
[/code]
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Thu May 20, 2010 8:50 am     Reply with quote

Does this work :-

Code:

   switch(current_state)
   {
   printf("\t current_state %s\n\n\r", current_state);

   case STIMULATING :     


Putting code between a switch statement and the first case ?

Could be a problem.

Is it all the for loops in your code that cuase a problem ?
Graham Webb



Joined: 18 Apr 2008
Posts: 9

View user's profile Send private message

PostPosted: Thu May 20, 2010 8:58 am     Reply with quote

Yes both.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri May 21, 2010 3:05 am     Reply with quote

What compiler version?.
The 'odd' thing, is that you can get the code to compile, with the printf, inside the switch statement.
This is 'invalid' syntactically, and if I try your code as posted, the compiler immediately complains about this....

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 21, 2010 5:19 am     Reply with quote

Just a few other issues, not related to your reported problem:

Code:
long decimal_adjust_int32(void)
In the CCS compiler a 'long' is an int16, not int32 as you intended. Result is that this function will wrong values for any input string larger than 65535.

Code:
SET_TRIS_A(PORTA_DIRECTION);
SET_TRIS_B(PORTB_DIRECTION);
SET_TRIS_C(PORTC_DIRECTION);
These are function calls and should be located inside a function and not at the global level where they are now.
Best is to remove these lines as the CCS compiler will automatically set the TRIS registers for you on every I/O operation. Setting the TRIS registers manually will save a bit of code space but this only works when you have the compiler directive '#use FAST_IO' at the start of your program.

Code:
#use   RS232(Baud=9600,XMIT=PIN_C6,RCV=PIN_C7, BRGH1OK)
It's been a long time I saw the BRGH1OK directive. It doesn't hurt to have it in here but it is a feature only used on a few old processor models with UART hardware errors. I doubt it has any effect in your program.

To avoid problems with the UART stalling on receive buffer overflow it is good practice to add the ERRORS directive to the RS232 line.

Code:
#INT_RDA
RS232_receive()   
{
   output_high(PIN_C1);      //Green LED
   gets(command_string);
This code has several problems:
1) gets() has no check on buffer overflows. If your input string is longer than 8 characters (including the terminating 0), then you will overwrite random memory.
2) gets() shouldn't be used inside an interrupt routine. As the name of an interrupt implies it should be an action to break out of normal program flow, do its thing, and then as soon as possible continue with the normal program flow. Receiving multiple bytes from a UART is _very_ slow from a computer speed of view. See the example program ex_sisr.c for an elegant method to buffer incoming data in the background.
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