uC only works correctly when reset twice

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm programming a atmega164p on a stk500 with the latest WinAVR (20070525) and AVRStudio (4.13). My code reads in commands on the USART0, and outputs pulses through a PWM signal to a stepper motor driver. If I turn off the power to the stk500 board, and turn it back on, the microcontroller will stop working/become stuck in a loop somewhere and stop responding to my commands. But the strange thing is that if I press the reset button on the STK board TWICE (or anything more than once), then it works correctly.

The code always gets stuck at the same place. (I debugged by transmitting characters back to my computer over the USART at different places in my code) I don't think it's a stack overflow because the uC isn't resetting itself, but I couldn't get the stack counter code working, as shown in the https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=52249&highlight=stack&sid=7a40f90687a028260d39c11a268f0ac5 tutorial "[SOFT] [C] AVRGCC: Monitoring Stack Usage"

What kind of bug would be fixed when the chip is reset twice? It doesn't seem like anything different should happen on the second reset that didn't happen on the first one.

I don't want to post all my code here, since it's a lot to go through. Here's a skeleton of what gets done. When run, on first powerup the uC would send a '*' to my computer. Then when I send the 'A' command, the uC will send back 'Q' and stop responding. If reset twice, sending 'A' would get a response of 'QR', and the program would keep running.

Thanks a lot for looking.

abbreviated pseudocode:
controller.c

#include 
#include 
#include "calculations.h"

int main( void )
{
  char command;
  PWM_Init();  // setup pwm signal
  USART0_Init(25);  //9600 baud @ 4Mhz clock
  sei();

  USART0_Transmit('*');

  for(;;)
  {
    if(USART0_RXHead != USART0_RXTail) // data in usart buffer
    {
      command = USART_Receive();
      switch(command)
      {
        case 'A':
          addSteps(100);
          break;
      }
    }
  }
}

calculations.c

void addSteps(long count)
{
  USART0_Transmit('Q');  // Debug
  USART0_Transmit('R');  // Debug
  // more code here...
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So it's gettting "stuck" in USART0_Transmit() then (if sometimes it sends Q and sometime QR. So let's see the body of that one (a peek at USART0_Init() would be good too). As you have an SEI it suggests you are enabling some form of interrupt in PWM_Init() so which interrupt is it and what's the ISR for it and does th LSS show that you ARE hooking the right vector for the AVR being used?

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I solved the problem... my TIMER1_OVF_vect interrupt function was apparently hogging up cycles.

I was using buffered USART transmit/receive functions and using the Timer1_CompA interrupt to count PWM pulses. I replaced the buffered USART_Transmit() function with a polling one so that it wouldn't get stuck.

void USART0_Transmit( unsigned char data )
{
	/* Wait until ready to transmit */
	while( !(UCSR0A & (1<<UDRE0)) )
		;
	/* Put data into UDR, sends the data */
	UDR0 = data;
}

So, my code would transmit all the characters it was supposed to, but it would still get stuck. I checked if the while loop inside my main function was still running by transmitting a character every 10000 loops. After sending a command the while loop was still running, but running really really slowly. I then disabled my interrupts until the program ran normally.

Thanks for your help. :)