STM32F4のTIMでPWMを出してDACっぽく使うサンプル
使用リソース
- PB6
- TIM3(Basic)
- TIM4(PWM)
- DMA1 ch5
TIM4 ch1をPB6に接続してPWMを出力し、外部のLPFで平滑します。また、TIM3でタイミングを作ってDMAをトリガすることで、周期的にPWMのパルス幅を変更します。
ソースコード
constexpr uint16_t period = 42;
constexpr uint16_t buff_len = 25;
static uint16_t buff[buff_len] = {};
for (uint32_t i = 0; i < buff_len; i++)
{
buff[i] = static_cast<uint16_t>(
period * 0.5f +
period * 0.5f * 0.8f * sinf(static_cast<float>(i) / buff_len * 3.141592f * 2.f) +
0.5f);
}
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_TIM3_CLK_ENABLE();
__HAL_RCC_TIM4_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef gpio = {
.Pin = GPIO_PIN_6,
.Mode = GPIO_MODE_AF_PP,
.Pull = GPIO_NOPULL,
.Speed = GPIO_SPEED_HIGH,
.Alternate = GPIO_AF2_TIM4};
HAL_GPIO_Init(GPIOB, &gpio);
TIM_HandleTypeDef htim1 = {
.Instance = TIM4,
.Init = TIM_Base_InitTypeDef{
.Prescaler = 0,
.CounterMode = TIM_COUNTERMODE_UP,
.Period = period - 1}};
HAL_TIM_PWM_Init(&htim1);
TIM_OC_InitTypeDef oc = {
.OCMode = TIM_OCMODE_PWM1,
.Pulse = period / 2 - 1};
HAL_TIM_PWM_ConfigChannel(&htim1, &oc, TIM_CHANNEL_1);
TIM_HandleTypeDef htim2 = {
.Instance = TIM3,
.Init = TIM_Base_InitTypeDef{
.Prescaler = 0,
.CounterMode = TIM_COUNTERMODE_UP,
.Period = 84 - 1}};
HAL_TIM_Base_Init(&htim2);
__HAL_TIM_ENABLE_DMA(&htim2, TIM_DMA_UPDATE);
DMA_HandleTypeDef hdma = {
.Instance = DMA1_Stream2,
.Init = DMA_InitTypeDef{
.Channel = DMA_CHANNEL_5,
.Direction = DMA_MEMORY_TO_PERIPH,
.PeriphInc = DMA_PINC_DISABLE,
.MemInc = DMA_MINC_ENABLE,
.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD,
.MemDataAlignment = DMA_MDATAALIGN_HALFWORD,
.Mode = DMA_CIRCULAR,
.Priority = DMA_PRIORITY_MEDIUM,
.FIFOMode = DMA_FIFOMODE_DISABLE}};
HAL_DMA_Init(&hdma);
HAL_DMA_Start(&hdma,
reinterpret_cast<uint32_t>(buff),
reinterpret_cast<uint32_t>(&htim1.Instance->CCR1),
buff_len);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_Base_Start(&htim2);
結果
黄色がPWM出力、紫色がCR LPFの後ろです(以下同様)。
168MHzのコアで、2分周がTIMに入り、42分周しているので、2MHzのPWMが出力されています。デューティー比50%付近では三角波状になっていますね。
2MHzなので1周期500ナノ秒、50%で250ナノ秒、のパルスでトリガしています。
PWMに対して通常のエッジトリガを使うと、アナログ波形の位相がロックされず、見づらくなってしまうので、パルス幅でトリができるオシロがあると便利です。アナログ波形のエッジでトリガした場合はPWMの位相がロックされなくなってしまうので、パルス幅でトリガしたほうが見やすいです。
波形転送は1MHzで行い、25ポイントで1周期なので、40kHzのピークが出ています。高調波も出ていますが-40dB程度であまり問題はないと思います。
PWMが2MHzなので、その付近にもピークが出ています。40kHzの第2高調波よりも高く出ています。
今回は2MHzから40kHzを出しているので、50倍程度の差となり、1段のCR LPFでは高周波成分を除去しきれていません。PWM周波数を上げれば多少は改善しますが、今度はデューティー分解能が低下してしまいます。
Author And Source
この問題について(STM32F4のTIMでPWMを出してDACっぽく使うサンプル), 我々は、より多くの情報をここで見つけました https://qiita.com/amutou/items/c182c04dc6f28dec71bf著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .