MRT有三种模式
可以利用重复中断的功能给GPIO电平拉高或拉低,但这种方式不是被逼无奈不要使用,经测量输出的PWM一个管脚的情况下,频率和占空比还算可以,当多路GPIO时输出的波形都不够准确。
先根据时钟总线设计MRT的轮询时间(1us轮询时间)
#define MRT_CLK_FREQ CLOCK_GetFreq(kCLOCK_BusClk)
void MRT0_init(void)
{
uint32_t mrt_clock;
/* Structure of initialize MRT */
mrt_config_t mrtConfig;
mrt_clock = MRT_CLK_FREQ;
/* mrtConfig.enableMultiTask = false; */
MRT_GetDefaultConfig(&mrtConfig);
/* Init mrt module */
MRT_Init(MRT0, &mrtConfig);
/* Setup Channel 0 to be repeated */
MRT_SetupChannelMode(MRT0, kMRT_Channel_1, kMRT_RepeatMode);
/* Enable timer interrupts for channel 0 */
MRT_EnableInterrupts(MRT0, kMRT_Channel_1, kMRT_TimerInterruptEnable);
/* Enable at the NVIC */
EnableIRQ(MRT0_IRQn);
/* Start channel 1 */
//printf("\r\nStarting channel No.0 ...");
if (USEC_TO_COUNT(1U, mrt_clock) > MRT_CHANNEL_INTVAL_IVALUE_MASK) //1us interrupt
{
mrtDividerValue = 0;
mrtEnableCount = true;
while (USEC_TO_COUNT((1U >> (++mrtDividerValue)), mrt_clock) > MRT_CHANNEL_INTVAL_IVALUE_MASK)
{
}
MRT_StartTimer(MRT0, kMRT_Channel_1, USEC_TO_COUNT((1U >> mrtDividerValue), mrt_clock));
}
else
{
MRT_StartTimer(MRT0, kMRT_Channel_1, USEC_TO_COUNT(1U, mrt_clock));
}
}
在MRT0中断里输入频率,占空比,利用中断产生时间计算,得到相应的PWM产生频率占空比
void MRT0_IRQHandler(void)
{
/* Clear interrupt flag.*/
MRT_ClearStatusFlags(MRT0, kMRT_Channel_1, kMRT_TimerInterruptFlag);
//利用MRT产生时间轮询功能
// if (mrtEnableCount == true)
// {
// mrtCountValue++;
// if (mrtCountValue == (1 << mrtDividerValue))
// {
// mrtIsrFlag = true;
// }
// }
// else
// {
// mrtIsrFlag = true;
// }
mrtCountValue++;
if (mrtCountValue == 0xFFFFFFFF)
{
mrtCountValue = 0;
//mrtIsrFlag = true;
}
if(mrtCountValue%2 == 0)
{
GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT01_PORT , BOARD_INITPINS_PWM_OUT01_PIN , 1);
}
else
{
GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT01_PORT , BOARD_INITPINS_PWM_OUT01_PIN , 0);
}
if (mrtCountValue == 0xFFFFFFFF)
{
mrtCountValue = 0;
//mrtIsrFlag = true;
}
//control GPIO
if(GPIO_PWM_Freq_Counter_OUT1 == 0)
{
//set GPIO high
// GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT01_PORT , BOARD_INITPINS_PWM_OUT01_PIN , 1);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT02_PORT , BOARD_INITPINS_PWM_OUT02_PIN , 1);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT03_PORT , BOARD_INITPINS_PWM_OUT03_PIN , 1);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT04_PORT , BOARD_INITPINS_PWM_OUT04_PIN , 1);
}
GPIO_PWM_Freq_Counter_OUT1++;
if(GPIO_PWM_Freq_Counter_OUT1 == 556000/(GPIO_PWM_Freq_OUT1))
{
GPIO_PWM_Freq_Counter_OUT1 = 0;
}
if(GPIO_PWM_Freq_Counter_OUT1 == (5560*GPIO_PWM_Duty_OUT1)/(GPIO_PWM_Freq_OUT1))
{
//set GPIO low
GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT01_PORT , BOARD_INITPINS_PWM_OUT01_PIN , 0);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT02_PORT , BOARD_INITPINS_PWM_OUT02_PIN , 0);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT03_PORT , BOARD_INITPINS_PWM_OUT03_PIN , 0);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT04_PORT , BOARD_INITPINS_PWM_OUT04_PIN , 0);
}
//out2
if(GPIO_PWM_Freq_Counter_OUT2 == 0)
{
//set GPIO high
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT01_PORT , BOARD_INITPINS_PWM_OUT01_PIN , 1);
GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT02_PORT , BOARD_INITPINS_PWM_OUT02_PIN , 1);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT03_PORT , BOARD_INITPINS_PWM_OUT03_PIN , 1);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT04_PORT , BOARD_INITPINS_PWM_OUT04_PIN , 1);
}
GPIO_PWM_Freq_Counter_OUT2++;
if(GPIO_PWM_Freq_Counter_OUT2 == 556000/(GPIO_PWM_Freq_OUT2))
{
GPIO_PWM_Freq_Counter_OUT2 = 0;
}
if(GPIO_PWM_Freq_Counter_OUT2 == (5560*GPIO_PWM_Duty_OUT2)/(GPIO_PWM_Freq_OUT2))
{
//set GPIO low
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT01_PORT , BOARD_INITPINS_PWM_OUT01_PIN , 0);
GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT02_PORT , BOARD_INITPINS_PWM_OUT02_PIN , 0);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT03_PORT , BOARD_INITPINS_PWM_OUT03_PIN , 0);
//GPIO_PinWrite(GPIO, BOARD_INITPINS_PWM_OUT04_PORT , BOARD_INITPINS_PWM_OUT04_PIN , 0);
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}