How Reliable is AVR Simulator 2?

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

Has anyone had any issues with AVR Simulator 2? I am having difficulty getting my program to function the way I believe it should be and I was using Simulator 2 to look at the registers and watch program flow to see what is going on.

But I'm getting some strange behavior, AVR Simulator 2 seems to jump to random locations within my program (which could be either Simulator 2 not working correctly or issues with my pointers messing things up) during the first few function calls as I step through it, after which it seems to run as I would expect. When I try the program in the micro-controller, LED2 never gets turn off, which indicates either an issue with Timer0 as you can see in my program snipet below or again something is being tromped on by pointers which could certainly mess things up(if LED2 never gets turn off then there is an issue with a part of the program never being run).

#define Trigger (PINC&_BV(PINC1))		
#define Gear_Sensor (PINC&_BV(PINC3))
#define Bolt_Sensor (PINC&_BV(PINC4))
#define	BB_Sensor (PINC&_BV(PINC5))	
#define	Mag_Sensor (PINC&_BV(PINC2))
#define	SW6	(PIND&_BV(PIND7))
	
#define Turn_On_Motor (PORTB |= _BV(PINB1))
#define Turn_Off_Motor (PORTB &= ~_BV(PINB1))
#define	Motor_On (PINB&_BV(PINB1))
#define Turn_On_Brake (PORTB |= _BV(PINB0))
#define Turn_Off_Brake (PORTB &= ~_BV(PINB0))
#define Brake_On (PINB&_BV(PINB0))

#define Start_PWM1 (TCCR1B |= (1<<CS11), TCCR1A |= (1<<COM1A1))
#define Stop_PWM1 (TCCR1B &= ~(1<<CS11), TCCR1A &= ~(1<<COM1A1))
#define	Enable_Timer0_Int TIMSK0 |= (1 << OCIE0A)
#define	Disable_Timer0_Int TIMSK0 &= ~(1 << OCIE0A)
#define	Start_Timer0 TCCR0B |= (1<<CS00)								/*(1<<CS02) |*/
#define	Stop_Timer0 TCCR0B &= ~(1<<CS00)								/*(1<<CS02) &*/
#define Clear_Timer0_Int_Flags TIFR0 &= ~((1<<OCF0B) & (1<<OCF0A))
#define TC0PrestartDelay 50												/* 10=1uS, 50=5uS */

#define Turn_On_LED1 PORTD |= (1<<PIND0)
#define Turn_Off_LED1 PORTD &= ~(1<<PIND0)
#define Turn_On_LED2 PORTD |= (1<<PIND1)
#define Turn_Off_LED2 PORTD &= ~(1<<PIND1)

TCCR0A |= (1<<WGM01);
OCR0A = TC0PrestartDelay; 
Enable_Timer0_Int;

Any variable that does not use a pointer and is used in the interrupt is volatile and global.
Any variable that uses a pointer is declared within the scope of main, the address of that variable is then passed into the function.

and

ISR(TIMER0_COMPA_vect){
	Stop_Timer0;
	TCNT0 = 0;
	Timer0DelayComplete_Gbl=true;
	if( SoftStartComplete_Gbl==true ){
		OCR1A=DutyCycle_Gbl;
		SoftStartComplete_Gbl=false;
		Timer0DelayComplete_Gbl=false;
	}
	Clear_Timer0_Int_Flags;
}

void Check_If_Safe_Mode(bool *ptr_TriggerFlag, bool *ptr_FireLockFlag, bool *ptr_StopFiringLockFlag){
	while( !SW6 ){
		if( *ptr_TriggerFlag ){
			if( (Trigger==0)&&((*ptr_FireLockFlag)==false) ){
				Turn_On_LED1;
				Turn_Off_Brake;
				OCR1A = SoftStartDutyCycle_Gbl;	/* set duty cycle to 80% */
				OCR0A = TC0PrestartDelay;		/* set prestart delay to 500us */
				Start_Timer0;					/* delay before start PWM */
				*ptr_FireLockFlag=true;			/* lock out this part of the program from being executed */
			}
			if( Timer0DelayComplete_Gbl==true ){
				Turn_On_LED2;
				Start_PWM1;
				Start_Timer0;
				SoftStartComplete_Gbl=true;		/* */
				*ptr_FireLockFlag=false;		/* */
				*ptr_TriggerFlag=false;			/* */
				Timer0DelayComplete_Gbl=false;	
			}
		}
		if( !(*ptr_TriggerFlag) ){
			if( (Trigger!=0)&&(*ptr_StopFiringLockFlag==false) ){
				Turn_Off_LED1;
				Stop_PWM1;		
				Turn_Off_Motor;
				OCR0A = TC0PrestartDelay;	/* 500us */
				Start_Timer0;
				*ptr_StopFiringLockFlag = true;
			}
			if( Timer0DelayComplete_Gbl==true ){
				Turn_Off_LED2;
				Turn_On_Brake;
				*ptr_StopFiringLockFlag = false;
				*ptr_TriggerFlag = true;
				Timer0DelayComplete_Gbl=false;			
			}
		}
	}	
}

Check If Safe Mode is a function that is called right before the main loop, its controlling a mechanical gearbox using two MOSFETS, one for drive and the other for active braking. The Trigger is the user input signal to start the gearbox.

Theory of operation:

If trigger:
1. turn off brake
2. delay a short period of time before start(to allow brake fet to turn fully off)
3. soft start drive fet at 80% of specified duty cycle for several hundred uS
4. change duty cycle to 100% of specified value and run until !Trigger

If !trigger:
1. turn off PWM, turn off drive FET
2. delay a short period of time before turning on brake
3. turn on brake

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

Quote:

AVR Simulator 2 seems to jump to random locations within my program (which could be either Simulator 2 not working correctly or issues with my pointers messing things up)

More than likely it's actually your C compiler's optimizer rearranging/discarding code. Try:

(a) switch to mixed C+Asm view then single step (now each step is one opcode not one whole C statement) and follow the flow.

(b) build the code with the optimizer switched off and see if there's a one to one correspondence between C statements and blocks of opcodes and that execution flow is linear

If it behaves as expected when not optimized then there is no issue here - it's simply optimizer re-arrangement which is one of the penalties you pay for using an efficient C compiler. The good news is that the actual function of your program will be as written, though the optimizer is at liberty to rearrange things if it makes for more efficient code.

PS for the sake of the next person who has to maintain your code would you not consider at least using all upper case for the over-use of macroization so at least the reader has some chance of knowing what are function calls and what are macros (and hence where to locate their definitions)

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

Have used AVR simulator quite often, haven't found any issues.