Rath-HAL - TIMER IC 接收 PWM 信号

2021-07-28  本文已影响0人  T_K_233

器材

电路连接

Tequila Nano
PA6 ---- PB6

用一根跳线连接 Tequila Nano 的 PA6 引脚和 PB6 引脚

原理

代码

/**
 * @file main.c
 * @version 1.0
 * @date 2021-07-28
 *
 */

#include "rath_hal.h"

static void AG_RCU_init(void);
static void AG_ECLIC_init(void);
static void AG_GPIO_init(void);
static void AG_TIMER2_init(void);
static void AG_TIMER3_init(void);
static void AG_USART0_init(void);

uint32_t pwm_period = 0;
uint32_t pwm_on_width = 0;

/**
 * @brief handles PWM input signal
 * 
 */
void TIMER2_IRQHandler() {
  if (HAL_TIMER_getFlag(TIMER2, TIMER_FLAG_CH0)) {
    pwm_period = HAL_TIMER_readChannelCapture(TIMER2, TIMER_CHANNEL_0) + pwm_on_width;
    HAL_TIMER_clearFlag(TIMER2, TIMER_FLAG_CH0);
  }
  if (HAL_TIMER_getFlag(TIMER2, TIMER_FLAG_CH1)) {
    pwm_on_width = HAL_TIMER_readChannelCapture(TIMER2, TIMER_CHANNEL_1) + 1;
    HAL_TIMER_clearFlag(TIMER2, TIMER_FLAG_CH1);
  }
}

int main(void) {
  AG_RCU_init();
  AG_ECLIC_init();
  AG_GPIO_init();
  AG_TIMER2_init();
  AG_TIMER3_init();
  AG_USART0_init();

  while (1) {
    HAL_TIMER_setPeriod(TIMER3, 20000);
    HAL_TIMER_setOCChannelPulse(TIMER3, TIMER_CHANNEL_0, 1500);

    uint32_t pwm_off_width = pwm_period - pwm_on_width;
    float duty_cycle = (float)pwm_on_width / (float)pwm_period;
    printf("period: %lu\ton: %lu\toff: %lu\tduty cycle: %f\n", pwm_period, pwm_on_width, pwm_off_width, duty_cycle);

    /* delay for 0.05 second */
    HAL_delay(100);
  }
}

static void AG_RCU_init(void) {
  HAL_RCU_initDefaultSystemClock();
  
  HAL_RCU_resetPeriphClock(RCU_GPIOA);
  HAL_RCU_resetPeriphClock(RCU_GPIOB);
  HAL_RCU_resetPeriphClock(RCU_TIMER2);
  HAL_RCU_resetPeriphClock(RCU_TIMER3);
  HAL_RCU_resetPeriphClock(RCU_USART0);

  HAL_RCU_enablePeriphClock(RCU_GPIOA);
  HAL_RCU_enablePeriphClock(RCU_GPIOB);
  HAL_RCU_enablePeriphClock(RCU_TIMER2);
  HAL_RCU_enablePeriphClock(RCU_TIMER3);
  HAL_RCU_enablePeriphClock(RCU_USART0);
}

static void AG_GPIO_init(void) {
  GPIO_InitTypeDef GPIO_init;
  
  GPIO_init.pin = GPIO_PIN_6;
  GPIO_init.mode = GPIO_MODE_INPUT;
  GPIO_init.speed = GPIO_SPEED_NONE;
  GPIO_init.pull = GPIO_PULL_DOWN;
  HAL_GPIO_init(GPIOA, &GPIO_init);

  GPIO_init.pin = GPIO_PIN_9;
  GPIO_init.mode = GPIO_MODE_AF_PP;
  GPIO_init.speed = GPIO_SPEED_50MHZ;
  GPIO_init.pull = GPIO_PULL_NONE;
  HAL_GPIO_init(GPIOA, &GPIO_init);

  GPIO_init.pin = GPIO_PIN_10;
  GPIO_init.mode = GPIO_MODE_INPUT;
  GPIO_init.speed = GPIO_SPEED_NONE;
  GPIO_init.pull = GPIO_PULL_NONE;
  HAL_GPIO_init(GPIOA, &GPIO_init);

  GPIO_init.pin = GPIO_PIN_6;
  GPIO_init.mode = GPIO_MODE_AF_PP;
  GPIO_init.speed = GPIO_SPEED_50MHZ;
  GPIO_init.pull = GPIO_PULL_NONE;
  HAL_GPIO_init(GPIOB, &GPIO_init);
}

static void AG_ECLIC_init(void) {
  HAL_ECLIC_setPriorityGroup(ECLIC_GROUP_LEVEL4_PRIO0);

  HAL_ECLIC_enableIRQ(TIMER2_IRQn, 1, 0);

  HAL_ECLIC_enableGlobalInterrupt();
}

static void AG_TIMER2_init(void) {  
  HAL_TIMER_disable(TIMER2);

  /* PSC = 107 + 1, freq = 1MHz, period = 0xFFFF -> 
     maximum capture period = 0xFFFF * (1 / 1MHz) = 65.5ms */
  TIMER_InitTypeDef TIMER2_init;

  TIMER2_init.prescaler = 107;
  TIMER2_init.counter_mode = TIMER_COUNTERMODE_EDGE_UP;
  TIMER2_init.period = 0xFFFF;
  TIMER2_init.clock_division = TIMER_CLOCKDIVISION_DIV1;
  TIMER2_init.repetition_counter = 0;
  HAL_TIMER_init(TIMER2, &TIMER2_init);

  TIMER_ICInitTypeDef TIMER2_IC_init;

  TIMER2_IC_init.IC_filter = TIMER_IC_FILTER_TIMER_CK_2;
  TIMER2_IC_init.IC_polarity = TIMER_IC_POLARITY_RISING;
  TIMER2_IC_init.IC_prescaler = TIMER_IC_PSC_DIV1;
  TIMER2_IC_init.IC_selection = TIMER_IC_SELECTION_DIRECTTI;
  HAL_TIMER_initICChannel(TIMER2, &TIMER2_IC_init, TIMER_CHANNEL_0);

  TIMER2_IC_init.IC_polarity = TIMER_IC_POLARITY_FALLING;
  TIMER2_IC_init.IC_selection = TIMER_IC_SELECTION_INDIRECTTI;
  HAL_TIMER_initICChannel(TIMER2, &TIMER2_IC_init, TIMER_CHANNEL_1);

  HAL_TIMER_setSlaveTrigger(TIMER2, TIMER_TRIGGERSOURCE_CI0);
  HAL_TIMER_setSlaveMode(TIMER2, TIMER_SLAVEMODE_RESTART_MODE);
  HAL_TIMER_enableSlaveMode(TIMER2);

  HAL_TIMER_enableInterrupt(TIMER2, TIMER_INT_CH0);
  HAL_TIMER_enableInterrupt(TIMER2, TIMER_INT_CH1);

  HAL_TIMER_enable(TIMER2);
}

static void AG_TIMER3_init(void) {
  HAL_TIMER_disable(TIMER3);

  TIMER_InitTypeDef TIMER3_init;

  TIMER3_init.prescaler = 107;
  TIMER3_init.counter_mode = TIMER_COUNTERMODE_EDGE_UP;
  TIMER3_init.period = 20000;
  TIMER3_init.clock_division = TIMER_CLOCKDIVISION_DIV1;
  TIMER3_init.repetition_counter = 0;
  HAL_TIMER_init(TIMER3, &TIMER3_init);

  TIMER_OCInitTypeDef TIMER3_OC_init;

  TIMER3_OC_init.mode = TIMER_OC_MODE_PWM0;
  TIMER3_OC_init.pulse = 1500;
  TIMER3_OC_init.OC_polarity = TIMER_OC_POLARITY_HIGH;
  TIMER3_OC_init.OCN_polarity = TIMER_OC_POLARITY_HIGH;
  TIMER3_OC_init.OC_idle_state = TIMER_OC_IDLE_STATE_LOW;
  TIMER3_OC_init.OCN_idle_state = TIMER_OC_IDLE_STATE_LOW;
  HAL_TIMER_initOCChannel(TIMER3, &TIMER3_OC_init, TIMER_CHANNEL_0);

  HAL_TIMER_enablePrimaryOutput(TIMER3);

  HAL_TIMER_setChannelOutput(TIMER3, TIMER_CHANNEL_0, ENABLE);

  HAL_TIMER_enable(TIMER3);
}

static void AG_USART0_init(void) {
  HAL_USART_disable(USART0);

  USART_InitTypeDef USART0_init;
  USART0_init.mode = USART_MODE_TX_RX;
  USART0_init.baudrate = 115200UL;
  USART0_init.word_length = USART_WORDLENGTH_8BIT;
  USART0_init.stop_bits = USART_STOPBITS_1BIT;
  USART0_init.parity = USART_PARITY_NONE;
  USART0_init.hw_control = USART_HWCONTROL_NONE;
  HAL_USART_init(USART0, &USART0_init);

  HAL_USART_enablePrintFloat();

  HAL_USART_enable(USART0);
}

上一篇下一篇

猜你喜欢

热点阅读