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.
 
 
 
 

4.2 KiB

PWM

1khz变换2khz切换点会产生一个错误脉冲

1khz

image-20220308143348591

切断点的错误脉冲

image-20220308143508650

2khz

image-20220308143535990

原因:

每次进行pwm设置的时候都调用了这个方法,失能定时器后进行重新配置,这就导致丢失一定的波形输出

void set_pwm_t16_pa4(int freqhz, float 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);
  uint16_t Mat3 = top;
  if (Mat2 >= top) Mat2 = top - 1;
  printf("Mat2:%d\r\n", Mat2);
  printf("Mat3:%d\r\n", Mat3);
  printf("top:%d\r\n", top);
  /////////////////////////////////////////////////
  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 = 0x01;           /* 预分频比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, Mat2);  //设置匹配寄存器的数值
  T16Nx_SetMAT3(T16N0, Mat3);  //设置匹配寄存器的数值
  //设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
  T16Nx_SetTOP1(T16N0, top);
  //以上是设置占空比
  /* 配置输出管脚 */
  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;
}

解决:

只初始化配置一次PWM输出,修改pwm频率时,只修改以下参数

T16Nx_SetMAT2(T16N0, Mat2);  //设置匹配寄存器的数值
T16Nx_SetMAT3(T16N0, Mat3);  //设置匹配寄存器的数值
//设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
T16Nx_SetTOP1(T16N0, top);