Files
checker_m4/source/interface/if_pwm.c

359 lines
6.9 KiB
C
Raw Normal View History

2023-06-25 15:30:36 +08:00
#include "board.h"
#include "debug.h"
2023-06-27 18:16:46 +08:00
#include "lock_resource.h"
2023-06-25 15:30:36 +08:00
// 使用定时器14,13
2023-06-25 15:30:36 +08:00
// PF7,8,9 是输出口
2023-06-27 18:16:46 +08:00
// 使用PF7来产生脉冲PF8来改变方向
// PI6 是输入口
// 使用PI6来捕获到位中断
2023-06-27 18:16:46 +08:00
typedef struct{
int tick;
int step;
int fre;
int fre_max;
int fre_min;
int up_tick;
}ctrl_fre;
2023-06-25 15:30:36 +08:00
typedef struct{
TIM_HandleTypeDef htim;
2023-06-27 18:16:46 +08:00
TIM_HandleTypeDef htim2;
EXTI_HandleTypeDef hexti;
2023-06-27 18:16:46 +08:00
int count_all;
int count_past;
int fre;
ctrl_fre cfre;
void (*end_irq)(void *t);
void *t;
2023-06-25 15:30:36 +08:00
}self_def;
2023-06-27 18:16:46 +08:00
2023-06-25 15:30:36 +08:00
static self_def g_self;
static void Exti14FallingCb(void);
2023-06-25 15:30:36 +08:00
static int init(pwm_def *p)
{
self_def *s=&g_self;
if(p->private_data) return 0;
p->private_data=s;
2023-06-27 18:16:46 +08:00
s->cfre.step=320;
s->cfre.fre_min=1100;
2023-06-25 15:30:36 +08:00
s->htim.Instance = TIM14;
s->htim.Init.Prescaler = 209-1;
s->htim.Init.CounterMode = TIM_COUNTERMODE_UP;
2023-06-27 18:16:46 +08:00
s->htim.Init.Period = 31-1;
2023-06-25 15:30:36 +08:00
s->htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
s->htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&s->htim) != HAL_OK)
{
DBG_ERR("time init failed.");
return -1;
}
2023-06-27 18:16:46 +08:00
s->htim2.Instance = TIM13;
s->htim2.Init.Prescaler = 209-1;
s->htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
s->htim2.Init.Period = 1000-1;
s->htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
s->htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&s->htim2) != HAL_OK)
{
DBG_ERR("time init failed.");
return -1;
}
GPIO_InitTypeDef init={0};
__HAL_RCC_GPIOF_CLK_ENABLE();
init.Mode = GPIO_MODE_OUTPUT_PP;
2023-06-27 18:16:46 +08:00
init.Pull = GPIO_NOPULL;
init.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
PERIPH_LOCK(GPIOF);
HAL_GPIO_Init(GPIOF, &init);
PERIPH_UNLOCK(GPIOF);
__HAL_RCC_GPIOI_CLK_ENABLE();
init.Mode = GPIO_MODE_INPUT;
init.Pull = GPIO_NOPULL;
init.Pin = GPIO_PIN_6;
PERIPH_LOCK(GPIOI);
HAL_GPIO_Init(GPIOI, &init);
PERIPH_UNLOCK(GPIOI);
EXTI_ConfigTypeDef init2={0};
init2.Line = EXTI_LINE_14;
init2.Trigger = EXTI_TRIGGER_FALLING;
init2.GPIOSel = EXTI_GPIOA;
init2.Mode = EXTI_MODE_C2_INTERRUPT;
PERIPH_LOCK(EXTI);
HAL_EXTI_SetConfigLine(&s->hexti, &init2);
PERIPH_UNLOCK(EXTI);
/* Register callback to treat Exti interrupts in user Exti14FallingCb function */
HAL_EXTI_RegisterCallback(&s->hexti, HAL_EXTI_FALLING_CB_ID, Exti14FallingCb);
/* Enable and set line 14 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI6_IRQn);
2023-06-27 18:16:46 +08:00
return 0;
}
static int deinit(pwm_def *p)
{
return 0;
}
static int start(pwm_def *p,int step_count)
{
param_check(p);
param_check(p->private_data);
self_def *self=p->private_data;
if(step_count==0) return 0;
if((HAL_GPIO_ReadPin(GPIOI,6)==GPIO_PIN_RESET)&&(step_count<0))
2023-06-27 18:16:46 +08:00
{
// 到达零点后不能继续上升
if(self->end_irq)
self->end_irq(self->t);
return -1;
}
if(step_count>0)
HAL_GPIO_WritePin(GPIOF,8,GPIO_PIN_RESET);
2023-06-27 18:16:46 +08:00
else{
step_count=-step_count;
HAL_GPIO_WritePin(GPIOF,8,GPIO_PIN_SET);
2023-06-27 18:16:46 +08:00
}
if(self->fre==0)
{
ctrl_fre *cfre=&self->cfre;
memset(cfre,0,sizeof(ctrl_fre));
int max_count=0;
cfre->tick=0;
cfre->step=320;
cfre->fre_max=16000;
cfre->fre_min=1100;
cfre->up_tick=0;
cfre->fre=cfre->fre_min;
}
irq_disable();
if(step_count>0)
{
self->count_all=step_count;
}else{
self->count_all=0;
}
self->count_past=0;
irq_enable();
HAL_TIM_Base_Start_IT(&self->htim);
HAL_TIM_Base_Start_IT(&self->htim2);
2023-06-25 15:30:36 +08:00
return 0;
}
2023-06-27 18:16:46 +08:00
static inline void self_stop__(self_def *self);
2023-06-25 15:30:36 +08:00
2023-06-27 18:16:46 +08:00
static int stop(pwm_def *p)
{
param_check(p);
param_check(p->private_data);
self_def *self=p->private_data;
self_stop__(self);
return 0;
}
static inline void self_set_fre(self_def *self,int fre)
{
// 两个定时器溢出为一个翻转周期这里重装载值要除2
__HAL_TIM_SET_AUTORELOAD(&self->htim,1000000/2/fre);
__HAL_TIM_SET_COUNTER(&self->htim,0);
}
2023-06-25 15:30:36 +08:00
2023-06-27 18:16:46 +08:00
// 设置频率最低8hz最高16000hz
// 如果设置fre为0则自动运行
static int set_fre(pwm_def *p,int fre)
{
param_check(p);
param_check(p->private_data);
self_def *self=p->private_data;
if(fre==0)
{
self->fre=fre;
return 0;
}
if((fre<8)||(fre>16000)) return -1;
self->fre=fre;
self_set_fre(self,fre);
return 0;
}
// 设置中断回调
static int set_irq_fun(pwm_def *p,void (*fun)(void *t),void *t)
{
param_check(p);
param_check(p->private_data);
self_def *self=p->private_data;
irq_disable();
self->end_irq=fun;
self->t=t;
irq_enable();
return 0;
}
2023-06-25 15:30:36 +08:00
2023-06-27 18:16:46 +08:00
static inline void self_stop__(self_def *self)
{
HAL_TIM_Base_Stop_IT(&self->htim);
HAL_TIM_Base_Stop_IT(&self->htim2);
if(self->end_irq)
self->end_irq(self->t);
}
2023-06-25 15:30:36 +08:00
2023-06-27 18:16:46 +08:00
pwm_init_export(pwm,init,deinit,start,stop,set_fre,set_irq_fun,0)
static inline void self_irq(self_def *self)
{
rt_interrupt_enter();
HAL_GPIO_TogglePin(GPIOF,7);
irq_disable();
self->count_past++;
irq_enable();
if(self->count_all>0&&(self->count_all<=self->count_past))
2023-06-27 18:16:46 +08:00
{
self_stop__(self);
2023-06-27 18:16:46 +08:00
}
rt_interrupt_leave();
}
static inline void calc_up(self_def *self)
{
ctrl_fre *cfre=&self->cfre;
if(self->count_past<self->count_all/2)
{
if(cfre->fre<cfre->fre_max)
cfre->fre+=cfre->step;
else
cfre->up_tick++;
}else{
if(cfre->up_tick>0)
cfre->up_tick--;
else{
cfre->fre-=cfre->step;
}
}
// 防止速度减到0永远不停止
if(cfre->fre<cfre->fre_min)
cfre->fre=cfre->fre_min;
}
static int calc_fre(self_def *self)
{
ctrl_fre *cfre=&self->cfre;
int fre=0;
calc_up(self);
fre=cfre->fre;
// 会每1ms更新一次频率因此频率必须大于1000
param_check(fre>1000);
cfre->tick++;
return fre;
}
static inline void self_irq2(self_def *self)
{
rt_interrupt_enter();
if(self->fre==0)
self_set_fre(self,calc_fre(self));
2023-06-27 18:16:46 +08:00
rt_interrupt_leave();
}
static inline void self_stop_irq(self_def *self)
{
rt_interrupt_enter();
irq_disable();
self->count_past=0;
self->count_all=0;
irq_enable();
self_stop__(self);
2023-06-27 18:16:46 +08:00
rt_interrupt_leave();
}
static void Exti14FallingCb(void)
{
self_def *s=&g_self;
self_stop_irq(s);
}
2023-06-27 18:16:46 +08:00
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
self_def *s=&g_self;
2023-06-27 18:16:46 +08:00
//DBG_LOG("timer updata.");
if(htim==&s->htim)
{
self_irq(s);
}
else if(htim==&s->htim2)
{
self_irq2(s);
}
2023-06-27 18:16:46 +08:00
}
void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim)
{
}
void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim)
{
}
void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim)
{
}
void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
{
}
void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
{
}
void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma)
{
}
2023-06-25 15:30:36 +08:00
void TIM14_IRQHandler(void)
{
self_def *s=&g_self;
HAL_TIM_IRQHandler(&s->htim);
}
2023-06-27 18:16:46 +08:00
void TIM13_IRQHandler(void)
{
self_def *s=&g_self;
HAL_TIM_IRQHandler(&s->htim2);
}
2023-06-25 15:30:36 +08:00
void EXTI6_IRQHandler(void)
{
self_def *s=&g_self;
HAL_EXTI_IRQHandler(&s->hexti);
}
2023-06-25 15:30:36 +08:00