使用定时器

This commit is contained in:
ranchuan
2023-06-27 18:16:46 +08:00
parent cdad432f8a
commit edd3010a20
6 changed files with 338 additions and 9 deletions

View File

@@ -3,3 +3,6 @@
2023.6.25
使用rt-thread
电机控制、按键、ADC在M4上实现
2023.6.27
在m4上使用定时器实现pwm控制的时候没有找到光感输入脚
如果发现程序不能运行检查RTE文件

View File

@@ -1130,7 +1130,7 @@
<Group>
<GroupName>::Compiler</GroupName>
<tvExp>0</tvExp>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>1</RteFlg>

View File

@@ -606,6 +606,11 @@
<FileName>stm32mp1xx_hal_fdcan.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\stm32lib\STM32MP1xx_HAL_Driver\Src\stm32mp1xx_hal_fdcan.c</FilePath>
</File>
<File>
<FileName>stm32mp1xx_hal_tim.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\stm32lib\STM32MP1xx_HAL_Driver\Src\stm32mp1xx_hal_tim.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
@@ -658,11 +663,6 @@
</FileArmAds>
</FileOption>
</File>
<File>
<FileName>stm32mp1xx_hal_tim.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\stm32lib\STM32MP1xx_HAL_Driver\Src\stm32mp1xx_hal_tim.c</FilePath>
</File>
</Files>
</Group>
<Group>
@@ -772,6 +772,57 @@
<FileName>if_pwm.c</FileName>
<FileType>1</FileType>
<FilePath>.\source\interface\if_pwm.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>0</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File>
</Files>
</Group>

1
debug.ini Normal file
View File

@@ -0,0 +1 @@
LOAD %L NOCODE INCREMENTAL

View File

@@ -1,15 +1,35 @@
#include "board.h"
#include "debug.h"
#include "lock_resource.h"
// 使用定时器14
// PF7,8,9 是输出口
// 使用PF7来产生脉冲PF8来改变方向
typedef struct{
int tick;
int step;
int fre;
int fre_max;
int fre_min;
int up_tick;
}ctrl_fre;
typedef struct{
TIM_HandleTypeDef htim;
TIM_HandleTypeDef htim2;
int count_all;
int count_past;
int fre;
ctrl_fre cfre;
void (*end_irq)(void *t);
void *t;
}self_def;
static self_def g_self;
@@ -18,11 +38,13 @@ static int init(pwm_def *p)
self_def *s=&g_self;
if(p->private_data) return 0;
p->private_data=s;
s->cfre.step=320;
s->cfre.fre_min=1100;
s->htim.Instance = TIM14;
s->htim.Init.Prescaler = 209-1;
s->htim.Init.CounterMode = TIM_COUNTERMODE_UP;
s->htim.Init.Period = 65535;
s->htim.Init.Period = 31-1;
s->htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
s->htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&s->htim) != HAL_OK)
@@ -30,16 +52,257 @@ static int init(pwm_def *p)
DBG_ERR("time init failed.");
return -1;
}
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_INPUT;
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);
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((*self->dtb->bitmap_pin_zero==0)&&(step_count<0))
{
// 到达零点后不能继续上升
if(self->end_irq)
self->end_irq(self->t);
return -1;
}
if(step_count>0)
*self->dtb->bitmap_pin_dir=0;
else{
step_count=-step_count;
*self->dtb->bitmap_pin_dir=1;
}
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);
return 0;
}
static inline void self_stop__(self_def *self);
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);
}
// 设置频率最低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;
}
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);
}
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();
volatile uint32_t *pin=self->dtb->bitmap_pin;
if(TIM_GetFlagStatus(self->dtb->tim,TIM_FLAG_Update))
{
TIM_ClearFlag(self->dtb->tim,TIM_FLAG_Update);
*pin=!(*pin);
irq_disable();
self->count_past++;
irq_enable();
if(self->count_all>0&&(self->count_all<=self->count_past))
{
self_stop__(self);
}
}
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();
volatile uint32_t *pin=self->dtb->bitmap_pin;
if(TIM_GetFlagStatus(self->dtb->tim2,TIM_FLAG_Update))
{
TIM_ClearFlag(self->dtb->tim2,TIM_FLAG_Update);
if(self->fre==0)
self_set_fre(self,calc_fre(self));
}
rt_interrupt_leave();
}
static inline void self_stop_irq(self_def *self)
{
rt_interrupt_enter();
if(EXTI_GetFlagStatus(1<<self->dtb->gpio_zero_pin)){
irq_disable();
self->count_past=0;
self->count_all=0;
irq_enable();
self_stop__(self);
EXTI_ClearFlag(1<<self->dtb->gpio_zero_pin);
}
rt_interrupt_leave();
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//DBG_LOG("timer updata.");
}
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)
{
}
@@ -50,6 +313,11 @@ void TIM14_IRQHandler(void)
self_def *s=&g_self;
HAL_TIM_IRQHandler(&s->htim);
}
void TIM13_IRQHandler(void)
{
self_def *s=&g_self;
HAL_TIM_IRQHandler(&s->htim2);
}

View File

@@ -25,6 +25,7 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "debug.h"
#include "board.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -139,6 +140,11 @@ int main(void)
{
Error_Handler();
}
pwm_def *pwm=dev_get("pwm");
pwm->init(pwm);
DBG_LOG("pwm start.");
pwm->start(pwm,1);
/* USER CODE END 2 */
/* Infinite loop */