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来产生方波,从而产生正玄波来驱动电机转动;由于资料有限,基本上属于闭门造车,如果有前辈知道如何处理,希望指教一下,在此不胜感激; |