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.
167 lines
5.6 KiB
167 lines
5.6 KiB
#if 0
|
|
#include "pwm.h"
|
|
|
|
#include "board.h"
|
|
#define CLCK 48.0
|
|
#define PRE_CLK 1.0
|
|
uint32_t target_frequencyhz;
|
|
uint32_t target_duty;
|
|
|
|
static uint32_t s_mat2;
|
|
static uint32_t s_top;
|
|
|
|
static double calculate_top(double target_frequency_hz) {
|
|
int clck = 0;
|
|
int top = 0;
|
|
clck = CLCK * 1000 * 1000 / PRE_CLK;
|
|
top = clck / target_frequency_hz;
|
|
return top;
|
|
}
|
|
|
|
void t16_pa4_init(void) {
|
|
T16Nx_Disable(T16N0);
|
|
// PA4 T16N0_1
|
|
T16Nx_BaseInitStruType x;
|
|
T16Nx_PWMInitStruType y;
|
|
/* 初始化T16Nx定时器*/
|
|
x.T16Nx_ClkS = T16Nx_ClkS_PCLK; //时钟源48M
|
|
x.T16Nx_SYNC = Disable; //不同步
|
|
x.T16Nx_EDGE = T16Nx_EDGE_Rise; //上升沿触发
|
|
x.T16Nx_Mode = T16Nx_Mode_PWM; // 选用PWM模式
|
|
x.T16Nx_PREMAT = PRE_CLK; /* 预分频比1:1 */
|
|
T16Nx_BaseInit(T16N0, &x);
|
|
/* 配置T16N0通道1输出 */
|
|
y.T16Nx_MOE0 = Disable;
|
|
y.T16Nx_MOE1 = Enable;
|
|
y.T16Nx_POL0 = POSITIVE; //在串口发送的时候,正极性代表发送的数据与接受的数据相同,负极性代表与发送的数据相反,在这么不知道有没有作用
|
|
y.T16Nx_POL1 = POSITIVE;
|
|
y.T16Nx_PWMMODE = T16Nx_PWMMode_INDEP; //选择独立模式
|
|
y.PWMDZE = Disable; // PWM互补模式死区使能
|
|
y.REGBUFEN = Enable; //缓冲寄存器使能 (REGBUFEN目前不知道干什么用的)
|
|
T16Nx_PMWOutInit(T16N0, &y);
|
|
/* 配置T16N0 通道1输出 */
|
|
/*MAT2 MAT3 通道的中断配置*/
|
|
//匹配寄存器值匹配后的工作模式,计数到以后: 继续计数不产生中断
|
|
T16Nx_MAT2ITConfig(T16N0, T16Nx_Go_No);
|
|
//匹配寄存器值匹配后的工作模式,清零并重新计数,产生中断
|
|
T16Nx_MAT3ITConfig(T16N0, T16Nx_Clr_Int);
|
|
|
|
/*MAT2 MAT3 匹配后的输出电平高低*/
|
|
T16Nx_MAT2Out1Config(T16N0,
|
|
T16Nx_Out_Low); //匹配后输出端口的模式,输出高还是低
|
|
T16Nx_MAT3Out1Config(T16N0,
|
|
T16Nx_Out_High); //匹配后输出端口的模式,输出高还是低
|
|
//以上是设置模式,输出高低电平
|
|
T16Nx_SetCNT1(T16N0, 0); //设定计数器的初始值
|
|
T16Nx_SetMAT2(T16N0, 0); //设置匹配寄存器的数值
|
|
T16Nx_SetMAT3(T16N0, 0); //设置匹配寄存器的数值
|
|
//设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
|
|
T16Nx_SetTOP1(T16N0, 0);
|
|
//以上是设置占空比
|
|
/* 配置输出管脚 */
|
|
GPIO_InitSettingType initset;
|
|
|
|
initset.Signal = GPIO_Pin_Signal_Digital; //数字
|
|
initset.Dir = GPIO_Direction_Output; //输出模式
|
|
initset.Func = GPIO_Reuse_Func2; //复用到T16N0_1功能
|
|
initset.ODE = GPIO_ODE_Output_Disable; //开漏使能
|
|
initset.DS = GPIO_DS_Output_Normal; //普通电流模式
|
|
initset.PUE = GPIO_PUE_Input_Enable; //弱上拉使能
|
|
initset.PDE = GPIO_PDE_Input_Disable; //弱下拉禁止
|
|
/* 配置PA4为T16N0输出通道1 */
|
|
GPIO_Init(GPIO_Pin_A4, &initset);
|
|
T16Nx_Enable(T16N0);
|
|
return;
|
|
}
|
|
|
|
void set_pwm_t16_pa4_2(uint16_t mat2, uint16_t top) {
|
|
uint16_t Mat2 = mat2;
|
|
uint16_t Mat3 = top;
|
|
|
|
s_mat2 = mat2;
|
|
s_top = top;
|
|
|
|
// printf("set_pwm_t16_pa4 mat2:%d mat3:%d top:%d\n", mat2, Mat3, top);
|
|
T16Nx_SetCNT1(T16N0, 0); //设定计数器的初始值
|
|
T16Nx_SetMAT2(T16N0, Mat2); //设置匹配寄存器的数值
|
|
T16Nx_SetMAT3(T16N0, Mat3); //设置匹配寄存器的数值
|
|
//设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
|
|
T16Nx_SetTOP1(T16N0, top);
|
|
//以上是设置占空比
|
|
}
|
|
|
|
uint32_t getCNT() { return T16Nx_GetCNT1(T16N0); }
|
|
uint32_t getTOP() { return T16Nx_GetTOP1(T16N0); }
|
|
|
|
void set_pwm_mat2(uint16_t mat2) { set_pwm_t16_pa4_2(mat2, s_top); }
|
|
|
|
void set_pwm_t16_pa4(uint32_t freqhz, double duty) {
|
|
// printf("set_pwm_t16_pa4 %d %f\n", freqhz, duty);
|
|
double top_double = calculate_top(freqhz); //根据需要的频率计算出TOP(自动重装载值)
|
|
uint16_t top = (uint16_t)top_double;
|
|
uint16_t Mat2 = (uint16_t)top_double * (duty / 100.0);
|
|
if (Mat2 >= top) Mat2 = top - 1;
|
|
set_pwm_t16_pa4_2(Mat2, top);
|
|
}
|
|
|
|
//######################################################
|
|
/**
|
|
* @brief 设置pwm的周期占空比
|
|
*
|
|
* @param frequency
|
|
* @param duty
|
|
*/
|
|
|
|
/**
|
|
*
|
|
* 频率变化:
|
|
*
|
|
*
|
|
*
|
|
* 占空比变化:
|
|
* 20->0
|
|
* 0->20
|
|
* 0->10
|
|
*
|
|
* 有效时间逐渐增加,周期最大,有效时间不变,周期变小,频率变大
|
|
*
|
|
*
|
|
*
|
|
* 周期变大,有效时间不变,周期变到最大,有效时间逐渐减小
|
|
*
|
|
*
|
|
* 1. 先变化到周期,如果周期时间大于占空比,则先变化到占空比
|
|
* 2. 再变化频率
|
|
*
|
|
*/
|
|
|
|
uint32_t s_target_frequencyhz;
|
|
uint32_t s_now_frequencyhz;
|
|
|
|
uint32_t s_target_duty;
|
|
uint32_t s_now_duty;
|
|
|
|
void set_pwm_modbul_freq_duty(uint32_t frequencyhz, uint32_t duty) {
|
|
// s_target_frequencyhz = frequencyhz;
|
|
|
|
// if (s_target_frequencyhz <= MIN_PWM_FREQ) {
|
|
// s_target_frequencyhz = MIN_PWM_FREQ;
|
|
// }
|
|
// s_target_duty = duty;
|
|
if (frequencyhz < 50) frequencyhz = 50;
|
|
set_pwm_t16_pa4(frequencyhz, duty);
|
|
}
|
|
|
|
void set_pwm_modbul_freq_duty2(uint32_t frequencyhz, double duty) {
|
|
// s_target_frequencyhz = frequencyhz;
|
|
|
|
// if (s_target_frequencyhz <= MIN_PWM_FREQ) {
|
|
// s_target_frequencyhz = MIN_PWM_FREQ;
|
|
// }
|
|
// s_target_duty = duty;
|
|
if (frequencyhz < 50) frequencyhz = 50;
|
|
set_pwm_t16_pa4(frequencyhz, duty);
|
|
}
|
|
|
|
void stop_pwm_output() { T16Nx_Disable(T16N0); }
|
|
#endif
|