//------------------------------------------------------------------------------ // This file is part of the QMdbSim project, a Microchip Simulator framework for // QSpice C-Block components. See the GitHub repository at // https://github.com/robdunn4/QSpice/ for the complete project, current // sources, documentation, and demonstration code. //------------------------------------------------------------------------------ /* * dsPIC33FJ128MC802: RB0 pulse, 8us HIGH / 2us LOW, in C with __delay_us(). * Companion to main_asm.c, which does the same pulse in cycle-exact assembly. */ #include #include //------------------------------------------------------------------------------ // Configuration bits // // Clock: Boot on the internal FRC oscillator (7.37MHz), then switch to FRC // with PLL in code. PLL settings: N1 = 2, M = 43, N2 = 2. // Fosc = 7.37MHz / 2 * 43 / 2 = 79.23MHz // Fcy = Fosc / 2 = 39.61MHz (nominal 40 MIPS) // The dsPIC33F executes 1 instruction cycle per 2 oscillator clocks, so the // SIMCLK in the QSpice schematic should be Fcy (39.61MHz). //------------------------------------------------------------------------------ // FOSCSEL #pragma config FNOSC = FRC // Start on FRC; switch to FRCPLL in code #pragma config IESO = OFF // Two-speed oscillator start-up disabled // FOSC #pragma config POSCMD = NONE // Primary oscillator off (RA2/OSC1 is I/O) #pragma config OSCIOFNC = ON // OSC2 pin is digital I/O (RA3) #pragma config IOL1WAY = OFF // Allow multiple peripheral pin remaps #pragma config FCKSM = CSECMD // Clock switching on, fail-safe monitor off // FWDT #pragma config FWDTEN = OFF // Watchdog timer disabled // FPOR #pragma config FPWRT = PWR1 // Power-up timer off (default is 128ms) // FICD #pragma config JTAGEN = OFF // JTAG disabled //------------------------------------------------------------------------------ // Clock setup //------------------------------------------------------------------------------ void initClock() { // configure PLL for Fosc = 79.23MHz from the 7.37MHz FRC CLKDIVbits.PLLPRE = 0; // N1 = 2 CLKDIVbits.PLLPOST = 0; // N2 = 2 PLLFBD = 41; // M = 43 // initiate clock switch to FRC with PLL (NOSC = 0b001) __builtin_write_OSCCONH(0x01); __builtin_write_OSCCONL(OSCCON | 0x01); // On real hardware, wait for the switch and PLL lock here: // while (OSCCONbits.COSC != 0b001); // while (OSCCONbits.LOCK != 1); // Omitted since MDBCS doesn't require it. } //------------------------------------------------------------------------------ // RB0 pulse in C // // Fixed from the original: the original defined FCY as 40MHz but never set // up the PLL, so it ran at the 7.37MHz FRC default (Fcy = 3.685MHz) and its // delays were about 10.9x too long. It now calls initClock(). FCY stays at // the nominal 40MHz so __delay_us() targets the same cycle counts as main_asm.c // (320 HIGH / 80 LOW). Loop and port-write overhead still make this // version a few cycles longer per phase than main_asm.c. //------------------------------------------------------------------------------ #define FCY 40000000UL #include // Brings in __delay_us() int main(void) { // CRITICAL: Switch AN2/RB0 pin from Analog to Digital mode AD1PCFGLbits.PCFG2 = 1; LATBbits.LATB0 = 0; // set pin state before enabling output TRISBbits.TRISB0 = 0; // RB0 = output // switch to FRC + PLL after the pin is defined (same order as main_asm.c) initClock(); while (1) { LATBbits.LATB0 = 1; // Turn LED ON (HIGH = 3.3V) __delay_us(8); LATBbits.LATB0 = 0; // Turn LED OFF (LOW = 0V) __delay_us(2); } return 0; }