打印
[Cortex-M0技术交流]

M058LBN 使用pwm中断出现问题

[复制链接]
2318|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jiangmali|  楼主 | 2014-2-12 19:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

void SYS_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock                                                                                       */
/*---------------------------------------------------------------------------------------------------------*/

    /* Enable Internal RC clock */
    SYSCLK->PWRCON |= SYSCLK_PWRCON_IRC22M_EN_Msk;

    /* Waiting for IRC22M clock ready */
    SYS_WaitingForClockReady(SYSCLK_CLKSTATUS_IRC22M_STB_Msk);

    /* Switch HCLK clock source to internal RC */
    SYSCLK->CLKSEL0 = SYSCLK_CLKSEL0_HCLK_IRC22M;

    /* Set PLL to power down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware.*/
    SYSCLK->PLLCON |= SYSCLK_PLLCON_PD_Msk;

    /* Enable external 12MHz XTAL, internal 22.1184MHz, 10kHz */
    SYSCLK->PWRCON |= SYSCLK_PWRCON_XTL12M_EN_Msk | SYSCLK_PWRCON_IRC22M_EN_Msk | SYSCLK_PWRCON_IRC10K_EN_Msk;

    /* Enable PLL and Set PLL frequency */        
    SYSCLK->PLLCON = PLLCON_SETTING;
   
    /* Waiting for clock ready */
    SYS_WaitingForClockReady(SYSCLK_CLKSTATUS_PLL_STB_Msk | SYSCLK_CLKSTATUS_XTL12M_STB_Msk  | SYSCLK_CLKSTATUS_IRC10K_STB_Msk |
                             SYSCLK_CLKSTATUS_IRC22M_STB_Msk);

    /* Switch HCLK clock source to PLL, STCLK to HCLK/2 */
    SYSCLK->CLKSEL0 = SYSCLK_CLKSEL0_STCLK_HCLK_DIV2 | SYSCLK_CLKSEL0_HCLK_PLL;

    /* Enable IP clock */        
    SYSCLK->APBCLK = SYSCLK_APBCLK_ACMP_EN_Msk | SYSCLK_APBCLK_ADC_EN_Msk | SYSCLK_APBCLK_PWM67_EN_Msk |
                        SYSCLK_APBCLK_PWM45_EN_Msk | SYSCLK_APBCLK_UART1_EN_Msk | SYSCLK_APBCLK_UART0_EN_Msk | SYSCLK_APBCLK_SPI1_EN_Msk |
                        SYSCLK_APBCLK_SPI0_EN_Msk | SYSCLK_APBCLK_I2C0_EN_Msk | SYSCLK_APBCLK_FDIV_EN_Msk |
                        SYSCLK_APBCLK_TMR3_EN_Msk | SYSCLK_APBCLK_TMR2_EN_Msk | SYSCLK_APBCLK_TMR1_EN_Msk |
                        SYSCLK_APBCLK_TMR0_EN_Msk | SYSCLK_APBCLK_WDT_EN_Msk;

    /* Select IP clock source */
    SYSCLK->CLKSEL1 = SYSCLK_CLKSEL1_UART_PLL|
                         SYSCLK_CLKSEL1_TMR3_XTAL | SYSCLK_CLKSEL1_TMR2_XTAL | SYSCLK_CLKSEL1_TMR1_HCLK |
                         SYSCLK_CLKSEL1_TMR0_HCLK  | SYSCLK_CLKSEL1_ADC_HCLK | SYSCLK_CLKSEL1_WDT_IRC10K;

    SYSCLK->CLKSEL2 = SYSCLK_CLKSEL2_PWM67_HCLK| SYSCLK_CLKSEL2_PWM45_HCLK| SYSCLK_CLKSEL2_FRQDIV_HCLK;
   
  ///  FMC->ISPCON |= FMC_ISPCON_ISPEN_Msk;   /*isp 功能使能*/
   
    /* IP clock divider */
    SYSCLK->CLKDIV = SYSCLK_CLKDIV_ADC(7) |  // ADC clock = ADC clock source / 7
                        SYSCLK_CLKDIV_UART(1) | // UART clock = UART clock source / 1
                        SYSCLK_CLKDIV_HCLK(1);  // HCLK clock = HCLK clock source / 1


    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
    //SystemCoreClockUpdate();
    PllClock        = PLL_CLOCK;            // PLL
    SystemCoreClock = PLL_CLOCK / 1;        // HCLK
    CyclesPerUs     = PLL_CLOCK / 1000000;  // For SYS_SysTickDelay()


/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function                                                                                 */
/*---------------------------------------------------------------------------------------------------------*/
    /*
       P0.0, P0.1  for UART1 - TXD1, RXD1
       P0.2, P0.3  for UART0 - CTS0, RTS0
       P0.4 ~ P0.7 for SPI1  - SPISS1, MOSI_1, MISO_1, SPICLK1
    */
   
    SYS->P0_MFP = SYS_MFP_P00_TXD1 | SYS_MFP_P01_RXD1 ;  /*| SYS_MFP_P02_CTS0 | SYS_MFP_P03_RTS0 |
                     SYS_MFP_P04_SPISS1 | SYS_MFP_P05_MOSI_1 | SYS_MFP_P06_MISO_1 | SYS_MFP_P07_SPICLK1*/

    SYS->P1_MFP = SYS_MFP_P10_T2 | SYS_MFP_P11_T3 | SYS_MFP_P12_AIN2 | SYS_MFP_P13_AIN3 |
                     SYS_MFP_P14_SPISS0 | SYS_MFP_P15_MOSI_0 | SYS_MFP_P16_MISO_0 | SYS_MFP_P17_SPICLK0;

    /* P2.0 ~ P2.7 for PWM0 ~ PWM7 */
   /*
    SYS->P2_MFP = SYS_MFP_P20_PWM0 | SYS_MFP_P21_PWM1 | SYS_MFP_P22_PWM2 | SYS_MFP_P23_PWM3 |
                                     SYS_MFP_P24_PWM4 | SYS_MFP_P25_PWM5 | SYS_MFP_P26_PWM6 | SYS_MFP_P27_PWM7;
*/
        SYS->P2_MFP |= SYS_MFP_P20_GPIO|SYS_MFP_P21_GPIO|SYS_MFP_P22_GPIO|SYS_MFP_P23_GPIO;
       SYS->P2_MFP |= SYS_MFP_P24_PWM4 | SYS_MFP_P25_PWM5 | SYS_MFP_P26_PWM6 | SYS_MFP_P27_PWM7;         

    /*
       P3.0, P3.1 for UART0  - RXD0, TXD0
       P3.2       for TIMER1 - T1EX (external capture/reset trigger input)
       P3.3       for TIMER0 - T0EX (external capture/reset trigger input)
       P3.4, P3.5 for I2C0   - SDA0, SCL0
       P3.6       for CKO
       P3.7       for GPIO
    */
    SYS->P3_MFP = SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0 | SYS_MFP_P32_T0EX | SYS_MFP_P33_T1EX |
                             SYS_MFP_P34_T0 | SYS_MFP_P35_T1 | SYS_MFP_P36_GPIO | SYS_MFP_P37_GPIO;
                     
    SYS_LockReg();
                        
}

void PWMB_Init(void)
{
    PWMB->PPR = PWM_PPR_CP01(2) | PWM_PPR_CP23(2);
    PWMB->CSR = PWM_CSR_CSR0(PWM_CSR_DIV1) | PWM_CSR_CSR1(PWM_CSR_DIV1) |
                          PWM_CSR_CSR2(PWM_CSR_DIV1) | PWM_CSR_CSR3(PWM_CSR_DIV1);

    /* Enable PWM0, PWM1, PWM2, PWM3 counter. We must set PWM mode before setting CNR, CMR. */
    PWMB->PCR |=  PWM_PCR_CH0MOD_AUTO_RELOAD | PWM_PCR_CH1MOD_AUTO_RELOAD |PWM_PCR_CH2MOD_AUTO_RELOAD |PWM_PCR_CH3MOD_AUTO_RELOAD;
//   PWMB->PCR |=  PWM_PCR_CH0EN_Msk |PWM_PCR_CH1EN_Msk |PWM_PCR_CH2EN_Msk | PWM_PCR_CH3EN_Msk;

   
    PWMB->PIER |= PWM_PIER_PWMIE0_Msk;           
    PWMB->PIER |= PWM_PIER_PWMIE1_Msk;   
    PWMB->PIER |= PWM_PIER_PWMIE2_Msk;           
    PWMB->PIER |= PWM_PIER_PWMIE3_Msk;

    NVIC_SetPriority(PWMB_IRQn, 1); //设置中断优先级 为1
    NVIC_EnableIRQ((PWMB_IRQn));

    /* Enable PWM channle 0, 1, 2, 3 Output */
  PWMB->POE = PWM_POE_PWM0_Msk | PWM_POE_PWM1_Msk | PWM_POE_PWM2_Msk | PWM_POE_PWM3_Msk;

}

void UART1_Init(void)
{
    /* Set 9600 baudrate according to 50MHz system clock  :   */
    UART1->BAUD = UART_BAUD_MODE2 | UART_BAUD_DIV_MODE2(PLL_CLOCK, 9600);
    _UART_SET_DATA_FORMAT(UART1, UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1);
    _UART_ENABLE_INT(UART1, (UART_IER_RDA_IEN_Msk | UART_IER_THRE_IEN_Msk | UART_IER_RTO_IEN_Msk));
    ///_UART_ENABLE_INT(UART1, ( UART_IER_THRE_IEN_Msk));
    NVIC_SetPriority(UART1_IRQn, 0); //设置中断优先级为 0
    NVIC_EnableIRQ(UART1_IRQn);
}


void UART1_IRQHandler(void)
{
        uint8_t u8InChar=0xFF;
        uint32_t u32IntSts= UART1->ISR;
        static uint8_t i = 0;
        uint8_t j=0;
       
        if(u32IntSts & UART_ISR_RDA_INT_Msk)
        {
                if(_UART_IS_RX_READY(UART1))
                {
                         _UART_RECEIVEBYTE(UART1,u8InChar);           /* Rx trigger level is 1 byte*/   

                        buf[i++] = u8InChar;
               
                        if((i%7) == 0)
                        {
                                rear = (rear+7)%28;
                                i = i%28;
                        }

                }
}


void PWMB_IRQHandler(void)
{
        NVIC_DisableIRQ        ((PWMB_IRQn));

        _PWM_CLR_CAP_INT_FLAG(PWMB,PWM_CH0);
        _PWM_CLR_CAP_INT_FLAG(PWMB,PWM_CH1);
        _PWM_CLR_CAP_INT_FLAG(PWMB,PWM_CH2);
        _PWM_CLR_CAP_INT_FLAG(PWMB,PWM_CH3);
       
     if(VMotor.able == ENABLE_PWM)
     {
                    PWMB->CNR0= 256 - 1;
                    PWMB->CMR0= Ref[VMotor.count0];
                   PWMB->CNR1= 256 - 1;
                    PWMB->CMR1= Ref[VMotor.count1];

               VMotor.count0 ++;
                VMotor.count1 ++;
                if(VMotor.count0 > 719)
                {
                        VMotor.count0 = 0;
                        VMotor.ph1=!VMotor.ph1;
                        PHASE1 =!PHASE1;
                }
               
                if(VMotor.count1 > 719)
                {
                        VMotor.count1 = 0;
                        VMotor.ph2 = !VMotor.ph2;
                        PHASE2 = !PHASE2;
                }
        }

        if(HMotor.able == ENABLE_PWM)
        {
               PWMB->CNR2= 256 - 1;
                    PWMB->CMR2= Ref[HMotor.count0];
                   PWMB->CNR3= 256 - 1;
                    PWMB->CMR3= Ref[HMotor.count1];

               HMotor.count0 ++;
                HMotor.count1 ++;
                if(HMotor.count0 > 719)
                {
                        HMotor.count0 = 0;
                        HMotor.ph1 = !HMotor.ph1;
                        PHASE3 = !PHASE3;
                }
               
                if(HMotor.count1 > 719)
                {
                        HMotor.count1 = 0;
                        HMotor.ph2 = !HMotor.ph2;
                        PHASE4 = !PHASE4;
                }
        }

         NVIC_EnableIRQ((PWMB_IRQn));
}

int main(void)
{

    uint8_t i;
   SYS_Init();
   
   HMotor_Init();
   VMotor_Init();
           
    GPIO_Init();

      PWMB_Init();
  UART1_Init();

  Motor_Direction(CLOCKWISE,&HMotor);
  Motor_Start(1, &HMotor);

   Motor_Direction(ANTICLOCK,&VMotor);
   Motor_Start(1, &VMotor);

   while(1);       
}

新塘m0系列m058LBN 单片机,使用pwm产生方波时出现的问题;
pwm中断函数每次中断都改变占空比,最后通过 RC振荡电路来产生正玄波;来驱动电机转动; 电机驱动芯片为A3988;

问题点如下:
1. 如果同时开启    PWMB_Init(); 和 UART1_Init();的初始化函数,会导致pwm中断 函数无**常工作,没有波形产生;串口中断也不正常工作;
2.如果只开启  PWMB_Init(); 屏蔽掉 ///UART1_Init();此时pwm中断函数正常工作。有波形产生。

本人初学m0,想用pwm来产生方波,从而产生正玄波来驱动电机转动;由于资料有限,基本上属于闭门造车,如果有前辈知道如何处理,希望指教一下,在此不胜感激;

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

7

帖子

0

粉丝