You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.8 KiB
135 lines
3.8 KiB
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#if 0
|
|
void trigger_pwm(int32_t freq, float duty, int32_t pluse_num) {
|
|
//无论怎样先停止PWM输
|
|
HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
|
|
if (freq == 0) {
|
|
LOGE("E:trigger pwm fail,freq == 0\n");
|
|
return;
|
|
}
|
|
// 确定预分频参数,重载值
|
|
float psc_x_arr = 90 * 1000 /*系统时钟*/ * 1000 / freq;
|
|
uint32_t psc = 0;
|
|
uint32_t arr = 65534;
|
|
for (; arr > 2; arr--) {
|
|
psc = psc_x_arr / arr;
|
|
if (psc >= 1) {
|
|
uint32_t tmparr = psc_x_arr / psc;
|
|
if (tmparr >= 65534) continue;
|
|
break;
|
|
}
|
|
}
|
|
if (psc == 0) return;
|
|
if (arr <= 3) return; //定时器一周期的分辨率太小了
|
|
arr = psc_x_arr / psc;
|
|
|
|
arr = arr - 1;
|
|
psc = psc - 1;
|
|
|
|
__HAL_TIM_SET_AUTORELOAD(&htim3, arr);
|
|
__HAL_TIM_SET_PRESCALER(&htim3, psc);
|
|
// 确定PWM通道占空比
|
|
uint16_t comparevalue = duty * arr;
|
|
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, comparevalue);
|
|
if (pluse_num == 0) {
|
|
g_continue_output_mode = true;
|
|
} else {
|
|
g_pulse_num = pluse_num - 1;
|
|
g_continue_output_mode = false;
|
|
}
|
|
__HAL_TIM_SET_COUNTER(&htim3, 0);
|
|
LOGD("a[%d] p[%d]c[%d]\r\n", arr, psc, comparevalue);
|
|
HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);
|
|
}
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
int autoreload;
|
|
int prescaler;
|
|
float realfreq;
|
|
} timer_config_t;
|
|
|
|
bool compute_timer_parameter(timer_config_t* config, int timer_in_clk /*mhz*/, int infreq /*hz*/)
|
|
{
|
|
float psc_x_arr =(float) timer_in_clk * 1000 /*定时器模块时钟*/ * 1000 / infreq;
|
|
uint32_t psc = 0;
|
|
uint32_t arr = 65534;
|
|
for (; arr > 2; arr--)
|
|
{
|
|
psc =(uint32_t)( psc_x_arr / arr);
|
|
if (psc >= 1)
|
|
{
|
|
uint32_t tmparr = psc_x_arr / psc;
|
|
if (tmparr >= 65534)
|
|
continue;
|
|
break;
|
|
}
|
|
}
|
|
if (psc == 0)
|
|
return false;
|
|
if (arr <= 3)
|
|
return false; //定时器一周期的分辨率太小了
|
|
arr = psc_x_arr / psc;
|
|
|
|
int psc_x_arr_real = arr * psc;
|
|
float realfreq = timer_in_clk * 1000.0 /*定时器模块时钟*/ * 1000 / psc_x_arr_real;
|
|
|
|
arr = arr - 1;
|
|
psc = psc - 1;
|
|
|
|
config->autoreload = arr;
|
|
config->prescaler = psc;
|
|
config->realfreq = realfreq;
|
|
// config->compare = arr / 2;
|
|
return false;
|
|
}
|
|
|
|
void dumpconfig_info(timer_config_t* config)
|
|
{
|
|
printf("* freq : %f \n", config->realfreq);
|
|
printf("* prescaler : %d \n", config->prescaler);
|
|
printf("* autoreload: %d \n", config->autoreload);
|
|
}
|
|
|
|
int main(int argc, char const* argv[])
|
|
{
|
|
if (argc != 3)
|
|
{
|
|
printf("%s timerInClk mhz expect_freq khz\n", argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
float expect_freq = 0;
|
|
float timerInClk = 0;
|
|
|
|
sscanf(argv[1], "%f", &timerInClk);
|
|
sscanf(argv[2], "%f", &expect_freq);
|
|
|
|
printf("******************************************************\n");
|
|
printf("* author: zhaohe *\n");
|
|
printf("* e-mail: h_zhaohe@163.com *\n");
|
|
printf("******************************************************\n");
|
|
printf("*\n");
|
|
printf("* timerInClk : %f mhz\n", timerInClk);
|
|
printf("* expect freq: %f khz\n", expect_freq);
|
|
printf("*\n");
|
|
|
|
int32_t infreq = (int32_t)(expect_freq * 1000);
|
|
timer_config_t timerconfig_apb2;
|
|
|
|
compute_timer_parameter(&timerconfig_apb2, timerInClk, infreq);
|
|
|
|
printf("******************************************************\n");
|
|
printf("*\n");
|
|
printf("* timer_module_clk: %f mhz\n", timerInClk);
|
|
printf("* freq : %f khz\n", timerconfig_apb2.realfreq / 1000.0);
|
|
printf("* period : %f ms\n", (1.0 / timerconfig_apb2.realfreq * 1000));
|
|
printf("* prescaler : %d \n", timerconfig_apb2.prescaler);
|
|
printf("* autoreload : %d \n", timerconfig_apb2.autoreload);
|
|
printf("*\n");
|
|
|
|
return 0;
|
|
}
|