使用定时器
This commit is contained in:
@@ -3,3 +3,6 @@
|
||||
2023.6.25
|
||||
使用rt-thread
|
||||
电机控制、按键、ADC在M4上实现
|
||||
2023.6.27
|
||||
在m4上使用定时器,实现pwm控制的时候没有找到光感输入脚
|
||||
如果发现程序不能运行,检查RTE文件
|
@@ -1130,7 +1130,7 @@
|
||||
|
||||
<Group>
|
||||
<GroupName>::Compiler</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>1</RteFlg>
|
||||
|
@@ -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,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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -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 */
|
||||
|
Reference in New Issue
Block a user