SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By angelsix
#128271
I've seen this happen twice in the last 2 weeks now and it is really starting to bug me.

To keep things as simple as possible here is a stepper motor code, in this instance running on a PIC24F04KA200. I have tested this on many other pics and symptoms are all the same.

Basically once a function gets too many __delay_ms calls in (and I don't even mean that long, a few calls) in some cases, specifically this one for example, the entire program stops working all together.

In works perfectly fine in the MPLAB SIM, but not on the PIC once so many lines are reached.

I have 2 other projects with completely different code and have also noticed once a function gets past a certain length the entire thing stops working and suspect it is likely due to the exact same thing.

I have played about with code model, data model, removing optimization, everything and nothing changes.

I have found that the problem occurs when a certain value is exceeded in the __delay_ms AND it is also called so many times. For example calling __delay_ms(500); works fine. But calling it 3 times stops everything working.

Here is the sample single file code. Simply uncomment out the lines in the main loop where it says and entire program stops working.

Anyone know why this happens and perhaps an alternate function to the __delay_ms? For now I have just written my own delay but would like to use library functions and figure out why it doesnt work in the first place.
Code: Select all
#include <p24fxxxx.h>

//_CONFIG(WDTPS_PS1);
_FGS(GCP_ON & GWRP_ON); // General and Flash protection on
_FOSCSEL(IESO_OFF & FNOSC_FRC); // Dual startup off, 8Mhz internal oscillator
_FOSC(FCKSM_CSDCMD & SOSCSEL_SOSCHP & POSCFREQ_MS & OSCIOFNC_ON & POSCMOD_NONE); 
					// Clock switching disabled, secondary oscillator for High Power op
					// Medium frequency (8Mhz), OSCO pin for I/O
					// Primary oscillator (external) disabled
_FWDT(FWDTEN_OFF & WINDIS_OFF & FWPSA_PR32 & WDTPS_PS1); // Watchdog off, default settings
_FPOR(MCLRE_OFF & BORV_LPBOR & PWRTEN_OFF & BOREN_BOR0); 
					// MCLR off
					// BOR diabled and set to lowest BOR voltage
					// Power-up timer disabled
_FICD(DSWDTEN_OFF & DSLPBOR_ON & DSWCKSEL_LPRC & DSWDTPS_DSWDTPSF); 
					// Deep-sleep WDT disabled
					// Deep-sleep BOR enabled using secondary LP oscillator
#include "main.h"
#define FCY 4000000UL
#include <libpic30.h>

#define CW 0
#define CCW 1

// number of steps per revolution 
// e.g. 1/8 deg per step = 200 steps per revolution
const int STEPS_PER_REV = 200;

#define DIRECTION_TRI	_TRISA2
#define DIRECTION		_LATA2
#define	STEP_TRI		_TRISB15
#define	STEP			_LATB15
#define MS1_TRI			_TRISA3
#define MS1				_LATA3
#define MS2_TRI			_TRISB4
#define MS2				_LATB4
#define SLEEP_TRI		_TRISA4
#define	SLEEP			_LATA4

int i = 10;

// enumerate motor step modes
enum STEP_MODE {
  FULL,
  HALF,
  QUARTER,
  EIGHTH  
};

int main()
{	
	Initialize();
		
	while (1)
	{
               // This is the test loop to check it is running by flashing an LED on the STEP pin.
		while (i > 0)
		{
			STEP = 0;
			__delay_ms(200);
			STEP = 1;
			__delay_ms(200);
			i--;
		}
		
		// full step test
		StepMotor(STEPS_PER_REV, CW, FULL, 1600);
		__delay_ms(500);
		__delay_ms(500);
		StepMotor(STEPS_PER_REV, CCW, FULL, 1600);
		__delay_ms(500);
		__delay_ms(500);

		// ####################
		// Add a few more lines of code here for example
		// copy and paste the motor code again, and
		// the entire chip will stop working
		// Tried this on PIC24F04s, PIC24FJ64s and 2 others
		// same issue!
		// ####################
		//StepMotor(STEPS_PER_REV, CW, FULL, 1600);
		//__delay_ms(500);
		//__delay_ms(500);
		//StepMotor(STEPS_PER_REV, CCW, FULL, 1600);
		//__delay_ms(500);
		//__delay_ms(500);
	}	

	return 0; // S_OK
}

void StepMotor(int steps, int dir, int mode, int delay)
{
	// Set direction
    DIRECTION = dir;
    
    // Set stepping mode
    SetStepMode(mode);

	// Wake up
	SLEEP = 1;

	int i = 0;
    for (i = 0; i < steps; i++)
	{
		STEP = 0;
		STEP = 1;
		__delay_ms(delay);
    }

	// Sleep
	SLEEP = 0;
}


void SetStepMode(int mode)
{
  switch (mode)
  {
    case FULL: 
		MS1 = 0;
		MS2 = 0;
		break;
    case HALF:
		MS1 = 1;
		MS2 = 0;
		break;
    case QUARTER:
		MS1 = 0;
		MS2 = 1;
		break;
    case EIGHTH:
		MS1 = 1;
		MS2 = 1;
		break;
  }
}

void Initialize()
{	
	// 8Mhz clock
	// No clock dividing (default is 4Mhz)
	CLKDIV = 0x3000;

	TRISA = 0;			// All outputs
	TRISB = 0;
	
	PORTA = 0;
	PORTB = 0;

	AD1PCFG = 0x1FFF;	// All digital I/Os (top 3 bits band gaps and vregs)
	
	
	DIRECTION_TRI = 0;
	STEP_TRI = 0;
	MS1_TRI = 0;
	MS2_TRI = 0;
	SLEEP_TRI = 0;
	
	// Sleep to begin with
	SLEEP = 0;
}