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.
243 lines
5.9 KiB
243 lines
5.9 KiB
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "board.h"
|
|
#include "port.h"
|
|
//
|
|
#include "gpio.h"
|
|
#include "main.h"
|
|
#include "tim.h"
|
|
#include "usart.h"
|
|
//
|
|
#include "stm32f429xx.h"
|
|
#include "stm32f4xx_hal_tim.h"
|
|
#include "stm32f4xx_hal_usart.h"
|
|
|
|
/**
|
|
* @brief 初始化所有IO状态
|
|
*/
|
|
|
|
/**
|
|
* @brief 底层驱动
|
|
*/
|
|
#define LOG_RELEASE(fmt, ...) printf("" fmt, ##__VA_ARGS__);
|
|
#define LOGI(fmt, ...) printf("I:" fmt, ##__VA_ARGS__);
|
|
#define LOGD(fmt, ...) printf("D:" fmt, ##__VA_ARGS__);
|
|
#define LOGE(fmt, ...) printf("E:" fmt, ##__VA_ARGS__);
|
|
|
|
static uint8_t s_order_rxbuf;
|
|
static uint8_t s_rxbuf[20];
|
|
static uint8_t s_rxbuf_has_received;
|
|
static bool s_rxbuf_is_ready;
|
|
|
|
//连续输出PWM
|
|
static bool g_continue_output_mode;
|
|
static uint32_t g_pulse_num = 0;
|
|
static bool g_internal_sync_mode;
|
|
void set_mode_in_internal_pwm_mode() {
|
|
LOG_RELEASE("内部信号同步模式\n");
|
|
EXT_OEn_SET(true);
|
|
PWM_OEn_SET(false);
|
|
g_internal_sync_mode = true;
|
|
}
|
|
void set_mode_in_external_pwm_mode() {
|
|
EXT_OEn_SET(false);
|
|
PWM_OEn_SET(true);
|
|
LOG_RELEASE("外部信号同步模式\n");
|
|
g_internal_sync_mode = false;
|
|
}
|
|
|
|
/**
|
|
* @brief 串口数据接收回调
|
|
*
|
|
* @param husart
|
|
*/
|
|
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
|
if (&huart1 == huart) {
|
|
/**
|
|
* @brief 接收并处指令串口的数据
|
|
*/
|
|
if (!s_rxbuf_is_ready) {
|
|
if (s_order_rxbuf == 'S') {
|
|
s_rxbuf[s_rxbuf_has_received] = s_order_rxbuf;
|
|
s_rxbuf_has_received++;
|
|
} else if (s_rxbuf_has_received != 0) {
|
|
s_rxbuf[s_rxbuf_has_received] = s_order_rxbuf;
|
|
s_rxbuf_has_received++;
|
|
}
|
|
|
|
if (s_rxbuf_has_received == 20) {
|
|
s_rxbuf_is_ready = true;
|
|
}
|
|
}
|
|
|
|
HAL_UART_Receive_IT(&huart1, &s_order_rxbuf, 1);
|
|
}
|
|
}
|
|
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
|
|
if (&huart1 == huart) {
|
|
HAL_UART_Receive_IT(&huart1, &s_order_rxbuf, 1);
|
|
}
|
|
}
|
|
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
|
|
if (htim->Instance == TIM3) {
|
|
/**
|
|
* @brief 当触发完指定数量的脉冲时,停止触发
|
|
*/
|
|
if (g_continue_output_mode) return;
|
|
|
|
if (g_pulse_num == 0) {
|
|
HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
|
|
} else {
|
|
g_pulse_num--;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* @brief 计算PWM的周期
|
|
*
|
|
* @param target_pluse_width_us
|
|
* @param targetfreq
|
|
* @param arr
|
|
* @return uint16_t 返回COMPARE寄存器的数值
|
|
*/
|
|
uint16_t get_tim_compare_value(int32_t target_pluse_width_us,
|
|
int32_t targetfreq, uint16_t arr) {
|
|
uint16_t comparevalue = 0;
|
|
float periodus = 1.0 / targetfreq * 1000 * 1000;
|
|
float duty_radio = target_pluse_width_us / periodus;
|
|
if (duty_radio >= 1) duty_radio = 1;
|
|
comparevalue = duty_radio * (arr + 1);
|
|
if (comparevalue < 2) {
|
|
return 1;
|
|
}
|
|
comparevalue = comparevalue - 1;
|
|
return comparevalue;
|
|
}
|
|
/**
|
|
* @brief 触发一次PWM
|
|
*
|
|
* @param freq
|
|
* @param pluse_width
|
|
* @param pluse_num
|
|
*/
|
|
void trigger_pwm(int32_t freq, float duty, int32_t pluse_num) {
|
|
#if 1
|
|
LOGI("I:trigger pwm freq[%d] duty[%f]us pluse_num[%d]\n", freq, duty,
|
|
pluse_num);
|
|
#endif
|
|
|
|
//无论怎样先停止PWM输
|
|
|
|
HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
|
|
if (freq == 0) {
|
|
LOGE("E:trigger pwm fail,freq == 0\n");
|
|
return;
|
|
}
|
|
// 确定预分频参数,重载值
|
|
float psc_x_arr = 84 * 1000 * 1000 / freq;
|
|
uint32_t psc = 0;
|
|
uint32_t arr = 65534;
|
|
for (; arr > 2; arr--) {
|
|
psc = psc_x_arr / arr;
|
|
if (psc >= 1) {
|
|
uint32_t tmparr = psc_x_arr / psc;
|
|
if (tmparr >= 65534) continue;
|
|
break;
|
|
}
|
|
}
|
|
if (psc == 0) return;
|
|
if (arr <= 3) return; //定时器一周期的分辨率太小了
|
|
|
|
arr = psc_x_arr / psc;
|
|
|
|
arr = arr - 1;
|
|
psc = psc - 1;
|
|
|
|
__HAL_TIM_SET_AUTORELOAD(&htim3, arr);
|
|
__HAL_TIM_SET_PRESCALER(&htim3, psc);
|
|
// 确定PWM通道占空比
|
|
uint16_t comparevalue = duty * arr;
|
|
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, comparevalue);
|
|
if (pluse_num == 0) {
|
|
g_continue_output_mode = true;
|
|
} else {
|
|
g_pulse_num = pluse_num - 1;
|
|
g_continue_output_mode = false;
|
|
}
|
|
__HAL_TIM_SET_COUNTER(&htim3, 0);
|
|
LOGI("I:trigger arr [%d] psc[%d] comparevalue[%d]\n", arr, psc, comparevalue);
|
|
HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);
|
|
}
|
|
|
|
void process_rxbuf() {
|
|
// clang-format off
|
|
/**
|
|
*
|
|
* @brief 协议
|
|
*
|
|
* [S] [2][3][4][5][6] [7][8][9][10][11][12][13] [14][15][16][17][18][19][20]
|
|
* 开始标志 频率值HZ 脉宽us 脉冲数
|
|
*
|
|
*
|
|
*/
|
|
// clang-format on
|
|
char freq_c[6] = {0};
|
|
char pluse_width_c[8] = {0};
|
|
char pluse_num_c[8] = {0};
|
|
int32_t freq = 0, pluse_width = 0, pluse_num = 0;
|
|
|
|
memcpy(freq_c, &s_rxbuf[1], 5);
|
|
memcpy(pluse_width_c, &s_rxbuf[6], 7);
|
|
memcpy(pluse_num_c, &s_rxbuf[13], 7);
|
|
|
|
freq = atoi(freq_c);
|
|
pluse_width = atoi(pluse_width_c);
|
|
pluse_num = atoi(pluse_num_c);
|
|
|
|
//使能内部,失能外部
|
|
set_mode_in_internal_pwm_mode();
|
|
/**
|
|
* @brief 触发一次pwm
|
|
*/
|
|
LOG_RELEASE("触发PWM 频率:%dHZ,脉冲宽度:%dus,脉冲数量:%d\n", freq,
|
|
pluse_width, pluse_num);
|
|
|
|
float duty = pluse_width / (1 * 1000 * 1000 / freq);
|
|
trigger_pwm(freq, duty, pluse_num);
|
|
}
|
|
|
|
void user_main() {
|
|
LOG_RELEASE("同步盒子\n");
|
|
LOG_RELEASE("网址:%s\n", "www.zwtime.com");
|
|
LOG_RELEASE("软件版本:%s\n", VERSION);
|
|
|
|
LOGI("I:wavebox sv:%s\n", VERSION);
|
|
|
|
HAL_UART_Receive_IT(&huart1, &s_order_rxbuf, 1);
|
|
set_mode_in_external_pwm_mode();
|
|
while (true) {
|
|
/**
|
|
* @brief 处理接收到的数据
|
|
*/
|
|
if (s_rxbuf_is_ready) {
|
|
process_rxbuf();
|
|
s_rxbuf_is_ready = false;
|
|
}
|
|
|
|
/**
|
|
* @brief 调制指示灯
|
|
*/
|
|
{
|
|
static uint32_t lastprocess = 0;
|
|
if (port_haspassedms(lastprocess) > 300) {
|
|
lastprocess = HAL_GetTick();
|
|
HAL_GPIO_TogglePin(DEBUG_LIGHT_PORT, DEBUG_LIGHT_PIN);
|
|
}
|
|
}
|
|
/**/
|
|
}
|
|
}
|