Rath-HAL - TIMER IC 接收 PWM 信号
2021-07-28 本文已影响0人
T_K_233
器材
- 1x Tequila Nano + RA_LINK 调试器
电路连接
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);
}