【雅特力开发板 AT32F421 测评】定时器PWM输出
本帖最后由 eew_Violet 于 2021-4-28 00:34 编辑<p><span style="font-size:24px;"> 有些地方需要输出有一定相位差的PWM,对于没有异步PWM的片子,这个时候可以利用定时器的PWM1和PWM2模式实现,像这种.</span></p>
<p><span style="font-size:24px;"> 最大占空比一般不超48%,否则会炸管,我已经搞废两个D209L了<img height="27" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/frowning-face-with-open-mouth_1f626.png" width="27" />.接下来我们看下具体如何实现.TIM初始化代码依旧放在了at32_board.c中.</span></p>
<pre>
<code>/*TIM1初始化*/
void TIM_Init()
{
TMR_TimerBaseInitType TIM_TimerBaseStructure;
TMR_OCInitType TMR_OCInitStructure;
GPIO_InitType GPIO_InitStructure;
/* 启用 TIM clock 和 GPIO 时钟*/
RCC_APB2PeriphClockCmd(AT32_TIM_FUNC , ENABLE);
RCC_AHBPeriphClockCmd(AT32_TIM_GPIO_RCC , ENABLE);
/* Configure tim_pins: CH1 CH4
* CH1-->PA8
* CH4-->PA11
*/
//GPIO初始化
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = AT32_TIM_CH1_PIN|AT32_TIM_CH4_PIN ;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
GPIO_Init(AT32_TIM_GPIO, &GPIO_InitStructure);
//GPIO复用到定时器
GPIO_PinAFConfig(AT32_TIM_GPIO, GPIO_PinsSource8, GPIO_AF_2);
GPIO_PinAFConfig(AT32_TIM_GPIO, GPIO_PinsSource11, GPIO_AF_2);
/* 定时器时基配置 为了便于观察先频率调的低些--------------------------------------*/
TMR_TimeBaseStructInit(&TIM_TimerBaseStructure);
TIM_TimerBaseStructure.TMR_Period = 65535-1;
TIM_TimerBaseStructure.TMR_DIV = 6553-1;
TIM_TimerBaseStructure.TMR_ClockDivision = TMR_CKD_DIV2;
TIM_TimerBaseStructure.TMR_CounterMode = TMR_CounterDIR_CenterAligned1;
TMR_TimeBaseInit(AT32_TIM, &TIM_TimerBaseStructure);
/* PWM模式配置: Channe8 */
TMR_OCStructInit(&TMR_OCInitStructure);
TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1;
TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
TMR_OCInitStructure.TMR_Pulse = 0;
TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_High;
TMR_OCInitStructure.TMR_OCIdleState = TMR_OCIdleState_Reset ;
TMR_OC1Init(AT32_TIM, &TMR_OCInitStructure);
TMR_OC1PreloadConfig(AT32_TIM, TMR_OCPreload_Enable);
/* PWM2模式配置: Channe11 */
TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM2;
TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
TMR_OCInitStructure.TMR_Pulse = 0;
TMR_OC4Init(AT32_TIM, &TMR_OCInitStructure);
TMR_OC4PreloadConfig(AT32_TIM, TMR_OCPreload_Enable);
//使能定时器
TMR_Cmd(AT32_TIM,ENABLE);
//使能输出
TMR_CtrlPWMOutputs(TMR1, ENABLE);
}
</code></pre>
<p><span style="font-size:24px;"> 为了便于移植在at32_board.h中宏定义</span></p>
<pre>
<code>/**************** TIM ****************/
#define AT32_TIM TMR1
#define AT32_TIM_GPIO_RCC RCC_AHBPERIPH_GPIOA
#define AT32_TIM_FUNC RCC_APB2PERIPH_TMR1
/*TIM1_CH1*/
#define AT32_TIM_CH1_PIN GPIO_Pins_8
#define AT32_TIM_GPIO GPIOA
/*TIM1_CH4*/
#define AT32_TIM_CH4_PIN GPIO_Pins_11
#define AT32_TIM_GPIO GPIOA
/**************** End TIM****************/</code></pre>
<p><span style="font-size:24px;"> 通道2和通道3让串口给占了,所以这里就用通道1和通道4了</span></p>
<p><span style="font-size:24px;"> 在board.c中调用初始化函数完成初始化.</span></p>
<pre>
<code>void rt_hw_board_init()
{
/* System Clock Update */
SystemCoreClockUpdate();
/* System Tick Configuration */
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* 串口1初始化*/
UART_Print_Init(115200);
/* SPI2初始化 */
SPI2_Init();
OLED_Init();
TIM_Init();
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
</code></pre>
<p><span style="font-size:24px;"> while(1)中写好测试代码</span></p>
<p> <span style="font-size:24px;"> 每100毫秒对比较寄存器自增一次,改变占空比,然后OLED获取并显示比较寄存器的值.</span></p>
<pre>
<code>uint16_t Pulse;
uint8_tdir = 1;
while (1)
{
if(dir == 1)
Pulse++;
if(Pulse>31456)
dir = 0;
if(dir == 0)
Pulse--;
if(Pulse==0)
dir = 1;
//设置比较寄存器
TMR_SetCompare1(AT32_TIM, Pulse);
TMR_SetCompare4(AT32_TIM, 65535-Pulse);
OLED打印寄存器值
OLED_ShowString(5,0,(uint8_t*)"CC1",16);
OLED_ShowNum(5,16,TMR_GetCapture1(AT32_TIM),5,16);
OLED_ShowString(5,30,(uint8_t*)"CC4",16);
OLED_ShowNum(5,46,TMR_GetCapture4(AT32_TIM),5,16);
OLED_Refresh();
rt_thread_mdelay(100);
}</code></pre>
<p></p>
<p><span style="font-size:24px;">这是占空比比较小的时候</span></p>
<p></p>
<p><span style="font-size:24px;">这是占空比比较大的时候,刚才蓝色绿色可能不太容易看出来,这次换个色.</span></p>
<p><span style="font-size:24px;"> 可以看到代码已成功运行</span></p>
<p>看到绿灯亮的还可以</p>
页:
[1]