zoukankan      html  css  js  c++  java
  • PIC32MZ tutorial -- OC Interrupt

      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, it runs very well.

    #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();
        }
    }
  • 相关阅读:
    HTML_项目符号使用图片
    字符串查找和替换接口
    AOP代理分析
    3星|董藩《房地产的逻辑》:应该鼓励开发商多盖房而不是惩罚开发商
    2.5星|郎咸平《拯救世界的经济学》:各发达国家与中国的福利政策、经济干预政策的前世今生
    3.5星|科特勒《营销革命4.0》:打造无缝衔接的线上和线下体验
    3星|《韩国式资本主义》:财阀祸害韩国,韩国需要正义的资本主义
    4星|《特朗普时代的全球化战略》:管理学界和管理者可能严重低估了核心管理实践的价值
    2星|《内容创业》:知识付费行业的公开资料整理汇编
    3星|《身边的博弈》:10年旧书,博弈论科普和习题讲解
  • 原文地址:https://www.cnblogs.com/geekygeek/p/pic32mz_ocinterrupt.html
Copyright © 2011-2022 走看看