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.

272 lines
6.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #include <stdbool.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "board.h"
  7. #include "port.h"
  8. //
  9. #include "gpio.h"
  10. #include "main.h"
  11. #include "tim.h"
  12. #include "usart.h"
  13. //
  14. #include "stm32f429xx.h"
  15. #include "stm32f4xx_hal_tim.h"
  16. #include "stm32f4xx_hal_usart.h"
  17. #include "iwdg.h"
  18. /**
  19. * @brief IO状态
  20. */
  21. /**
  22. * @brief
  23. */
  24. #define LOG_RELEASE(fmt, ...) printf("" fmt, ##__VA_ARGS__);
  25. #define LOGI(fmt, ...) printf("" fmt, ##__VA_ARGS__);
  26. #define LOGD(fmt, ...) printf("D:" fmt, ##__VA_ARGS__);
  27. #define LOGE(fmt, ...) printf("E:" fmt, ##__VA_ARGS__);
  28. #if 0
  29. #define LOGI(fmt, ...) printf("" fmt, ##__VA_ARGS__);
  30. #define LOGD(fmt, ...) printf("D:" fmt, ##__VA_ARGS__);
  31. #define LOGE(fmt, ...) printf("E:" fmt, ##__VA_ARGS__);
  32. #else
  33. #define LOGI(fmt, ...) printf("" fmt, ##__VA_ARGS__);
  34. #define LOGD(fmt, ...)
  35. #define LOGE(fmt, ...)
  36. #endif
  37. static uint8_t s_order_rxbuf;
  38. static uint8_t s_rxbuf[50];
  39. static uint8_t s_rxbuf_has_received;
  40. static bool s_rxbuf_is_ready;
  41. //连续输出PWM
  42. static bool g_continue_output_mode;
  43. static uint32_t g_pulse_num = 0;
  44. static bool g_internal_sync_mode;
  45. void set_mode_in_internal_pwm_mode() {
  46. // LOG_RELEASE("内部信号同步模式\n");
  47. EXT_OEn_SET(true);
  48. PWM_OEn_SET(false);
  49. g_internal_sync_mode = true;
  50. }
  51. void set_mode_in_external_pwm_mode() {
  52. EXT_OEn_SET(false);
  53. PWM_OEn_SET(true);
  54. // LOG_RELEASE("外部信号同步模式\n");
  55. g_internal_sync_mode = false;
  56. }
  57. /**
  58. * @brief
  59. *
  60. * @param husart
  61. */
  62. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
  63. if (&huart1 == huart) {
  64. /**
  65. * @brief
  66. */
  67. if (!s_rxbuf_is_ready) {
  68. if (s_order_rxbuf == 'S') {
  69. s_rxbuf_has_received = 0;
  70. s_rxbuf[s_rxbuf_has_received] = s_order_rxbuf;
  71. s_rxbuf_has_received++;
  72. } else if (s_rxbuf_has_received != 0) {
  73. s_rxbuf[s_rxbuf_has_received] = s_order_rxbuf;
  74. s_rxbuf_has_received++;
  75. }
  76. if (s_rxbuf_has_received == 20) {
  77. s_rxbuf_is_ready = true;
  78. }
  79. }
  80. // HAL_UART_Receive_IT(&ORDER_UART, &s_order_rxbuf, 1);
  81. }
  82. }
  83. void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
  84. if (&ORDER_UART == huart) {
  85. // HAL_UART_Receive_IT(&ORDER_UART, &s_order_rxbuf, 1);
  86. }
  87. }
  88. void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) {
  89. if (&ORDER_UART == huart) {
  90. // HAL_UART_Receive_IT(&ORDER_UART, &s_order_rxbuf, 1);
  91. }
  92. }
  93. void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) {
  94. if (&ORDER_UART == huart) {
  95. // HAL_UART_Receive_IT(&ORDER_UART, &s_order_rxbuf, 1);
  96. }
  97. }
  98. void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
  99. if (htim->Instance == TIM3) {
  100. /**
  101. * @brief
  102. */
  103. #if 1
  104. if (g_continue_output_mode) return;
  105. if (g_pulse_num == 0) {
  106. HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
  107. } else {
  108. g_pulse_num--;
  109. }
  110. #endif
  111. }
  112. }
  113. /**
  114. * @brief PWM的周期
  115. *
  116. * @param target_pluse_width_us
  117. * @param targetfreq
  118. * @param arr
  119. * @return uint16_t COMPARE寄存器的数值
  120. */
  121. uint16_t get_tim_compare_value(int32_t target_pluse_width_us,
  122. int32_t targetfreq, uint16_t arr) {
  123. uint16_t comparevalue = 0;
  124. float periodus = 1.0 / targetfreq * 1000 * 1000;
  125. float duty_radio = target_pluse_width_us / periodus;
  126. if (duty_radio >= 1) duty_radio = 1;
  127. comparevalue = duty_radio * (arr + 1);
  128. if (comparevalue < 2) {
  129. return 1;
  130. }
  131. comparevalue = comparevalue - 1;
  132. return comparevalue;
  133. }
  134. /**
  135. * @brief PWM
  136. *
  137. * @param freq
  138. * @param pluse_width
  139. * @param pluse_num
  140. */
  141. void trigger_pwm(int32_t freq, float duty, int32_t pluse_num) {
  142. //无论怎样先停止PWM输
  143. HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
  144. if (freq == 0) {
  145. LOGE("E:trigger pwm fail,freq == 0\n");
  146. return;
  147. }
  148. // 确定预分频参数,重载值
  149. float psc_x_arr = 90 * 1000 /*系统时钟*/ * 1000 / freq;
  150. uint32_t psc = 0;
  151. uint32_t arr = 65534;
  152. for (; arr > 2; arr--) {
  153. psc = psc_x_arr / arr;
  154. if (psc >= 1) {
  155. uint32_t tmparr = psc_x_arr / psc;
  156. if (tmparr >= 65534) continue;
  157. break;
  158. }
  159. }
  160. if (psc == 0) return;
  161. if (arr <= 3) return; //定时器一周期的分辨率太小了
  162. arr = psc_x_arr / psc;
  163. arr = arr - 1;
  164. psc = psc - 1;
  165. __HAL_TIM_SET_AUTORELOAD(&htim3, arr);
  166. __HAL_TIM_SET_PRESCALER(&htim3, psc);
  167. // 确定PWM通道占空比
  168. uint16_t comparevalue = duty * arr;
  169. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, comparevalue);
  170. if (pluse_num == 0) {
  171. g_continue_output_mode = true;
  172. } else {
  173. g_pulse_num = pluse_num - 1;
  174. g_continue_output_mode = false;
  175. }
  176. __HAL_TIM_SET_COUNTER(&htim3, 0);
  177. LOGD("a[%d] p[%d]c[%d]\r\n", arr, psc, comparevalue);
  178. HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);
  179. }
  180. void process_rxbuf() {
  181. // clang-format off
  182. /**
  183. *
  184. * @brief
  185. *
  186. * S0000112345601234567
  187. * S 0 0 0 0 1 1 2 3 4 5 6 0 1 2 3 4 5 6 7
  188. * [S] [2][3][4][5][6] [7][8][9][10][11][12][13] [14][15][16][17][18][19][20]
  189. * HZ 0.1us
  190. *
  191. *
  192. */
  193. // clang-format on
  194. LOGD("rx:%s\r\n", s_rxbuf);
  195. char freq_c[6] = {0};
  196. char pluse_width_c[8] = {0};
  197. char pluse_num_c[8] = {0};
  198. int32_t freq = 0, pluse_width = 0, pluse_num = 0;
  199. memcpy(freq_c, &s_rxbuf[1], 5);
  200. memcpy(pluse_width_c, &s_rxbuf[6], 7);
  201. memcpy(pluse_num_c, &s_rxbuf[13], 7);
  202. freq = atoi(freq_c);
  203. pluse_width = atoi(pluse_width_c);
  204. pluse_num = atoi(pluse_num_c);
  205. //使能内部,失能外部
  206. set_mode_in_internal_pwm_mode();
  207. /**
  208. * @brief pwm
  209. */
  210. // LOG_RELEASE("触发PWM 频率:%dHZ,脉冲宽度:%dus,脉冲数量:%d\n", freq,
  211. // pluse_width, pluse_num);
  212. float duty = pluse_width / 10.0 / (1 * 1000 * 1000.0 / freq);
  213. LOGI("f[%d]hz \r\n", freq);
  214. LOGI("w[%d]us \r\n", pluse_width/10);
  215. trigger_pwm(freq, duty, pluse_num);
  216. }
  217. void user_main() {
  218. // LOG_RELEASE("wavebox %s\r\n", VERSION);
  219. // LOG_RELEASE("%s\r\n", "www.zwtime.com");
  220. HAL_UART_Receive_IT(&ORDER_UART, &s_order_rxbuf, 1);
  221. set_mode_in_external_pwm_mode();
  222. while (true) {
  223. /**
  224. * @brief
  225. */
  226. HAL_IWDG_Refresh(&hiwdg);
  227. #if 1
  228. if (s_rxbuf_is_ready) {
  229. process_rxbuf();
  230. s_rxbuf_is_ready = false;
  231. s_rxbuf_has_received = 0;
  232. }
  233. #endif
  234. if (ORDER_UART.RxState == HAL_UART_STATE_READY) {
  235. HAL_UART_Receive_IT(&ORDER_UART, &s_order_rxbuf, 1);
  236. }
  237. /**
  238. * @brief
  239. */
  240. {
  241. static uint32_t lastprocess = 0;
  242. if (port_haspassedms(lastprocess) > 300) {
  243. lastprocess = HAL_GetTick();
  244. HAL_GPIO_TogglePin(DEBUG_LIGHT_PORT, DEBUG_LIGHT_PIN);
  245. }
  246. }
  247. /**/
  248. }
  249. }