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.

197 lines
6.6 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
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. #include "board.h"
  3. #define CLCK 48.0
  4. #define PRE_CLK 1.0
  5. uint32_t target_frequencyhz;
  6. uint32_t target_duty;
  7. static uint32_t s_mat2;
  8. static uint32_t s_top;
  9. static double calculate_top(double target_frequency_hz) {
  10. int clck = 0;
  11. int top = 0;
  12. clck = CLCK * 1000 * 1000 / PRE_CLK;
  13. top = clck / target_frequency_hz;
  14. return top;
  15. }
  16. void t16_pa4_init(void) {
  17. T16Nx_Disable(T16N0);
  18. // PA4 T16N0_1
  19. T16Nx_BaseInitStruType x;
  20. T16Nx_PWMInitStruType y;
  21. /* 初始化T16Nx定时器*/
  22. x.T16Nx_ClkS = T16Nx_ClkS_PCLK; //时钟源48M
  23. x.T16Nx_SYNC = Disable; //不同步
  24. x.T16Nx_EDGE = T16Nx_EDGE_Rise; //上升沿触发
  25. x.T16Nx_Mode = T16Nx_Mode_PWM; // 选用PWM模式
  26. x.T16Nx_PREMAT = PRE_CLK; /* 预分频比1:1 */
  27. T16Nx_BaseInit(T16N0, &x);
  28. /* 配置T16N0通道1输出 */
  29. y.T16Nx_MOE0 = Disable;
  30. y.T16Nx_MOE1 = Enable;
  31. y.T16Nx_POL0 = POSITIVE; //在串口发送的时候,正极性代表发送的数据与接受的数据相同,负极性代表与发送的数据相反,在这么不知道有没有作用
  32. y.T16Nx_POL1 = POSITIVE;
  33. y.T16Nx_PWMMODE = T16Nx_PWMMode_INDEP; //选择独立模式
  34. y.PWMDZE = Disable; // PWM互补模式死区使能
  35. y.REGBUFEN = Enable; //缓冲寄存器使能 (REGBUFEN目前不知道干什么用的)
  36. T16Nx_PMWOutInit(T16N0, &y);
  37. /* 配置T16N0 通道1输出 */
  38. /*MAT2 MAT3 通道的中断配置*/
  39. //匹配寄存器值匹配后的工作模式,计数到以后: 继续计数不产生中断
  40. T16Nx_MAT2ITConfig(T16N0, T16Nx_Go_No);
  41. //匹配寄存器值匹配后的工作模式,清零并重新计数,产生中断
  42. T16Nx_MAT3ITConfig(T16N0, T16Nx_Clr_Int);
  43. /*MAT2 MAT3 匹配后的输出电平高低*/
  44. T16Nx_MAT2Out1Config(T16N0,
  45. T16Nx_Out_Low); //匹配后输出端口的模式,输出高还是低
  46. T16Nx_MAT3Out1Config(T16N0,
  47. T16Nx_Out_High); //匹配后输出端口的模式,输出高还是低
  48. //以上是设置模式,输出高低电平
  49. T16Nx_SetCNT1(T16N0, 0); //设定计数器的初始值
  50. T16Nx_SetMAT2(T16N0, 0); //设置匹配寄存器的数值
  51. T16Nx_SetMAT3(T16N0, 0); //设置匹配寄存器的数值
  52. //设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
  53. T16Nx_SetTOP1(T16N0, 0);
  54. //以上是设置占空比
  55. /* 配置输出管脚 */
  56. GPIO_InitSettingType initset;
  57. initset.Signal = GPIO_Pin_Signal_Digital; //数字
  58. initset.Dir = GPIO_Direction_Output; //输出模式
  59. initset.Func = GPIO_Reuse_Func2; //复用到T16N0_1功能
  60. initset.ODE = GPIO_ODE_Output_Disable; //开漏使能
  61. initset.DS = GPIO_DS_Output_Normal; //普通电流模式
  62. initset.PUE = GPIO_PUE_Input_Enable; //弱上拉使能
  63. initset.PDE = GPIO_PDE_Input_Disable; //弱下拉禁止
  64. /* 配置PA4为T16N0输出通道1 */
  65. GPIO_Init(GPIO_Pin_A4, &initset);
  66. T16Nx_Enable(T16N0);
  67. return;
  68. }
  69. void set_pwm_t16_pa4_2(uint16_t mat2, uint16_t top) {
  70. uint16_t Mat2 = mat2;
  71. uint16_t Mat3 = top;
  72. s_mat2 = mat2;
  73. s_top = top;
  74. printf("set_pwm_t16_pa4 mat2:%d mat3:%d top:%d\n", mat2, Mat3, top);
  75. T16Nx_SetCNT1(T16N0, 0); //设定计数器的初始值
  76. T16Nx_SetMAT2(T16N0, Mat2); //设置匹配寄存器的数值
  77. T16Nx_SetMAT3(T16N0, Mat3); //设置匹配寄存器的数值
  78. //设置计数器峰值//根据这个得到定时的时钟48M/48000=1khZ(在独立模式下PWM的周期由TOP1决定为TOP+1,周期算出来是1ms)
  79. T16Nx_SetTOP1(T16N0, top);
  80. //以上是设置占空比
  81. }
  82. void set_pwm_mat2(uint16_t mat2) { set_pwm_t16_pa4_2(mat2, s_top); }
  83. void set_pwm_t16_pa4(uint32_t freqhz, double duty) {
  84. printf("set_pwm_t16_pa4 %d %f\n", freqhz, duty);
  85. double top_double = calculate_top(freqhz); //根据需要的频率计算出TOP(自动重装载值)
  86. uint16_t top = (uint16_t)top_double;
  87. uint16_t Mat2 = (uint16_t)top_double * (duty / 100.0);
  88. if (Mat2 >= top) Mat2 = top - 1;
  89. set_pwm_t16_pa4_2(Mat2, top);
  90. }
  91. //######################################################
  92. /**
  93. * @brief pwm的周期占空比
  94. *
  95. * @param frequency
  96. * @param duty
  97. */
  98. /**
  99. *
  100. * :
  101. *
  102. *
  103. *
  104. * :
  105. * 20->0
  106. * 0->20
  107. * 0->10
  108. *
  109. * ,
  110. *
  111. *
  112. *
  113. *
  114. *
  115. *
  116. * 1. ,
  117. * 2.
  118. *
  119. */
  120. uint32_t s_target_frequencyhz;
  121. uint32_t s_now_frequencyhz;
  122. uint32_t s_target_duty;
  123. uint32_t s_now_duty;
  124. void set_pwm_modbul_freq_duty(uint32_t frequencyhz, uint32_t duty) {
  125. // s_target_frequencyhz = frequencyhz;
  126. // if (s_target_frequencyhz <= MIN_PWM_FREQ) {
  127. // s_target_frequencyhz = MIN_PWM_FREQ;
  128. // }
  129. // s_target_duty = duty;
  130. if (frequencyhz < 50) frequencyhz = 50;
  131. set_pwm_t16_pa4(frequencyhz, duty);
  132. }
  133. void set_pwm_modbul_freq_duty2(uint32_t frequencyhz, double duty) {
  134. // s_target_frequencyhz = frequencyhz;
  135. // if (s_target_frequencyhz <= MIN_PWM_FREQ) {
  136. // s_target_frequencyhz = MIN_PWM_FREQ;
  137. // }
  138. // s_target_duty = duty;
  139. if (frequencyhz < 50) frequencyhz = 50;
  140. set_pwm_t16_pa4(frequencyhz, duty);
  141. }
  142. void stop_pwm_output() { T16Nx_Disable(T16N0); }
  143. // uint32_t get_next_value_on_step(uint32_t now, uint32_t target, uint32_t step) {
  144. // }
  145. // void pwm_module_stop() { set_pwm_modbul_freq_duty(MIN_PWM_FREQ, 0); }
  146. // void pwm_schdule() {
  147. // /**
  148. // * @brief 当前频率的占空比的百分之一变化
  149. // */
  150. // //计算当前频率下的目标占空比
  151. // uint32_t targetduty = 0;
  152. // uint32_t targetduty1 = s_target_duty;
  153. // uint32_t targetduty2 = (1.0 / s_target_frequencyhz) * (s_target_duty / 100.0) / (1.0 / s_now_frequencyhz) * 100;
  154. // targetduty = targetduty1 < targetduty2 ? targetduty1 : targetduty2;
  155. // if (targetduty != s_now_duty) {
  156. // set_pwm_t16_pa4(s_now_frequencyhz, targetduty);
  157. // return;
  158. // } else {
  159. // //计算下一次设置的频率
  160. // set_pwm_t16_pa4(s_now_frequencyhz, targetduty);
  161. // }
  162. // if (s_target_frequencyhz > s_now_frequencyhz) {
  163. // s_now_frequencyhz += 1000;
  164. // }
  165. // }
  166. //######################################################
  167. //# c语言的理解
  168. //# static , 字节长度 ,堆,栈,变量分布,
  169. //# 操作系统
  170. //# 线程,进程,信号量
  171. //#
  172. //#