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

Unexpected Reboot at PIC 16F876, Why ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rodorico



Joined: 14 Nov 2010
Posts: 8

View user's profile Send private message

Unexpected Reboot at PIC 16F876, Why ?
PostPosted: Sun Nov 14, 2010 2:17 pm     Reply with quote

Hi people, I have this problem and I don't know how to resolve it.

I'm executing this c code, and when I send some operations (*move (leftmove, forwardmove, rightmove, leftmovestop....)) at the rs232 from the PC to the PIC, normally when I do it faster (from the key PC), The PIC reboot, and I don't know why.

I attach my main function and the int_rda function:
Code:

void main()
{
   /* inicializacion de variables */
   duty_wheel_left = duty_stop;
   duty_wheel_right = duty_stop;
   next_duty_wheel_left = duty_stop;
   next_duty_wheel_right = duty_stop;

   /* configuramos interrupciones del timer2 */
   set_tris_b (0xF0); /* puerto b 0,1,2,3 out, others in */
   //set_timer2 (0);
   //set_timer0(0xFF);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_256); /* configuramos el timer 0*/
   setup_timer_2 (T2_DIV_BY_1, 0x63, 1); /* establece el timer2 para 10Khz */
   enable_interrupts (INT_RDA); /* habilitamos interrupciones rs232 */
   enable_interrupts (GLOBAL); /* habilitamos todas las interrupciones */
   
   printf("WELCOME");
   
   
   /* habilitamos interrupciones */
   //enable_interrupts (INT_RB); /* habilitamos interrupciones en el puerto B */
   //enable_interrupts (INT_TIMER0); /* habilitamos interrupciones del timer0 */
   //enable_interrupts (INT_TIMER2); /* habilitamos interrupciones del timer2 */
   
   
   /* inicializamos el valor de los pines */
   output_high (PIN_B1);
   output_high (PIN_B0);
   output_low (PIN_B2);
   high_b2 = false;
   manual_move = true;



   /* bucle infinito */
   while (true) {

      if (starts) {   

         read_tpa81(TPA81_ID);
         
         disable_interrupts(GLOBAL);
         printf("%C\n",setTermalScan);
         printf("%U,%U,%U,%U,%U,%U,%U,%U,%U\n", t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9]);
         enable_interrupts(GLOBAL);
         delay_ms(termalScanPeriod);
      }
   }
}


#int_RDA
interrupt_RS232 () {

   operation = getc();

   printf("Operacion recibida: %C\n", operation);


   // operation to move the robot forward
   else if (operation == forwardMove) {
      moving_forward =true;
      next_duty_wheel_left = duty_forward_left;
      next_duty_wheel_right = duty_forward_right;
   }

   // operation to move the robot to the backward
   else if (operation == backwardMove) {
      moving_backward =true;
      next_duty_wheel_left = duty_backward_left;
      next_duty_wheel_right = duty_backward_right;
   }

   // operation to move the robot to the left
   else if (operation == leftMove) {
      next_duty_wheel_left = duty_stop;
      next_duty_wheel_right = duty_forward_right;
   }

   // operation to move the robot to the right
   else if (operation == rightMove) {
      next_duty_wheel_left = duty_forward_left;
      next_duty_wheel_right = duty_stop;
   }

   // operation to move the robot forward
   else if (operation == forwardMoveStop) {
      moving_forward =false;
      if (moving_backward) {
         next_duty_wheel_left = duty_backward_left;
         next_duty_wheel_right = duty_backward_right;
      }
      else {
         next_duty_wheel_left = duty_stop;
         next_duty_wheel_right = duty_stop;
      }
   }

   // operation to move the robot to the backward
   else if (operation == backwardMoveStop) {
      moving_backward = false;
      if (moving_forward) {
         next_duty_wheel_left = duty_forward_left;
         next_duty_wheel_right = duty_forward_right;
      }
      else {
         next_duty_wheel_left = duty_stop;
         next_duty_wheel_right = duty_stop;
      }
     
   }

   // operation to move the robot to the left
   else if (operation == leftMoveStop) {
      if (moving_forward) {
         next_duty_wheel_left = duty_forward_left;
         next_duty_wheel_right = duty_forward_right;
      }
      else if (moving_backward) {
          next_duty_wheel_left = duty_backward_left;
         next_duty_wheel_right = duty_backward_right;
      }
      else {
         next_duty_wheel_left = duty_stop;
         next_duty_wheel_right = duty_stop;
      }
   }

   // operation to move the robot to the right
   else if (operation == rightMoveStop) {
      if (moving_forward) {
         next_duty_wheel_left = duty_forward_left;
         next_duty_wheel_right = duty_forward_right;
      }
      else if (moving_backward) {
         next_duty_wheel_left = duty_backward_left;
         next_duty_wheel_right = duty_backward_right;
      }
      else {
         next_duty_wheel_left = duty_stop;
         next_duty_wheel_right = duty_stop;
      }
   }

   // operation to stop moving the robot
   else if (operation == stopMove) {
      next_duty_wheel_left = duty_stop;
      next_duty_wheel_right = duty_stop;

   }

   // operation to kwon that the robot is alive
   else if (operation == heartbeat) {

   }

   // operation to start the vigilance
   else if (operation == start) {
      set_timer2 (0);
      set_timer0(0xFF);
      enable_interrupts(INT_RB);
      enable_interrupts(INT_TIMER2);
      starts = true;
   }
   
   // operation to stop the vigilance
   else if (operation == stop) {
      disable_interrupts(INT_RB);
      disable_interrupts(INT_TIMER0);
      disable_interrupts(INT_TIMER2);
      starts = false;
     
   }
   

}


Any Idea....
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Sun Nov 14, 2010 2:34 pm     Reply with quote

My first guess is that you have noise on the PIC power pins when you do the move commands.

Does it reset if you have your motors disconnected?
What chip are you using?
What are your fuse settings?
Do you have capacitors across (all of) the PIC power pins?
How is MCLR terminated?
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun Nov 14, 2010 3:49 pm     Reply with quote

Since you did not show all your code, one thing I see right off:

Code:
#int_RDA
interrupt_RS232 () {

   operation = getc();

   printf("Operacion recibida: %C\n", operation);

 


The printf in your interrupt routine can cause all
kinds of problems. You are using getc() to fetch one character then try to
PRINTF at least 19 characters immediately after. This will cause your
RS232 buffer to UART overflow and the PIC to hang. If you have the WDT
timer enabled you will get a reset.
_________________
Google and Forum Search are some of your best tools!!!!
rodorico



Joined: 14 Nov 2010
Posts: 8

View user's profile Send private message

PostPosted: Sun Nov 14, 2010 5:31 pm     Reply with quote

pmuldoon wrote:
My first guess is that you have noise on the PIC power pins when you do the move commands.

Does it reset if you have your motors disconnected?

yes it happens with the motors disconnected

Quote:
What chip are you using?

16f876

Quote:
What are your fuse settings?

Code:

#fuses XT,NOWDT, NOPROTECT, NOLVP, PUT, NOBROWNOUT
#use delay (clock = 4000000)
#use rs232 (baud = 9600, xmit = PIN_C6, rcv = PIN_C7)
#use I2C(master, sda=PIN_C4, scl=PIN_C3)


Quote:
Do you have capacitors across (all of) the PIC power pins?

No I don't have none capacitors.

Quote:
How is MCLR terminated?

watch it here
http://www.x-robotics.com/images/PIC16f876_3basic.gif


Hi pmuldoon, I answer at your quote

Any Idea ?
rodorico



Joined: 14 Nov 2010
Posts: 8

View user's profile Send private message

PostPosted: Sun Nov 14, 2010 5:40 pm     Reply with quote

dyeatman wrote:
Since you did not show all your code, one thing I see right off:

Code:
#int_RDA
interrupt_RS232 () {

   operation = getc();

   printf("Operacion recibida: %C\n", operation);

 


The printf in your interrupt routine can cause all
kinds of problems. You are using getc() to fetch one character then try to
PRINTF at least 19 characters immediately after. This will cause your
RS232 buffer to UART overflow and the PIC to hang. If you have the WDT
timer enabled you will get a reset.


Hi dyeatman,
mm I have enabled the Timer0 interrupts but not the WDT.
And the reset is not occur always that I send that printf.
Anyway tomorrow I'll try without that printf.

The configuration I have for the timer0 no enabled the WDT ?
Code:

#int_rb
interrupt_RB()
{

   /** Interrupcion del sensor de movimiento **/
   if (input(PIN_B6) && !timer_move_sensor) {

      timer_move_sensor = true;
      cicles_delay_move_sensor =    number_cicles_delay_move_sensor;
      enable_interrupts (INT_TIMER0);
     

      if (high_b2) {
         output_low(PIN_B2);
           high_b2 = false;
      }
      else {
         output_high(PIN_B2);
         high_b2 = true;
      }

      printf("%C\n", setMoveAlarm);

   }
   
   /** Interrupciones de los sensores de luz del siguelineas **/
   if (!input(PIN_B5) && !manual_move)
      next_duty_wheel_left = duty_stop;
   else if (input(PIN_B5) && !manual_move)
      next_duty_wheel_left = duty_forward_left;

   if (!input(PIN_B4) && !manual_move)
      next_duty_wheel_right = duty_stop;
   else if (input(PIN_B4) && !manual_move)
      next_duty_wheel_right = duty_forward_right;

   
}

and the configuration for the timer0:

void main()
{

 

   /* inicializacion de variables */
   duty_wheel_left = duty_stop;
   duty_wheel_right = duty_stop;
   next_duty_wheel_left = duty_stop;
   next_duty_wheel_right = duty_stop;

   /* configuramos interrupciones del timer2 */
   set_tris_b (0xF0); /* puerto b 0,1,2,3 out, others in */
   
   set_timer0(0xFF);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_256); /* configure timer0 to 16 ms */


Regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 14, 2010 9:18 pm     Reply with quote

It would be better if you posted a small, but complete test program that
shows the problem. You can probably cut out a large amount of your
code and still create a program that shows the problem. Try to do that.
Then post it. The program that you post should be compilable with no
errors. Test it before you post it. It must have the #include for the PIC,
and the #fuses, and the #use delay(), and all variable declarations, and
a main().

But remember, if you make the program very short, it will be easier for
us to see the problem. We don't want to look at a lot of code, if the
problem can be shown in just a few lines.
rodorico



Joined: 14 Nov 2010
Posts: 8

View user's profile Send private message

PostPosted: Mon Nov 15, 2010 5:10 am     Reply with quote

PCM programmer wrote:
It would be better if you posted a small, but complete test program that
shows the problem. You can probably cut out a large amount of your
code and still create a program that shows the problem. Try to do that.
Then post it. The program that you post should be compilable with no
errors. Test it before you post it. It must have the #include for the PIC,
and the #fuses, and the #use delay(), and all variable declarations, and
a main().

But remember, if you make the program very short, it will be easier for
us to see the problem. We don't want to look at a lot of code, if the
problem can be shown in just a few lines.


Ok i'll try to post a short test program to check.
rodorico



Joined: 14 Nov 2010
Posts: 8

View user's profile Send private message

PostPosted: Mon Nov 15, 2010 3:53 pm     Reply with quote

Hi, I'm making some test and this is my conclusion, the problem is at the while(true) loop.

If I no put code inside it works fine, but if I insert code, the pic reboots.

This is the while loop
Code:

/* loop */
   while (true) {

      if (starts) {

         read_tpa81(TPA81_ID);
         printf("%C\n",setTermalScan);
         delay_ms(1);
         printf("%U,%U,%U,%U,%U,%U,%U,%U,%U\n", t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9]);
         enable_interrupts(GLOBAL);
         delay_ms(termalScanPeriod);
      }
   }

and the read_tpa81

Code:
void read_tpa81( byte slaveID ) {

   for ( i=0; i<10; i++) {

      i2c_start();
      i2c_write(slaveID);
      i2c_write(i);
      i2c_start();
      i2c_write(slaveID+1);
      t[i] =  i2c_read(0);
      i2c_stop ();
      delay_ms(10);
   }
}


any Idea....

Regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 15, 2010 4:05 pm     Reply with quote

I can't really do anything without a (short) complete test program
and the compiler version.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Nov 16, 2010 3:11 am     Reply with quote

I agree with PCM programmer but as you are trying to track the problem down yourself, try commenting out individual lines in the while to see which one causes the reboot!

Also:-
printf("%U,%U,%U,%U,%U,%U,%U,%U,%U\n", t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9]);

I notice you are accessing your array starting at [1], arrays in C start at base 0 [0], but as you have not posted the variable definition I can not say if this is a problem!

Forget that, I see what you are doing, but still, you don't post ANY variable definitions!
rodorico



Joined: 14 Nov 2010
Posts: 8

View user's profile Send private message

PostPosted: Thu Nov 18, 2010 10:44 am     Reply with quote

Here is a short program test,

I'm printing every x second 9 values from a thermal scan connected to the pic by I2c, and attached is all the code of the short program with all the variable declarations.
Code:

#fuses XT,NOWDT, NOPROTECT, NOLVP, PUT, NOBROWNOUT

#use delay (clock = 4000000)
#use rs232 (baud = 9600, xmit = PIN_C6, rcv = PIN_C7)
#use I2C(master, sda=PIN_C4, scl=PIN_C3)


/* PIN_B6 represents move sensor input  */
/* PIN_B4 represents left line sensor */
/* PIN_B5 represents right line sensor */
/* PIN_B0 represents left wheel */
/* PIN_B1 represents right wheel  */

boolean manual_move;
boolean starts = false;

boolean moving_forward = false;
boolean moving_backward = false;
boolean moving_left = false;
boolean moving_right = false;

char operation;

int i = 0;
byte  t[10];

void read_tpa81( byte slaveID ) {

   for ( i=0; i<10; i++) {

      i2c_start();
      i2c_write(slaveID);
      i2c_write(i);
      i2c_start();
      i2c_write(slaveID+1);
      t[i] =  i2c_read(0);
      i2c_stop ();
   }
}

#int_RDA
interrupt_RS232 () {

   operation = getc();

 
   // operation to kwon that the robot is alive
   if (operation == heartbeat) {
      printf("%C\n", heartbeat);
   }

   // operation to start the vigilance
   else if (operation == start) {
      set_timer2 (0);
      set_timer0(0xFF);
      enable_interrupts(INT_TIMER2);
      output_high (PIN_B1);
      output_high (PIN_B0);
      starts = true;
   }

   // operation to stop the vigilance
   else if (operation == stop) {
      disable_interrupts(INT_RB);
      disable_interrupts(INT_TIMER0);
      disable_interrupts(INT_TIMER2);
      output_low (PIN_B1);
      output_low (PIN_B0);
      starts = false;
   }

}


void main()
{

   /* configuramos interrupciones del timer2 */
   set_tris_b (0xF0); /* puerto b 0,1,2,3 out, others in */

   
   enable_interrupts (INT_RDA); /* habilitamos interrupciones rs232 */
   enable_interrupts (GLOBAL); /* habilitamos todas las interrupciones */

   printf("WELCOME\n");
   
   
   output_low (PIN_B1);
   output_low (PIN_B0);
   output_low (PIN_B2);

   manual_move = true;

   /* bucle infinito */
   while (true) {
      delay_ms(1000);
      read_tpa81(TPA81_ID);
      printf("%C\n",setTermalScan);
      for (i = 1; i <10; i++){
         if (i == 9)
            printf("%U",t[i]);
         else
            printf("%U,",t[i]);
      }       
      putc('\n');
  }
}

When I send a lot of commands by rs232 to the robot, it reboots, printing again the WELCOME message.
rodorico



Joined: 14 Nov 2010
Posts: 8

View user's profile Send private message

PostPosted: Fri Nov 19, 2010 8:45 am     Reply with quote

any idea guys Rolling Eyes
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Fri Nov 19, 2010 9:10 am     Reply with quote

I don't know if this is the problem or not, but here's a couple of things I would do differently:

Don't enable/disable interrupts in the interrupt routine. Enable them in main() before your infinite loop and leave them enabled. SET or CLEAR a flag in your #int_RDA and use an if(FLAG) to determine whether to execute the code in your other interrupt routines.

Same thing with the printf. Don't printf inside the interrupt. Set a flag and put an if(FLAG)printf(...) in your main loop.

Just my thoughts, but hope it helps.
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Nov 19, 2010 9:10 am     Reply with quote

Add 'errors' to the use rs232(....) function.

Set 'flags' inside the ISR.

Remove all prints,etc. inside the isr.

In the main program loop, test the 'flags' and take the apporopriate action.
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Fri Nov 19, 2010 9:13 am     Reply with quote

Ahh, the ERRORS gotcha!
I missed that completely.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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