Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

dsPIC33E Oscillator Config issues

Status
Not open for further replies.

chinuhark

Member level 5
Joined
Aug 16, 2014
Messages
88
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Activity points
1,051
I want to run my dsPIC33E as fast as possible using the internal FRC with PLL but it seems to be running slow as hell. I configured it to run at 80MHz Fosc and checked the speed using GPIO on RB15 and a DSO.

Code:
while(1)
    {
    LATBbits.LATB15 = ~LATBbits.LATB15;
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    asm("NOP");
    }

THE PROBLEM:
Above code generated a square wave of just 735-740kHz. (Meaning freq of just 7.35-7.4MHz)
With 50 NOPs, frequency was about 280-290kHz. (Meaning frequency of about 14.5MHz)
Removing everything else and with just
Code:
while(1)
{
  LATBbits.LATB15 = ~LATBbits.LATB15;   
}
I got a measly 1.1MHz for the square wave.
Two seperate DSOs gave the same results and both measured line frequency to precisely 50Hz and are rated at 50MHz each.

None of the readings agree with each other and a Float Multiply took 8usec.

The biggest issue is that with #define FCY 40000000ULL I got accurate delays for LED Blinks (in seconds with a stopwatch. Didn't have a DSO or CRO at the time but had tested for upto 10 seconds for any error)


The part of my code which is related to clock settings is as shown:


Code:
// FWDT
#pragma config PLLKEN = ON              // PLL Lock Enable bit (Clock switch to PLL source will wait until the PLL lock signal is valid.)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable bit (Watchdog timer enabled/disabled by user software)

// FOSC
#pragma config POSCMD = NONE            // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
#pragma config OSCIOFNC = OFF           // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config IOL1WAY = OFF            // Peripheral pin select configuration (Allow multiple reconfigurations)
#pragma config FCKSM = CSECMD           // Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled)

// FOSCSEL
#pragma config FNOSC = FRC              // Oscillator Source Selection (Internal Fast RC (FRC))
#pragma config IESO = OFF               // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)

The instructions above are put in the header file. The instructions given below are in the c main file:

Code:
int main()
{
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD=63; // M=65
CLKDIVbits.PLLPOST=0; // N2=2
CLKDIVbits.PLLPRE=1; // N1=3
// Initiate Clock Switch to FRC oscillator with PLL (NOSC=0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(OSCCON | 0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
// Wait for PLL to lock
while (OSCCONbits.LOCK!= 1);

}


Please help as 8 microseconds for a floating multiply is just unacceptable for me as I want to implement a Fuzzy Current controller which will have to run atleast at 25-30kHz meaning all calculations must be over within 40us.
The fact that these DSCs can do sensorless vector control means that they must be able to run those complex algorithms and those systems also have inner current loops at 30-35kHz.
 

The form:
while(1)

appears to take a lot of time. It may take less time if you use instead:
while(a)

where you have previously declared a as an integer, and set it to any non-zero integer

------------------------------------------

Similarly with the form:
while (OSCCONbits.LOCK!= 1)

Try:
while (OSCCONbits.LOCK!= x)

Where you have previously declared x as a variable of the exact same format (byte, integer, long integer, floating, etc.) as the variable OSCCONbits.LOCK, and you previously set x equal to 1.

Then the value of x can be retrieved from memory quickly.

On the other hand, a fixed number value must be converted each time the command is executed, taking up cpu cycles each time.

At least I've heard of some program compilers working that way.
 

dsPIC33EP256MC202.
I just can't understand how it's taking 8us for a floating multiplication whereas everywhere on the web I see people saying it should be around 100-120 cycles, i.e. 0.8-1us.
 

I thought it prudent to point out the dsPIC33EP256MC202 is capable of generating a maximum Fosc of 140MHz with a device operating temperature of 85°C or below, which in turn produces an Instruction Cycle Clock (Fcy) of 70MHz for a performance of approximately 70MIPS.


Your current code to reconfigure the clock generates a Fvco of approximately 239.2MHz, which in turn generates a Fosc of approximately 119.6MHz and Fcy of approximately 59.8MHz when using the FRC of approximately 7.37MHz.


Code:
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD=63; // [COLOR="#FF0000"]M=65[/COLOR]
CLKDIVbits.PLLPOST=0; // N2=2
CLKDIVbits.PLLPRE=1; // N1=3
// Initiate Clock Switch to FRC oscillator with PLL (NOSC=0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(OSCCON | 0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
// Wait for PLL to lock
while (OSCCONbits.LOCK!= 1);

Therefore assuming the floating point multiplication does indeed require 120 cycles of Fcy, the time required would be approximately 2us. Of course this estimate is based on your stated estimates required to carry out the floating point multiplication operation being correct.

In any event, if speed is what you require, a more prudent method of performing the task would be to utilize fixed point operations, rather than floating point operations, which is why many of the high performance DSP devices, e.g., TMS320C6457, etc, are inherently designed to support fixed point math, rather than floating point math.

The primary reason to utilize floating point math, is for applications which require calculations/results of large dynamic range. Unfortunately, the use of float point math comes at a price, both speed and the introduction of some forms of error are inherently burdensome.

At least three important questions must be answered:

What is the require task of your application?

What is the required speed of the calculations to achieve the task?

What is the required accuracy of these calculations to achieve the task?



BigDog
 

Thanks for the reply. I did realize that I am running at 80Mhz and changed N1 to to to get 120MHz last night. But before I proceed please tell me-
1) How to decide whether to go for 120MHz or 140MHz. The datasheet tells to use 120MHz above 85C and 140 below it. How will I know the temperature at which it will run?
Answering your questions:
1) I want to implement a Fuzzy logic controller in the MCU.
2) It will be used for the inner current control loop of either a Vector Drive or Active power filter. From what people have told me, this loop must run at atleast 10kHz, meaning that all calculations must be completed within 100us. This is generally done using Hysteresis or PI controllers for which the computations are negligible as compared to Fuzzy control.
3) Accuracy. Haven't really looked into that aspect, but I will have to calculate and check.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top