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.

125 lines
4.9 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. #include "pwm.h"
  2. #define CLCK 48
  3. uint32_t target_frequencyhz;
  4. uint32_t target_duty;
  5. static double calculate_top(double target_frequency_hz) {
  6. int clck = 0;
  7. int top = 0;
  8. clck = CLCK * 1000 * 1000;
  9. top = clck / target_frequency_hz;
  10. return top;
  11. }
  12. void t16_pa4_init(void) {
  13. T16Nx_Disable(T16N0);
  14. // PA4 T16N0_1
  15. T16Nx_BaseInitStruType x;
  16. T16Nx_PWMInitStruType y;
  17. /* 初始化T16Nx定时器*/
  18. x.T16Nx_ClkS = T16Nx_ClkS_PCLK; //时钟源48M
  19. x.T16Nx_SYNC = Disable; //不同步
  20. x.T16Nx_EDGE = T16Nx_EDGE_Rise; //上升沿触发
  21. x.T16Nx_Mode = T16Nx_Mode_PWM; // 选用PWM模式
  22. x.T16Nx_PREMAT = 0x01; /* 预分频比1:1 */
  23. T16Nx_BaseInit(T16N0, &x);
  24. /* 配置T16N0通道1输出 */
  25. y.T16Nx_MOE0 = Disable;
  26. y.T16Nx_MOE1 = Enable;
  27. y.T16Nx_POL0 = POSITIVE; //在串口发送的时候,正极性代表发送的数据与接受的数据相同,负极性代表与发送的数据相反,在这么不知道有没有作用
  28. y.T16Nx_POL1 = POSITIVE;
  29. y.T16Nx_PWMMODE = T16Nx_PWMMode_INDEP; //选择独立模式
  30. y.PWMDZE = Disable; // PWM互补模式死区使能
  31. y.REGBUFEN = Enable; //缓冲寄存器使能 (REGBUFEN目前不知道干什么用的)
  32. T16Nx_PMWOutInit(T16N0, &y);
  33. /* 配置T16N0 通道1输出 */
  34. /*MAT2 MAT3 通道的中断配置*/
  35. //匹配寄存器值匹配后的工作模式,计数到以后: 继续计数不产生中断
  36. T16Nx_MAT2ITConfig(T16N0, T16Nx_Go_No);
  37. //匹配寄存器值匹配后的工作模式,清零并重新计数,产生中断
  38. T16Nx_MAT3ITConfig(T16N0, T16Nx_Clr_Int);
  39. /*MAT2 MAT3 匹配后的输出电平高低*/
  40. T16Nx_MAT2Out1Config(T16N0,
  41. T16Nx_Out_Low); //匹配后输出端口的模式,输出高还是低
  42. T16Nx_MAT3Out1Config(T16N0,
  43. T16Nx_Out_High); //匹配后输出端口的模式,输出高还是低
  44. //以上是设置模式,输出高低电平
  45. T16Nx_SetCNT1(T16N0, 0); //设定计数器的初始值
  46. T16Nx_SetMAT2(T16N0, 0); //设置匹配寄存器的数值
  47. T16Nx_SetMAT3(T16N0, 0); //设置匹配寄存器的数值
  48. //设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
  49. T16Nx_SetTOP1(T16N0, 0);
  50. //以上是设置占空比
  51. /* 配置输出管脚 */
  52. GPIO_InitSettingType initset;
  53. initset.Signal = GPIO_Pin_Signal_Digital; //数字
  54. initset.Dir = GPIO_Direction_Output; //输出模式
  55. initset.Func = GPIO_Reuse_Func2; //复用到T16N0_1功能
  56. initset.ODE = GPIO_ODE_Output_Disable; //开漏使能
  57. initset.DS = GPIO_DS_Output_Normal; //普通电流模式
  58. initset.PUE = GPIO_PUE_Input_Enable; //弱上拉使能
  59. initset.PDE = GPIO_PDE_Input_Disable; //弱下拉禁止
  60. /* 配置PA4为T16N0输出通道1 */
  61. GPIO_Init(GPIO_Pin_A4, &initset);
  62. T16Nx_Enable(T16N0);
  63. return;
  64. }
  65. void set_pwm_t16_pa4(int freqhz, float duty) {
  66. double top_double = calculate_top(freqhz); //根据需要的频率计算出TOP(自动重装载值)
  67. uint16_t top = (uint16_t)top_double;
  68. uint16_t Mat2 = (uint16_t)top_double * (duty / 100.0);
  69. uint16_t Mat3 = top;
  70. if (Mat2 >= top) Mat2 = top - 1;
  71. printf("Mat2:%d\r\n", Mat2);
  72. printf("Mat3:%d\r\n", Mat3);
  73. printf("top:%d\r\n", top);
  74. /////////////////////////////////////////////////
  75. T16Nx_SetMAT2(T16N0, Mat2); //设置匹配寄存器的数值
  76. T16Nx_SetMAT3(T16N0, Mat3); //设置匹配寄存器的数值
  77. //设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
  78. T16Nx_SetTOP1(T16N0, top);
  79. //以上是设置占空比
  80. }
  81. //######################################################
  82. /**
  83. * @brief pwm的周期占空比
  84. *
  85. * @param frequency
  86. * @param duty
  87. */
  88. void set_pwm_modbul_freq_duty(uint32_t frequencyhz, uint32_t duty) {
  89. static uint32_t now_frequencyhz;
  90. static uint32_t now_duty;
  91. target_frequencyhz = frequencyhz;
  92. target_duty = duty;
  93. // while (1) {
  94. /**
  95. * @brief 1khz
  96. *
  97. */
  98. // Delayms(1000); 合适的延时
  99. if (now_frequencyhz == target_frequencyhz) {
  100. return;
  101. }
  102. if (now_frequencyhz < target_frequencyhz) {
  103. now_frequencyhz = now_frequencyhz + 1000;
  104. if (now_frequencyhz >= target_frequencyhz) {
  105. now_frequencyhz = target_frequencyhz;
  106. }
  107. set_pwm_t16_pa4(now_frequencyhz, target_duty);
  108. } else if (now_frequencyhz > target_frequencyhz) {
  109. now_frequencyhz = now_frequencyhz - 1000;
  110. if (now_frequencyhz <= target_frequencyhz) {
  111. now_frequencyhz = target_frequencyhz;
  112. }
  113. set_pwm_t16_pa4(now_frequencyhz, target_duty);
  114. }
  115. // }
  116. printf("set_pwm_modbul_freq_duty freq:%d,duty%d\n", frequencyhz, duty);
  117. // set_pwm_t16_pa4(frequencyhz, duty);
  118. }
  119. //######################################################