b49c9ab0c6
完整实现了以下模块: - 系统数据总线(sys_data_bus)模块间通信 - UART/USART/LPUART驱动 + RS485半双工 - I2C驱动(AS5600角度传感器 + AT24C02 EEPROM) - Modbus RTU从站协议 - 步进电机微步进控制(正弦/余弦换相+S曲线加减速) - 到位开关驱动(DI_MIN/DI_MAX) - PGA+ADC电流检测 - 系统监控任务(内存/串口/传感器/任务状态) - LED/Key外设驱动 - 基于CMake + arm-none-eabi-gcc构建系统
164 lines
3.1 KiB
C
164 lines
3.1 KiB
C
#include "timer_driver.h"
|
|
#include "py32md530.h"
|
|
#include "system_py32md530.h"
|
|
#include "config.h"
|
|
|
|
ret_code_t timer_pwm_init(uint32_t freq_hz)
|
|
{
|
|
uint32_t prescaler, period;
|
|
|
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
|
|
|
TIM1->CR1 &= ~TIM_CR1_CEN;
|
|
TIM1->SR = 0;
|
|
TIM1->BDTR |= TIM_BDTR_MOE_Msk;
|
|
TIM1->BDTR &= ~TIM_BDTR_BKE_Msk;
|
|
|
|
prescaler = (SystemCoreClock / 1000000) - 1;
|
|
|
|
period = (1000000 / freq_hz) - 1;
|
|
|
|
TIM1->PSC = prescaler;
|
|
TIM1->ARR = period;
|
|
|
|
TIM1->CCMR1 = (0x6 << 4)
|
|
| (0x6 << 12);
|
|
|
|
TIM1->CCMR2 = (0x6 << 4);
|
|
|
|
TIM1->CCER |= TIM_CCER_CC1E_Msk
|
|
| TIM_CCER_CC2E_Msk
|
|
| TIM_CCER_CC3E_Msk;
|
|
|
|
TIM1->CCER |= TIM_CCER_CC1NE_Msk
|
|
| TIM_CCER_CC2NE_Msk
|
|
| TIM_CCER_CC3NE_Msk;
|
|
|
|
TIM1->BDTR |= TIM_BDTR_MOE_Msk;
|
|
|
|
TIM1->EGR |= TIM_EGR_UG_Msk;
|
|
|
|
TIM1->CR1 |= TIM_CR1_ARPE_Msk;
|
|
TIM1->CR1 |= TIM_CR1_CEN_Msk;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
ret_code_t timer_stepper_pwm_init(uint32_t freq_hz, uint16_t resolution)
|
|
{
|
|
if (resolution == 0) return RET_INVALID_PARAM;
|
|
|
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
|
|
|
TIM1->CR1 &= ~TIM_CR1_CEN;
|
|
TIM1->SR = 0;
|
|
|
|
TIM1->PSC = 0;
|
|
|
|
TIM1->ARR = resolution - 1;
|
|
|
|
TIM1->CCMR1 = (0x6 << 4)
|
|
| (0x6 << 12);
|
|
|
|
TIM1->CCMR2 = 0;
|
|
|
|
TIM1->CCER |= TIM_CCER_CC1E_Msk
|
|
| TIM_CCER_CC2E_Msk;
|
|
|
|
TIM1->CCER |= TIM_CCER_CC1NE_Msk
|
|
| TIM_CCER_CC2NE_Msk;
|
|
|
|
TIM1->CCER &= ~(TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk);
|
|
|
|
TIM1->BDTR |= TIM_BDTR_MOE_Msk;
|
|
|
|
TIM1->EGR |= TIM_EGR_UG_Msk;
|
|
|
|
TIM1->CR1 |= TIM_CR1_ARPE_Msk;
|
|
TIM1->CR1 |= TIM_CR1_CEN_Msk;
|
|
|
|
(void)freq_hz;
|
|
return RET_OK;
|
|
}
|
|
|
|
ret_code_t timer_pwm_set_duty(timer_channel_t ch, uint16_t duty)
|
|
{
|
|
switch (ch) {
|
|
case TIMER_CHANNEL_1:
|
|
TIM1->CCR1 = duty;
|
|
break;
|
|
case TIMER_CHANNEL_2:
|
|
TIM1->CCR2 = duty;
|
|
break;
|
|
case TIMER_CHANNEL_3:
|
|
TIM1->CCR3 = duty;
|
|
break;
|
|
default:
|
|
return RET_INVALID_PARAM;
|
|
}
|
|
return RET_OK;
|
|
}
|
|
|
|
ret_code_t timer_pwm_set_compare(timer_channel_t ch, uint16_t compare)
|
|
{
|
|
return timer_pwm_set_duty(ch, compare);
|
|
}
|
|
|
|
ret_code_t timer_pwm_start(void)
|
|
{
|
|
TIM1->CR1 |= TIM_CR1_CEN_Msk;
|
|
TIM1->BDTR |= TIM_BDTR_MOE_Msk;
|
|
return RET_OK;
|
|
}
|
|
|
|
ret_code_t timer_pwm_stop(void)
|
|
{
|
|
TIM1->BDTR &= ~TIM_BDTR_MOE_Msk;
|
|
TIM1->CR1 &= ~TIM_CR1_CEN_Msk;
|
|
return RET_OK;
|
|
}
|
|
|
|
ret_code_t timer_pwm_deinit(void)
|
|
{
|
|
TIM1->CR1 &= ~TIM_CR1_CEN_Msk;
|
|
TIM1->BDTR = 0;
|
|
TIM1->CCER = 0;
|
|
TIM1->SR = 0;
|
|
|
|
RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
|
|
return RET_OK;
|
|
}
|
|
|
|
ret_code_t timer_encoder_init(void)
|
|
{
|
|
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
|
|
|
TIM3->CR1 &= ~TIM_CR1_CEN;
|
|
TIM3->SR = 0;
|
|
|
|
TIM3->PSC = 0;
|
|
TIM3->ARR = 0xFFFF;
|
|
|
|
TIM3->SMCR = (0x3 << 0);
|
|
|
|
TIM3->CCMR1 = (0x01 << 0)
|
|
| (0x01 << 8);
|
|
|
|
TIM3->CCER = 0;
|
|
|
|
TIM3->EGR |= TIM_EGR_UG_Msk;
|
|
TIM3->CR1 |= TIM_CR1_CEN_Msk;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
uint16_t timer_encoder_get_count(void)
|
|
{
|
|
return (uint16_t)TIM3->CNT;
|
|
}
|
|
|
|
void timer_encoder_clear_count(void)
|
|
{
|
|
TIM3->CNT = 0;
|
|
}
|