首页 > 其他 > 详细

PIC32MZ tutorial -- OC Interrupt

时间:2016-01-05 22:39:17      阅读:327      评论:0      收藏:0      [点我收藏+]

  In my previous blog "PIC32MZ tutorial -- Output Compare", I shows how to apply Output Compare without interrupt to generate PWM signal. I also tried the Output Compare interrupt. I selected OC to be PWM mode without fault pin (OCM = "110") and enable its interrupt. Below is the initialization of OC.

void OC1_Init(void)
{
    OC1CON = 0x0000;
    //RPD1/RD1 -> OC1
    RPD1R = 0xC;
 
    IPC1SET = 0x1E000000;
    IFS0CLR = 0x80;
    IEC0SET = 0x80;
    
    OC1RS = OC_MIN;
    OC1R = OC_MIN;
    OC1CON = 0x2E;
    OC1CONSET = 0x8000;  // Enable OC
}

  But the application run not properly. The symptom was the OC interrupt never happened ( I set a breakpoint in the OC interrupt service routine, never saw the application entry this interrupt service routine). I raised a support ticket for this issue to Microchip. And the fleedback was that PWM mode without fault pin would not generate interrupt. So I decided change the PWM mode to Continuous Pulses mode (OCM = "101") and enabled interrupt then retried. This time the whole application is like below.

#include <xc.h>
 
#include <sys/attribs.h>
#pragma config FMIIEN = ON // Ethernet RMII/MII Enable (MII Enabled) // need a 25MHz XTAL in MII mode, a 50MHz Clock in RMII mode. 
#pragma config FETHIO = ON // Ethernet I/O Pin Select (Default Ethernet I/O)
#pragma config PGL1WAY = ON // Permission Group Lock One Way Configuration (Allow only one reconfiguration)
#pragma config PMDL1WAY = ON // Peripheral Module Disable Configuration (Allow only one reconfiguration)
#pragma config IOL1WAY = ON // Peripheral Pin Select Configuration (Allow only one reconfiguration)
#pragma config FUSBIDIO = OFF // USB USBID Selection (Controlled by Port Function)
// DEVCFG2  7FF9B11A
#pragma config FPLLIDIV = DIV_3 // System PLL Input Divider (3x Divider)
#pragma config FPLLRNG = RANGE_5_10_MHZ // System PLL Input Range (5-10 MHz Input)
#pragma config FPLLICLK = PLL_POSC // System PLL Input Clock Selection (POSC is input to the System PLL)
#pragma config FPLLMULT = MUL_50 // System PLL Multiplier (PLL Multiply by 50) //PLL must output between 350 and 700 MHz
#pragma config FPLLODIV = DIV_2 // System PLL Output Clock Divider (2x Divider)
#pragma config UPLLFSEL = FREQ_24MHZ // USB PLL Input Frequency Selection (USB PLL input is 24 MHz)
#pragma config UPLLEN = OFF // USB PLL Enable (USB PLL is disabled)
// DEVCFG1  7F7F3839
#pragma config FNOSC = SPLL // Oscillator Selection Bits (System PLL)
#pragma config DMTINTV = WIN_127_128 // DMT Count Window Interval (Window/Interval value is 127/128 counter value)
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disable SOSC)
#pragma config IESO = OFF // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = EC // Primary Oscillator Configuration (External clock mode)
#pragma config OSCIOFNC = ON // CLKO Output Signal Active on the OSCO Pin (Enabled)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disabled, FSCM Disabled)
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
#pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming)
#pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled)
#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%)
#pragma config DMTCNT = DMT31 // Deadman Timer Count Selection (2^31 (2147483648))
#pragma config FDMTEN = OFF // Deadman Timer Enable (Deadman Timer is disabled)
// DEVCFG0  FFFFFFF7
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config JTAGEN = ON // JTAG Enable (JTAG Port Enabled)
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (Communicate on PGEC2/PGED2)
#pragma config TRCEN = ON // Trace Enable (Trace features in the CPU are enabled)
#pragma config BOOTISA = MIPS32 // Boot ISA Selection (Boot code and Exception code is MIPS32)
#pragma config FECCCON = OFF_UNLOCKED // Dynamic Flash ECC Configuration (ECC and Dynamic ECC are disabled (ECCCON bits are writable))
#pragma config FSLEEP = OFF // Flash Sleep Mode (Flash is powered down when the device is in Sleep mode)
#pragma config DBGPER = ALLOW_PG2 // Debug Mode CPU Access Permission (Allow CPU access to Permission Group 2 permission regions)
#pragma config EJTAGBEN = NORMAL // EJTAG Boot (Normal EJTAG functionality)
// DEVCP0
#pragma config CP = OFF // Code Protect (Protection Disabled)

#define Mvec_Interrupt() INTCONSET = 0x1000; asm volatile("ei");

#define OC1_VALUE (PORTD & 0x2)
#define OC_MAX (0x7A120)
#define OC_MIN (0x0)
#define STEP_VALUE (500)

#define LED_IOCTL() TRISHCLR = (1<<0)
#define LED_SETON() LATHSET = (1<<0)
#define LED_SETOFF() LATHCLR = (1<<0)
#define LED_ONOFF() LATHINV = (1<<0)
#define LED_OPEN() ANSELH &= 0xFFFFFFFE

typedef enum _eRUN_MODE
{
    Stable1,
    Welcome,
    Stable2,
    Goodbye,
} eRUN_MODE;
eRUN_MODE LED_RunMode;

void OC1_Init(void)
{
     OC1CON = 0x0000;
    //RPD1/RD1 -> OC1
    RPD1R = 0xC;
    
    IPC1SET = 0x1E000000;
    IFS0CLR = 0x80;
    IEC0SET = 0x80;
    
    OC1RS = OC_MIN;
    OC1R = OC_MIN;
    OC1CON = 0x2D;
    OC1CONSET = 0x8000;  // Enable OC
}
void LED_Init(void)
{
    LED_SETOFF();
    LED_OPEN();
    LED_IOCTL();
    LED_RunMode = Stable1;
}

void T23_Init(void)
{
    T2CON = 0x0;
    T3CON = 0x0;
    TMR2 = 0;
    TMR3 = 0;
    
    //IPC3SET = 0x50000;
    IPC3SET = 0x120000;
    IEC0SET = 0x4000;
    IFS0CLR = 0x4000;
    
    PR2 = 0xA120;
    PR3 = 0x7;

    T2CON = 0x0008;
    T2CON |= 0x8000;
}
void T45_Init(void)
{
    T4CON = 0;
    T5CON = 0;
    TMR4 = 0;
    TMR5 = 0;
    IPC6SET = 0x6;
    IFS0CLR = 0x1000000;
    IEC0SET = 0x1000000;
    PR4 = 0xE100;
    PR5 = 0x05F5;
    T4CON = 0x0008;
    T4CON |= 0x8000;
}

void __ISR(_OUTPUT_COMPARE_1_VECTOR,ipl7AUTO) OC1_Handler(void)
{
    IFS0CLR = 0x80;
    LED_SETOFF();
    if (LED_RunMode == Stable1)
    {
        ; // do nothing
    }
    else if (LED_RunMode == Stable2)
    {
        ; // do nothing
    }
    else if (LED_RunMode == Welcome)
    {
        OC1RS = OC1RS + STEP_VALUE;
        if (OC1RS >= OC_MAX)
        {
            T4CON = 0x0008;
            TMR4 = 0;
            TMR5 = 0;
            PR4 = 0xE100;
            PR5 = 0x05F5;
            T4CON = 0x8008;
            IFS0CLR = 0x1000000;
            LED_RunMode = Stable2;
        }
    }
    else            // LED_RunMode == Goodbye
    {
        OC1RS = OC1RS - STEP_VALUE;
        if (OC1RS == OC_MIN)
        {
            T4CON = 0x0008;
            TMR4 = 0;
            TMR5 = 0;
            PR4 = 0xE100;
            PR5 = 0x05F5;
            T4CON = 0x8008;
            IFS0CLR = 0x1000000;
            LED_RunMode = Stable1;
        }
    }
    Nop();
}

void __ISR(_TIMER_3_VECTOR,ipl4AUTO) T23_Handler(void)
{
    LED_SETON();
    TMR2 = 0;
    TMR3 = 0;
    IFS0CLR = 0x4000;
    Nop();
}
void __ISR(_TIMER_5_VECTOR,ipl1AUTO) T45_Handler(void)
{
    if (LED_RunMode == Stable1)
    {
        LED_RunMode = Welcome;
        //PR5 = 0x98;
        PR4 = 0x9680;
        PR5 = 0x98;
    }
    else if (LED_RunMode == Welcome)
    {
        ; // do nothing
    }
    else if (LED_RunMode == Stable2)
    {
        LED_RunMode = Goodbye;
        //PR5 = 0x98;
        PR4 = 0x9680;
        PR5 = 0x98;
    }
    else // LED_RunMode == Goodbye
    {
        ; // do nothing
    }
    TMR4 = 0;
    TMR5 = 0;
    IFS0CLR = 0x1000000;
    Nop();
}
void main(void)
{
    LED_Init();
    OC1_Init();
    T23_Init();
    T45_Init();
    Mvec_Interrupt();
    while(1)
    {
        LED_Scheduler();
    }
}

 

PIC32MZ tutorial -- OC Interrupt

原文:http://www.cnblogs.com/geekygeek/p/pic32mz_ocinterrupt.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!