⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ect_pwm.c

📁 移植到freescale 9s12系列单片机的uCOSII
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    if (duty > 100) {
        return (ECT_PWM_ERR_DUTY);                                      /* Return an error if the duty cycle is invalid (> 100%)    */    
    }

                                                                        /* Determine if the specified frequency is possible         */

    ECT_prescaler   =   TSCR2 & TSCR2_PR_MASK;                          /* Get the prescaler value in the control register          */    
    ECT_prescaler   =  (1 << ECT_prescaler);                            /* Calculate the correct prescaler value from the reg val   */
                                                                                                                                                
    busclk_frq      =   BSP_CPU_ClkFreq();                              /* Get the current CPU frequency (Hz)                       */
    busclk_frq     /=   2;                                              /* Divide the CPU frequency by 2 to get the BUSCLK freq     */

    ECT_curr_frq    =   busclk_frq / (ECT_prescaler);                   /* Determine the frequency of the ECT timer                 */
                                                                      
    if (ECT_curr_frq < frq_hz) {
        return (ECT_PWM_ERR_FRQ);                                       /* Desired PWM frequency is not obtainable given the        */
    }                                                                   /* current ECT prescaler and bus clock frequency            */
        
    CPU_CRITICAL_ENTER();                                               /* Disable interrupts when modifying global shared data     */
    Period[channel] =  (busclk_frq      / (ECT_prescaler * frq_hz));    /* Calculate necessary PWM settings                         */
    Mark[channel]   = ((Period[channel] *  duty) / 100);
    Space[channel]  =  (Period[channel] -  Mark[channel]);
    CPU_CRITICAL_EXIT();                                                /* Re-enable interrupts                                     */
    
    if (duty <= 3) {                                                    /* 0-3 percent, PWM off. See note 1)                        */ 
        ECT_PWM_Dis(channel, ECT_PWM_LAST_LOW);                         /* Stop the PWM with the output LOW                         */
    } else if (duty >= 98) {                                            /* 98-100 percent, PWM off. See note 1)                     */ 
        ECT_PWM_Dis(channel, ECT_PWM_LAST_HIGH);                        /* Stop the PWM with the output HIGH                        */
    } else {        
        ECT_PWM_DisLast[channel][ECT_DIS]   = 0;                        /* Re-enable the PWM channel if currently discabled         */
        TIE        |=    (1 << channel);                                /* Re-enable interrupts if the PWM is currently disabled    */
    }
    
    return (ECT_PWM_ERR_NONE);                                          /* Return without error                                     */
}

/*
*********************************************************************************************************
*                                         ECT_PWM_Dis()
*
* Description : This function safely stops the specified PWM channel with the output pin
*               in the specified state.
*
* Arguments   : channel,            The ECT and SW PWM channel to stop (0-7)
*                                   or (4-7) depending on the derivative
*                
*               last,               The state of the output pin after the last transition has ooccured.
*                                  (ECT_PWM_LAST_LOW = logic low, ECT_PWM_LAST_HIGH = logic high)
* 
* Returns     : ECT_PWM_ERR_NONE,   No error has occured.
*               ECT_PWM_ERR_CHA,    Error. An invalid channel number was specified
*               ECT_PWM_ERR_RESV,   Error. The reserved channel number was specified
*               ECT_PWM_ERR_LAST,   Error. An invalid value for 'last' has been specified
*               ECT_PWM_ERR_OFF,    Error. The PWM channel is already disabled.
*********************************************************************************************************
*/

CPU_INT08U  ECT_PWM_Dis (CPU_INT08U  channel, CPU_INT08U last)					
{
    if (channel > 7) {
        return (ECT_PWM_ERR_CHA);                                       /* Channel number > 7 is invalid                            */
    }
    
    if ((ECT_NBR_CHANNELS == 4) && (channel < 4)) {                     /* Only 4 channels, 4-7, supported on this derivative       */
        return (ECT_PWM_ERR_CHA);
    }

    if ((channel == 7) && (ECT_PWM_ERR_RESV > 0)) {
        return (ECT_PWM_ERR_RESV);                                      /* Invalid channel number. Channel 7 is reserved            */
    }
   
    if ((last != ECT_PWM_LAST_LOW) && (last != ECT_PWM_LAST_HIGH)) {    /* Invalid value for last. Must be 0 or 1                   */
        return (ECT_PWM_ERR_LAST);    
    }
    
    if ((TIE & (1 << channel)) == 0) {                                  /* Disabling the PWM has no meaning if it is already off    */
        return (ECT_PWM_ERR_OFF);                                       /* Return an error code indicating this condition           */
    }
            
    CPU_CRITICAL_ENTER();    
    ECT_PWM_DisLast[channel][ECT_DIS]  = 1;
    ECT_PWM_DisLast[channel][ECT_LAST] = last;
    CPU_CRITICAL_EXIT();
    
    return (ECT_PWM_ERR_NONE);                                          /* Return without error                                     */
}

/*
*********************************************************************************************************
*                                         ECT_PWM_ISR()
*
* Description : This function serves as the interrupt service routine for ALL PWM channels. The
*               interrupting channel is identified and reconfigured for the next Mark or Space
*               depending on the current level of the output pin. The application programmer
*               MUST set an interrupt vector to this function for each channel of PWM that they 
*               wish to implement in their application. 
*
* Arguments   : None.
*
* Returns     : None.
*
* Notes       : This function MUST be located in NON_BANKED memory.
*********************************************************************************************************
*/

#pragma CODE_SEG NON_BANKED
interrupt CPU_VOID  ECT_PWM_ISR (CPU_VOID)
{
    CPU_INT08U   flags;
    CPU_INT08U   oln_bit;
    CPU_INT08U   i;
    CPU_INT16U  *ptcn_base;
    CPU_INT16U  *ptcn;
    CPU_INT08U   last_channel;
           
        
    ptcn_base    =  ((CPU_INT08U *)(&TC4)) - 8;                         /* All derivatives have TC4. Get the address of TC4 and     */
    
    flags  =  TFLG1;                                                    /* Read the flags reg, determine which channel interrupted  */

    if (ECT_PWM_RESV_TC7 > 0) {                                         /* Check for channels 4-6 and possibly 7 if not rsvd        */    
        last_channel = 6;                                               /* If ECT TC7 is reserved, then final loop value is 6       */
    } else {
        last_channel = 7;                                               /* If ECT TC7 not reserved, then final loop value is 7      */
    }
              
#if (ECT_NBR_CHANNELS == 8)                                             /* If 8 channels available, test flags for channels 0-4     */ 
    for (i = 0; i < 4; i++) {
        if ((flags & (1 << i)) > 0) {                                   /* If channel 'i' interrupted                               */            
            ptcn        =  (ptcn_base + i);                             /* Determine address of TCn register to modify              */
            oln_bit     =  (i * 2);                                     /* Determine OLn bit position of channel 'i'                */

            if ((TCTL2 & (1 << oln_bit)) > 0) {                         /* If channel is set to generate rising edge                */
               *ptcn   +=   Mark[i];                                    /* Set up timer compare for mark (on) time, clear TCn flag  */
                TCTL2  &= ~(1 << oln_bit);                              /* Set pin action to falling edge                           */                      
                if ((ECT_PWM_DisLast[i][ECT_DIS]  == 1) &&              /* If stopping PWM channel 'i' with pin polarity high       */
                    (ECT_PWM_DisLast[i][ECT_LAST] == ECT_PWM_LAST_HIGH)) {
                     TIE   &= ~(1 << i);                                /* Disable interrupts for PWM channel 'i'                   */                    
                }
            } else {                                                    /* Channel is set to generate a falling edge                */
               *ptcn   +=   Space[i];                                   /* Set up timer compare for space (off) time                */
                TCTL2  |=  (1 << oln_bit);                              /* Set pin action to rising edge                            */                      
                if ((ECT_PWM_DisLast[i][ECT_DIS]  == 1) &&              /* If stopping PWM channel 'i' with pin polarity low        */
                    (ECT_PWM_DisLast[i][ECT_LAST] == ECT_PWM_LAST_LOW)) {
                     TIE   &= ~(1 << i);                            /* Disable interrupts for PWM channel 'i'                   */                    
                }
            }

            TFLG1      |=  (1 << i);                                    /* Clear the interrupt flag for TCn, where n = i.           */    
        }
    }
#endif    
                                                                     
    for (i = 4; i <= last_channel; i++) {
        if ((flags & (1 << i)) > 0) {                                   /* If channel 'i' interrupted                               */            
            ptcn        =  (ptcn_base + i);                             /* Determine address of TCn register to modify              */
            oln_bit     = ((i - 4) * 2);                                /* Determine OLn bit position of channel 'i'                */

            if ((TCTL1 & (1 << oln_bit)) > 0) {                         /* If channel is set to generate rising edge                */
               *ptcn   +=   Space[i];                                   /* Set up timer compare for space (off) time                */
                TCTL1  &= ~(1 << oln_bit);                              /* Set pin HIGH for Mark # of ticks. Next compare set LOW   */                      
                if ((ECT_PWM_DisLast[i][ECT_DIS]  == 1) &&              /* If stopping PWM channel 'i' with pin polarity high       */
                    (ECT_PWM_DisLast[i][ECT_LAST] == ECT_PWM_LAST_HIGH)) {
                     TIE   &= ~(1 << i);                                /* Disable interrupts for PWM channel 'i'                   */                    
                }
            } else {                                                    /* Channel is set to generate a falling edge                */
               *ptcn   +=   Mark[i];                                    /* Set up timer compare for mark (on) time, clear TCn flag  */
                TCTL1  |=  (1 << oln_bit);                              /* Set pin LOW for Space # of ticks. Next compare set HIGH  */                      
                if ((ECT_PWM_DisLast[i][ECT_DIS]  == 1) &&              /* If stopping PWM channel 'i' with pin polarity low        */
                    (ECT_PWM_DisLast[i][ECT_LAST] == ECT_PWM_LAST_LOW)) {
                     TIE   &= ~(1 << i);                                /* Disable interrupts for PWM channel 'i'                   */                    
                }
            }
        
            TFLG1      |=  (1 << i);                                    /* Clear the interrupt flag for TCn, where n = i.           */                
        }
    }
}
#pragma CODE_SEG DEFAULT_ROM

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -