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.
152 lines
4.1 KiB
152 lines
4.1 KiB
#include "pwm.h"
|
|
#define TIMING_TICK 1800000
|
|
#define INTERVAL_TICK 30000
|
|
#define CLCK 48
|
|
uint32_t s_hardware_period; //单位ms
|
|
uint32_t s_hardware_duty; //单位ms
|
|
|
|
/**
|
|
* @brief s_large_duty是由s_large_period与INTERVAL_TIME决定
|
|
* s_large_duty = INTERVAL_TIME/s_large_period
|
|
* 例如:s_large_period=1800000
|
|
* s_large_duty = (30000/1800000)*100
|
|
*
|
|
*/
|
|
uint32_t s_large_period; //单位ms
|
|
uint32_t s_large_duty = 100; //单位ms
|
|
uint32_t begin_ticket;
|
|
uint8_t update_large_period_count;
|
|
bool enableFlag = false;
|
|
|
|
void HOOK_pwm_module_set_pwm_duty(uint32_t frequency, uint32_t duty) {
|
|
ozone_pwm_control_set_pwm_duty(frequency, duty);
|
|
}
|
|
|
|
void HOOK_pwm_stop(void) {
|
|
HOOK_pwm_module_set_pwm_duty(0, 0); //关闭PWM输出
|
|
port_fan_set(false); //风扇结束工作
|
|
}
|
|
|
|
bool HOOK_pwm_is_enable(void) { return enableFlag; }
|
|
|
|
void update_large_period(void) {
|
|
uint32_t large_period;
|
|
update_large_period_count++;
|
|
switch (update_large_period_count) {
|
|
case 1:
|
|
large_period = 1 * TIMING_TICK;
|
|
break;
|
|
case 2:
|
|
large_period = 2 * TIMING_TICK;
|
|
break;
|
|
case 3:
|
|
large_period = 3 * TIMING_TICK;
|
|
break;
|
|
case 4:
|
|
large_period = 4 * TIMING_TICK;
|
|
break;
|
|
case 5:
|
|
update_large_period_count = 0;
|
|
large_period = 0 * TIMING_TICK;
|
|
break;
|
|
}
|
|
pwm_module_set_pwm_output_1(
|
|
large_period, s_large_duty); //将更新后的周期以及现在的占空比传进去
|
|
}
|
|
|
|
/**
|
|
* @brief 一直工作的时间定时的占空比为100,
|
|
* 间歇时间设置300000
|
|
* @param freq
|
|
* @param duty
|
|
*/
|
|
void pwm_module_set_pwm_output_1(uint32_t large_period, uint32_t large_duty) {
|
|
pwm_module_set_pwm_output_2(s_hardware_period, s_hardware_duty, large_period,
|
|
large_duty);
|
|
}
|
|
/**
|
|
* @brief 定时和PWM
|
|
*
|
|
* @param hardware_period pwm频率
|
|
* @param hardware_duty pwm占空比
|
|
* @param large_period 定时周期
|
|
* @param large_duty 定时占空比
|
|
*/
|
|
void pwm_module_set_pwm_output_2(uint32_t hardware_period,
|
|
uint32_t hardware_duty, uint32_t large_period,
|
|
uint32_t large_duty) {
|
|
s_hardware_period = hardware_period;
|
|
s_hardware_duty = hardware_duty;
|
|
s_large_period = large_period;
|
|
s_large_duty = large_duty;
|
|
|
|
begin_ticket = get_sys_ticket();
|
|
|
|
enableFlag = true;
|
|
HOOK_pwm_module_set_pwm_duty(s_hardware_period, s_hardware_duty);
|
|
}
|
|
|
|
void pwm_module_stop_pwm(void) { enableFlag = false; }
|
|
|
|
void pwm_module_loop(void) {
|
|
if (!enableFlag) {
|
|
HOOK_pwm_stop();
|
|
return;
|
|
}
|
|
if (port_haspassedms(begin_ticket) % s_large_period <=
|
|
s_large_period * s_large_duty / 100) {
|
|
if (!HOOK_pwm_is_enable()) {
|
|
HOOK_pwm_module_set_pwm_duty(s_hardware_period, s_hardware_duty);
|
|
}
|
|
} else {
|
|
enableFlag = false;
|
|
HOOK_pwm_stop();
|
|
}
|
|
}
|
|
|
|
//######################################################
|
|
double calculate_top(double target_frequency) {
|
|
int clck = 0;
|
|
int target_frequency_hz = 0;
|
|
int top = 0;
|
|
clck = CLCK * 1000 * 1000;
|
|
target_frequency_hz = (int)target_frequency * 1000;
|
|
// printf("target_frequency_hz%d\n", target_frequency_hz);
|
|
top = clck / target_frequency_hz;
|
|
// printf("top%d\t\n", top);
|
|
return top;
|
|
}
|
|
double calculate_MAT2(double top, double duty) {
|
|
double percentage_duty = 0;
|
|
double Mat2 = 0;
|
|
percentage_duty = duty / 100;
|
|
Mat2 = top * percentage_duty;
|
|
return Mat2;
|
|
}
|
|
|
|
void ozone_pwm_control_set_pwm_duty(uint32_t frequency, uint32_t duty) {
|
|
double top = 0;
|
|
double Mat2 = 0;
|
|
if (frequency > CLCK * 1000) {
|
|
printf("out of range\n");
|
|
return;
|
|
}
|
|
top = calculate_top(frequency); //根据需要的频率计算出TOP(自动重装载值)
|
|
if (top == 0) {
|
|
return;
|
|
}
|
|
Mat2 = calculate_MAT2(top, duty);
|
|
printf("top:\t%2.lf\n", top);
|
|
printf("MAT2:\t%2.lf\n", Mat2);
|
|
printf("MAT3:\t%2.lf\n", top);
|
|
T16Nx_Disable(T16N0);
|
|
t16n0_1_init();
|
|
T16Nx_SetMAT2(T16N0, Mat2);
|
|
if (duty == 100) {
|
|
T16Nx_SetMAT3(T16N0, top - 1);
|
|
} else {
|
|
T16Nx_SetMAT3(T16N0, top);
|
|
}
|
|
T16Nx_SetTOP1(T16N0, top);
|
|
}
|
|
//######################################################
|