Estoy trabajando en un dsPIC33EP64GS502
tratando de hacer que funcione a 70 MIPS con el oscilador interno. Este es mi código:
// FSEC
#pragma config BWRP = OFF // Boot Segment Write-Protect bit (Boot Segment may be written)
#pragma config BSS = DISABLED // Boot Segment Code-Protect Level bits (No Protection (other than BWRP))
#pragma config BSEN = OFF // Boot Segment Control bit (No Boot Segment)
#pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
#pragma config GSS = DISABLED // General Segment Code-Protect Level bits (No Protection (other than GWRP))
#pragma config CWRP = OFF // Configuration Segment Write-Protect bit (Configuration Segment may be written)
#pragma config CSS = DISABLED // Configuration Segment Code-Protect Level bits (No Protection (other than CWRP))
#pragma config AIVTDIS = OFF // Alternate Interrupt Vector Table bit (Disabled AIVT)
// FBSLIM
#pragma config BSLIM = 0x1FFF // Boot Segment Flash Page Address Limit bits (Boot Segment Flash page address limit)
// FSIGN
// FOSCSEL (Select Internal FRC at POR)
#pragma config FNOSC = FRC // Oscillator Source Selection (Fast RC Oscillator)
#pragma config IESO = OFF // Two-speed Oscillator Start-up Disabled
// FOSC
#pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
#pragma config OSCIOFNC = ON // OSC2 Pin is I/O
#pragma config IOL1WAY = OFF // Peripheral pin select configuration bit (Allow multiple reconfigurations)
#pragma config FCKSM = CSECME // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are enabled)
#pragma config PLLKEN = ON // PLL Lock Enable Bit (Clock switch will wait for the PLL lock signal)
// FWDT
#pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
#pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit (1:128)
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (WDT and SWDTEN disabled)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
#pragma config WDTWIN = WIN25 // Watchdog Timer Window Select bits (WDT Window is 25% of WDT period)
// FICD
#pragma config ICS = PGD1 // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1)
#pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
#pragma config BTSWP = OFF // BOOTSWP Instruction Enable/Disable bit (BOOTSWP instruction is disabled)
// FDEVOPT
#pragma config PWMLOCK = OFF // PWMx Lock Enable bit (PWM registers may be written without key sequence)
#pragma config ALTI2C1 = OFF // Alternate I2C1 Pin bit (I2C1 mapped to SDA1/SCL1 pins)
#pragma config ALTI2C2 = OFF // Alternate I2C2 Pin bit (I2C2 mapped to SDA2/SCL2 pins)
#pragma config DBCC = OFF // DACx Output Cross Connection bit (No Cross Connection between DAC outputs)
// FALTREG
#pragma config CTXT1 = OFF // Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 1 bits (Not Assigned)
#pragma config CTXT2 = OFF // Specifies Interrupt Priority Level (IPL) Associated to Alternate Working Register 2 bits (Not Assigned)
// FBTSEQ
#pragma config BSEQ = 0xFFF // Relative value defining which partition will be active after device Reset; the partition containing a lower boot number will be active (Boot Sequence Number bits)
#pragma config IBSEQ = 0xFFF // The one's complement of BSEQ; must be calculated by the user and written during device programming. (Inverse Boot Sequence Number bits)
#include <xc.h>
#include <stdlib.h>
#include <libpic30.h>
#include <pps.h>
#include <uart.h>
#include <stdint.h>
int main(int argc, char** argv) {
PLLFBD = 74; // M = PLLFBD + 2 = 76
CLKDIVbits.PLLPOST = 0; // N2 = 2
CLKDIVbits.PLLPRE = 0; // N1 = 2
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(OSCCON | 0x01);
while(OSCCONbits.COSC != 0);
while(OSCCONbits.LOCK != 1);
ACLKCONbits.FRCSEL = 1;
ACLKCONbits.SELACLK = 1;
ACLKCONbits.APSTSCLR = 7;
ACLKCONbits.ENAPLL = 1;
while(ACLKCONbits.APLLCK != 1);
INTCON1bits.NSTDIS = 0;
TRISBbits.TRISB5 = 0;
LATBbits.LATB5 = 1;
while(1){
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
LATBbits.LATB5= 0;
LATBbits.LATB5= 1;
}
return (EXIT_SUCCESS);
}
Básicamente, puse M=76
, N1=2
y N2=2
que deberían dar 70 MIPS con FRC a 7.37 MHz. Estoy alternando RB5, verifiqué el ensamblador generado y es una sola instrucción:
Yestaeslaseñalqueveoenmialcance(perdónporlaimagendemalacalidad):
El período de señal es de 57.6ns y el período debería ser (1/70e6) * 2 = 28.5ns
, que es la mitad del período que estoy viendo, por lo que el dsPIC parece estar funcionando a 35 MIPS, no a 70 MIPS. ¿Qué hay de malo con el código? Incluso copié un código del ejemplo de Microchip y siempre obtengo la mitad de la frecuencia.
El dsPIC se alimenta con VDD = 3.3V
y AVDD = 3.3V
y VCAP = 10uF
. Estoy trabajando con MPLABX v3.61 y XC16 v1.31. Anteriormente trabajé con dsPICs
hasta 40 MIPS y nunca encontré un problema de este tipo.