AT32F403A を使ってみた その3
「ドラクエのアレ」を AT32F403A で動かす
タイマー/PWM
CH32V003/203 や GD32VF103 で Systick を使った例である「ドラクエのアレ」を AT32F403A の Firmlib に移植する。 タイマー系の操作はレジスタの名前が違うなどいろいろあるが、さほど難しくはないと思う。
CH32Vの場合
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ccp;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
AT32F403Aの場合
tmr_base_init(TMR1, arr, psc);
tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);
tmr_output_default_para_init(&tmr_oc_init_structure);
tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
tmr_oc_init_structure.oc_idle_state = FALSE;
tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_oc_init_structure.oc_output_state = TRUE;
tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, ccp);
tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_1, TRUE);
tmr_period_buffer_enable(TMR1, TRUE);
tmr_output_enable(TMR1, TRUE);
tmr_counter_enable(TMR1, TRUE);
Systick 割り込み
問題は Systick である。 AT32F403A の Systick は STM32 と同じく 24bit のタイプで、普通に ARM 提供の Systick_Config 関数があるのでそれを使えば定期的に割り込みをかけてくれる。 唯一嵌ったのは割り込みハンドラである。
AT32F403A の firmlib では at32f403a_407int.c
で一通りの割り込みハンドラが定義されていて、SysTick_Handler
もここに定義されている。
よって自前の Systick 割り込みハンドラを登録するには、at32f403a_407int.c
の Systick_Handler中で自前の関数を呼び出すようにするか、
Systick_Handler 関数自体をコメントアウトしておく必要がある。
公式の例(cortex_m4/systick_interrupt) では前者を採用していたので、ここでもそれを踏襲することとした。
/**
* @brief this function handles systick handler.
* @param none
* @retval none
*/
void SysTick_Handler(void)
{
systick_handler();
}
CH32V のライブラリでは割り込みハンドラは weak を使って定義されていて、自前の関数を書けば勝手にオーバーライドされたので、ちょっと面倒ではある。
とりあえず完成したサンプルがhttps://github.com/shippoiincho/at32f403a_examples/tree/master/polytone