完成CANFD通信调试

This commit is contained in:
cbb
2025-10-14 00:49:58 +08:00
parent 2d807260c5
commit a63a344f89
13 changed files with 704 additions and 509 deletions
+4 -1
View File
@@ -77,7 +77,10 @@ CurrentKalman::CurrentKalman(float initial_current, float L, float R, float T,
: x(initial_current), P(1.0f), // 初始误差协方差 : x(initial_current), P(1.0f), // 初始误差协方差
Q(Q), // 过程噪声 Q(Q), // 过程噪声
R(R_noise), // 测量噪声 R(R_noise), // 测量噪声
L(L), R_m(R), T(T) {} L(L), R_m(R), T(T) {
CircularBuffer buffer;
}
/*! /*!
\brief 更新卡尔曼滤波器状态 \brief 更新卡尔曼滤波器状态
\param[in] measured_current 测量电流值 \param[in] measured_current 测量电流值
-3
View File
@@ -66,9 +66,6 @@ class CurrentKalman {
void setMeasurementNoise(float r); void setMeasurementNoise(float r);
}; };
extern CurrentKalman kalman;
extern CircularBuffer buffer;
#endif // __cplusplus #endif // __cplusplus
#endif // _FILTER_H #endif // _FILTER_H
@@ -978,7 +978,8 @@ void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_m
receive_message->rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number))); receive_message->rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
} else { } else {
CAN_ERROR_HANDLE("CAN FD function disabled \r\n"); printf("CAN FD function disabled but FD frame received\r\n");
// CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
} }
} else { } else {
+1 -1
View File
@@ -1,4 +1,3 @@
# A project translates into one executable or library.
project: project:
groups: groups:
- group: Source Files - group: Source Files
@@ -21,6 +20,7 @@ project:
- file: device/adc.h - file: device/adc.h
- file: device/Timer.cpp - file: device/Timer.cpp
- file: device/Timer.h - file: device/Timer.h
- file: device/test.cpp
- group: Algorithm - group: Algorithm
files: files:
- file: Algorithm/Filter.cpp - file: Algorithm/Filter.cpp
+2 -2
View File
@@ -7,7 +7,7 @@ constexpr float ERROR_ADC_VAL = 255.0f;
constexpr float ADC_SCALE = 3.3f / 4096.0f; constexpr float ADC_SCALE = 3.3f / 4096.0f;
constexpr float TEMP_FACTOR = 1000.0f / 4.3f; constexpr float TEMP_FACTOR = 1000.0f / 4.3f;
constexpr float VCC_FACTOR = 11.0f; constexpr float VCC_FACTOR = 11.0f;
constexpr float CURRENT_FACTOR = 1.0f / 50.0f * 100.0f; constexpr float CURRENT_FACTOR = 1.0f / 50.0f * 100.0f * 1000.0f;
constexpr float MAX_TEMP = 150.0f; constexpr float MAX_TEMP = 150.0f;
constexpr float MIN_TEMP = -40.0f; constexpr float MIN_TEMP = -40.0f;
constexpr float MAX_CURRENT = 50.0f; constexpr float MAX_CURRENT = 50.0f;
@@ -102,7 +102,7 @@ float get_vbus_voltage() {
float vcc_latest = ERROR_ADC_VAL; float vcc_latest = ERROR_ADC_VAL;
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
// 获取电压值 // 获取电压值
vcc_latest = adc_value[6] * ADC_SCALE * VCC_FACTOR; vcc_latest = adc_value[5] * ADC_SCALE * VCC_FACTOR;
// 检查电压读数是否在有效范围内 // 检查电压读数是否在有效范围内
if (vcc_latest > MAX_VCC || vcc_latest < MIN_VCC) { if (vcc_latest > MAX_VCC || vcc_latest < MIN_VCC) {
+406 -276
View File
@@ -1,26 +1,41 @@
#include "Can.h" #include "Can.h"
#include "gd32c10x.h"
#include "gd32c10x_can.h" #include "gd32c10x_can.h"
#include "gd32c10x_eval.h"
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <inttypes.h> #include <inttypes.h>
#include <random>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#define DEV_CAN0_ID 0x0000
#define DEV_CAN0_MASK 0x0000
#define CANX CAN0
#define DEV_CAN_LOOPBACK_ID 0x0000 #define DEV_CAN_LOOPBACK_ID 0x0000
#define DEV_CAN0_ID 0xaabb
#define DEV_CAN0_MASK 0x0000
extern CAN_transmiter CAN0_transmiter;
/*!
\brief initialize CAN GPIO
\param[in] none
\param[out] none
\retval ErrStatus: SUCCESS or ERROR
*/
u8 can_gpio_init() { u8 can_gpio_init() {
/* enable CAN clock */ /* enable CAN clock */
rcu_periph_clock_enable(RCU_CAN0); rcu_periph_clock_enable(RCU_CAN0);
rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_AF);
/* configure CAN0 GPIO */
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_MAX, GPIO_PIN_11);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_MAX, GPIO_PIN_12);
/* enable the EN GPIO clock */
rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_AF);
/* configure CAN0 GPIO */
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_11); // tx
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12); // rx
gpio_pin_remap_config(GPIO_CAN0_FULL_REMAP, DISABLE);
/* enable the EN GPIO clock */
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
gpio_bit_reset(GPIOB, GPIO_PIN_13); gpio_bit_reset(GPIOB, GPIO_PIN_13);
return 0; return 0;
@@ -33,8 +48,9 @@ u8 can_gpio_init() {
\retval none \retval none
*/ */
void can_config(void) { void can_config(void) {
can_gpio_init();
can_parameter_struct can_parameter; can_parameter_struct can_parameter;
can_filter_parameter_struct can_filter; can_filter_parameter_struct can_filter;
can_struct_para_init(CAN_INIT_STRUCT, &can_parameter); can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
/* initialize CAN register */ /* initialize CAN register */
@@ -52,31 +68,31 @@ void can_config(void) {
can_parameter.resync_jump_width = CAN_BT_SJW_1TQ; can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
can_parameter.time_segment_1 = CAN_BT_BS1_7TQ; can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ; can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
can_parameter.prescaler = 12; can_parameter.prescaler = 6;
/* initialize CAN */ /* initialize CAN */
can_init(CAN0, &can_parameter); if (can_init(CAN0, &can_parameter) != SUCCESS) {
while (1)
printf("can init error \r\n");
}
/* initialize filter */ /* initialize filter */
/* configure filter mode */ /* configure filter mode */
can_filter.filter_mode = CAN_FILTERMODE_MASK; can_filter.filter_mode = CAN_FILTERMODE_MASK;
can_filter.filter_bits = CAN_FILTERBITS_32BIT; can_filter.filter_bits = CAN_FILTERBITS_32BIT;
/* configure filter ID */ /* configure filter mask */
can_filter.filter_list_high = (uint16_t)(DEV_CAN_LOOPBACK_ID >> 13U); can_filter.filter_mask_high = 0x0000;
can_filter.filter_list_low = ((uint16_t)(DEV_CAN_LOOPBACK_ID)) << 3U | (1U << 2); can_filter.filter_mask_low = 0x0000;
/* configure filter mask */ /* select receiver fifo */
can_filter.filter_mask_high = 0x0000; can_filter.filter_fifo_number = CAN_FIFO0;
can_filter.filter_mask_low = 0x0000; can_filter.filter_enable = ENABLE;
/* select receiver fifo */ /* configure filter number */
can_filter.filter_fifo_number = CAN_FIFO0; can_filter.filter_number = 0;
can_filter.filter_enable = ENABLE; can_filter_init(&can_filter);
can_filter_init(&can_filter);
/* configure CAN0 NVIC */ /* configure CAN0 NVIC */
nvic_irq_enable(CAN0_RX0_IRQn, 0, 0); nvic_irq_enable(CAN0_RX0_IRQn, 1, 0);
/* enable can receive FIFO0 not empty interrupt */ /* enable can receive FIFO0 not empty interrupt */
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0); can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
} }
/*! /*!
@@ -86,18 +102,16 @@ void can_config(void) {
\retval none \retval none
*/ */
void canfd_config(void) { void canfd_config(void) {
can_gpio_init();
can_parameter_struct can_parameter; can_parameter_struct can_parameter;
can_fdframe_struct can_fd_parameter; can_fdframe_struct can_fd_parameter;
can_fd_tdc_struct can_fd_tdc_parameter; can_fd_tdc_struct can_fd_tdc_parameter;
can_filter_parameter_struct can_filter; can_filter_parameter_struct can_filter;
/* enable CAN clock */ /* initialize CAN register */
rcu_periph_clock_enable(RCU_CAN0); can_deinit(CAN0);
/* initialize CAN register */ /* initialize CAN */
can_deinit(CAN0);
/* initialize CAN parameters */
can_parameter.time_triggered = DISABLE; can_parameter.time_triggered = DISABLE;
can_parameter.auto_bus_off_recovery = DISABLE; can_parameter.auto_bus_off_recovery = DISABLE;
can_parameter.auto_wake_up = DISABLE; can_parameter.auto_wake_up = DISABLE;
@@ -109,8 +123,7 @@ void canfd_config(void) {
can_parameter.resync_jump_width = CAN_BT_SJW_1TQ; can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
can_parameter.time_segment_1 = CAN_BT_BS1_7TQ; can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ; can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
can_parameter.prescaler = 12; can_parameter.prescaler = 6;
/* initialize CAN */
can_init(CAN0, &can_parameter); can_init(CAN0, &can_parameter);
can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter); can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);
@@ -129,17 +142,29 @@ void canfd_config(void) {
can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ; can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ;
/* CAN-FD data segement prescaler should be the same as non-data segement /* CAN-FD data segement prescaler should be the same as non-data segement
* prescaler */ * prescaler */
can_fd_parameter.data_prescaler = 12; can_fd_parameter.data_prescaler = 6;
can_fd_init(CAN0, &can_fd_parameter); can_fd_init(CAN0, &can_fd_parameter);
/* initialize filter */ /* initialize filter */
can1_filter_start_bank(14); can_filter.filter_mode = CAN_FILTERMODE_MASK;
can_filter_mask_mode_init(DEV_CAN0_ID, DEV_CAN0_MASK, CAN_EXTENDED_FIFO0, 0); can_filter.filter_bits = CAN_FILTERBITS_32BIT;
/* configure filter ID */
can_filter.filter_list_high = 0x0000;
can_filter.filter_list_low = 0x0000;
/* configure filter mask */
can_filter.filter_mask_high = 0x0000;
can_filter.filter_mask_low = 0x0000;
/* select receiver fifo */
can_filter.filter_fifo_number = CAN_FIFO0;
can_filter.filter_enable = ENABLE;
/* configure filter number */
can_filter.filter_number = 0;
can_filter_init(&can_filter);
/* configure CAN0 NVIC */ /* configure CAN0 NVIC */
nvic_irq_enable(CAN0_RX0_IRQn, 0, 0); nvic_irq_enable(CAN0_RX0_IRQn, 1, 0);
/* enable can receive FIFO0 not empty interrupt */ /* enable can receive FIFO0 not empty interrupt */
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0); can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
} }
/*! /*!
@@ -149,109 +174,171 @@ void canfd_config(void) {
\retval none \retval none
*/ */
void can_loopback_init(void) { void can_loopback_init(void) {
can_gpio_init();
can_parameter_struct can_parameter; can_parameter_struct can_parameter;
can_fdframe_struct can_fd_parameter; can_filter_parameter_struct can_filter;
can_fd_tdc_struct can_fd_tdc_parameter; /* initialize CAN register */
can_filter_parameter_struct can_filter; can_deinit(CANX);
/* enable CAN clock */ /* initialize CAN */
rcu_periph_clock_enable(RCU_CAN0);
/* initialize CAN register */
can_deinit(CAN0);
/* initialize CAN parameters */
can_parameter.time_triggered = DISABLE; can_parameter.time_triggered = DISABLE;
can_parameter.auto_bus_off_recovery = DISABLE; can_parameter.auto_bus_off_recovery = DISABLE;
can_parameter.auto_wake_up = DISABLE; can_parameter.auto_wake_up = DISABLE;
can_parameter.auto_retrans = ENABLE; can_parameter.auto_retrans = DISABLE;
can_parameter.rec_fifo_overwrite = ENABLE; can_parameter.rec_fifo_overwrite = DISABLE;
can_parameter.trans_fifo_order = ENABLE; can_parameter.trans_fifo_order = DISABLE;
can_parameter.working_mode = CAN_LOOPBACK_MODE; can_parameter.working_mode = CAN_NORMAL_MODE;
/* baudrate 1Mbps, sample piont at 80% */ /* baudrate 1Mbps, sample piont at 80% */
can_parameter.resync_jump_width = CAN_BT_SJW_1TQ; can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
can_parameter.time_segment_1 = CAN_BT_BS1_7TQ; can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ; can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
can_parameter.prescaler = 12; can_parameter.prescaler = 6;
/* initialize CAN */ if (can_init(CANX, &can_parameter) != SUCCESS) {
can_init(CAN0, &can_parameter); while (1)
printf("can init error \r\n");
}
can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter); /* initialize filter */
can_fd_parameter.fd_frame = ENABLE; /* configure filter mode */
can_fd_parameter.excp_event_detect = ENABLE; can_filter.filter_mode = CAN_FILTERMODE_MASK;
can_fd_parameter.delay_compensation = ENABLE; can_filter.filter_bits = CAN_FILTERBITS_32BIT;
can_fd_tdc_parameter.tdc_filter = 0x04; /* configure filter ID */
can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET; can_filter.filter_list_high = (uint16_t)(DEV_CAN_LOOPBACK_ID >> 13U);
can_fd_tdc_parameter.tdc_offset = 0x04; can_filter.filter_list_low =
can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter; ((uint16_t)(DEV_CAN_LOOPBACK_ID)) << 3U | (1U << 2);
can_fd_parameter.iso_bosch = CAN_FDMOD_ISO; /* configure filter mask */
can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE; can_filter.filter_mask_high = 0x0000;
/* FD mode data baudrate 2Mbps, sample piont at 80% */ can_filter.filter_mask_low = 0x0000;
can_fd_parameter.data_resync_jump_width = CAN_BT_SJW_1TQ; /* select receiver fifo */
can_fd_parameter.data_time_segment_1 = CAN_BT_BS1_3TQ; can_filter.filter_fifo_number = CAN_FIFO0;
can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ; can_filter.filter_enable = ENABLE;
/* CAN-FD data segement prescaler should be the same as non-data segement /* configure filter number */
* prescaler */ can_filter.filter_number = 0;
can_fd_parameter.data_prescaler = 12; can_filter_init(&can_filter);
can_fd_init(CAN0, &can_fd_parameter);
/* initialize filter */
can1_filter_start_bank(14);
can_filter_mask_mode_init(DEV_CAN_LOOPBACK_ID, DEV_CAN0_MASK, CAN_EXTENDED_FIFO0, 0);
} }
/*! /*!
\brief CAN0 loopback test \brief CAN0 FD回环测试
\param[in] none \param[in] none
\param[out] none \param[out] none
\retval ErrStatus \retval ErrStatus
*/ */
void can_loopback_test(void) { void canfd_loopback_test(void) {
can_trasnmit_message_struct transmit_message; can_trasnmit_message_struct transmit_message;
can_receive_message_struct receive_message; can_receive_message_struct receive_message;
uint32_t timeout = 0xFFFF; uint32_t timeout = 0xFFFF;
uint8_t transmit_mailbox = 0; uint8_t transmit_mailbox = 0;
std::mt19937 gen;
std::uniform_int_distribution<int> dis(0, 255);
can_struct_para_init(CAN_FD_FRAME_STRUCT, &transmit_message); can_struct_para_init(CAN_FD_FRAME_STRUCT, &transmit_message);
transmit_message.tx_sfid = DEV_CAN_LOOPBACK_ID; transmit_message.tx_sfid = DEV_CAN_LOOPBACK_ID;
transmit_message.tx_efid = 0x00; transmit_message.tx_efid = 0x00;
transmit_message.tx_ft = CAN_FT_DATA; transmit_message.tx_ft = CAN_FT_DATA;
transmit_message.tx_ff = CAN_FF_EXTENDED; transmit_message.tx_ff = CAN_FF_EXTENDED;
transmit_message.tx_dlen = 12; transmit_message.tx_dlen = 7;
transmit_message.fd_flag = 1; transmit_message.fd_flag = 1;
transmit_message.fd_brs = 1; transmit_message.fd_brs = 1;
transmit_message.fd_esi = 0; transmit_message.fd_esi = 0;
int i = 0; int i = 0;
while (i++<transmit_message.tx_dlen) { while (i++ < transmit_message.tx_dlen) {
transmit_message.tx_data[i] = i; transmit_message.tx_data[i] = dis(gen);
std::printf("%x\n", transmit_message.tx_data[i]);
} }
/* transmit message */
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
/* waiting for transmit completed */
while ((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) &&
(0 != timeout)) {
timeout--;
}
timeout = 0xFFFF;
/* waiting for receive completed */
while ((can_receive_message_length_get(CAN0, CAN_FIFO0) < 1) &&
(0 != timeout)) {
timeout--;
}
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);
can_message_receive(CAN0, CAN_FIFO0, &receive_message);
/* transmit message */ /* check the receive message */
transmit_mailbox = can_message_transmit(CAN0, &transmit_message); if ((transmit_message.tx_sfid == receive_message.rx_sfid) &&
/* waiting for transmit completed */ (transmit_message.tx_ff == receive_message.rx_ff) &&
while((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) && (0 != timeout)) { (transmit_message.tx_dlen == receive_message.rx_dlen)) {
timeout--; /* loopback test is success */
}
timeout = 0xFFFF;
/* waiting for receive completed */
while((can_receive_message_length_get(CAN0, CAN_FIFO0) < 1) && (0 != timeout)) {
timeout--;
}
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);
can_message_receive(CAN0, CAN_FIFO0, &receive_message);
/* check the receive message */
if((transmit_message.tx_sfid == receive_message.rx_sfid) && (transmit_message.tx_ff == receive_message.rx_ff)
&& (transmit_message.tx_dlen == receive_message.rx_dlen) ) {
/* loopback test is success */
std::printf("CAN LO0PBACK SUCCESS\r\n"); std::printf("CAN LO0PBACK SUCCESS\r\n");
} else { } else {
/* loopback test is failed */ /* loopback test is failed */
std::printf("CAN LO0PBACK FAIL\r\n"); std::printf("CAN LO0PBACK FAIL\r\n");
} }
}
/**
\brief CAN0 回环测试
\param[in] none
\param[out] none
\retval none
*/
void can_loopback_test(void) {
can_trasnmit_message_struct transmit_message;
can_receive_message_struct receive_message;
uint32_t timeout = 0xF;
uint8_t transmit_mailbox = 0;
std::mt19937 gen(rand()); // 使用随机设备生成的种子
std::uniform_int_distribution<int> dis(0, 0xff);
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
/* initialize transmit message */
transmit_message.tx_sfid = DEV_CAN_LOOPBACK_ID;
transmit_message.tx_ft = CAN_FT_DATA;
transmit_message.tx_ff = CAN_FF_STANDARD;
transmit_message.tx_dlen = 7;
int i = 0;
while (i++ < transmit_message.tx_dlen) {
// transmit_message.tx_data[i] = dis(gen);
transmit_message.tx_data[i] = i;
}
/* transmit message */
transmit_mailbox = can_message_transmit(CANX, &transmit_message);
/* waiting for transmit completed */
while ((CAN_TRANSMIT_OK != can_transmit_states(CANX, transmit_mailbox)) &&
(0 != timeout)) {
printf("sending:%x...\n", can_transmit_states(CANX, transmit_mailbox));
timeout--;
}
timeout = 0xFF;
/* waiting for receive completed */
while ((can_receive_message_length_get(CANX, CAN_FIFO0) < 1) &&
(0 != timeout)) {
timeout--;
}
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);
can_message_receive(CANX, CAN_FIFO0, &receive_message);
/* check the receive message */
if ((DEV_CAN_LOOPBACK_ID == receive_message.rx_sfid) &&
(CAN_FF_STANDARD == receive_message.rx_ff) &&
(transmit_message.tx_dlen == receive_message.rx_dlen)) {
i = transmit_message.tx_dlen;
while (i-- > 0) {
std::printf("rx %d:%x:%x\n", i, transmit_message.tx_data[i],
receive_message.rx_data[i]);
}
if (std::memcmp(receive_message.rx_data, transmit_message.tx_data,
transmit_message.tx_dlen) == 0) {
/* loopback test is success */
std::printf("loopback success\n");
} else {
std::printf("loopback failed\n");
}
} else {
/* loopback test is failed */
std::printf("loopback failed\n");
}
} }
/*! /*!
@@ -259,33 +346,14 @@ void can_loopback_test(void) {
\note 初始化CAN通信相关参数和硬件配置 \note 初始化CAN通信相关参数和硬件配置
*/ */
CAN_transmiter::CAN_transmiter() { CAN_transmiter::CAN_transmiter() {
// 初始化成员变量
controller_Mode = 0;
limit_velocity_union.f = 0;
limit_voltage = 0;
mcu_temp = 0;
motor_temp = 0;
Power_Voltage = 0;
rt_angle_union.f = 0;
Status_code = 0;
target_angle_union.f = 0;
Target_Control_Mode = 0;
target_velocity_union.f = 0;
u_current_union.f = 0;
w_current_union.f = 0;
v_current_union.f = 0;
// 初始化CAN硬件 // 初始化CAN硬件
can_gpio_init(); // can_config();
can_config(); canfd_config();
printf("CAN_transmiter initialized successfully\r\n"); // 初始化发送消息结构体
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
transmit_mailbox = CAN_NOMAILBOX; // 初始化为无mailbox状态 /* initialize receive message */
timeout = 0xFFFF; // 默认超时时间 0xFFFF can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);
// 初始化发送消息结构体
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
} }
/*! /*!
@@ -293,142 +361,142 @@ CAN_transmiter::CAN_transmiter() {
*/ */
void CAN_transmiter::update(void) { void CAN_transmiter::update(void) {
limit_velocity_union.f = 0; limit_velocity_union.f = 0;
limit_voltage = 0; limit_voltage = 0 * 1000;
mcu_temp = get_mcu_temp(); mcu_temp = get_mcu_temp() * 100;
motor_temp = get_drv_temp(); motor_temp = get_drv_temp() * 100;
Power_Voltage = get_vbus_voltage(); Power_Voltage = get_vbus_voltage() * 1000;
rt_angle_union.f = 0; rt_angle_union.f = 0;
rt_velocity_union.f = 0; rt_velocity_union.f = 0;
Status_code = (gpio_input_bit_get(GPIOB, GPIO_PIN_2) == SET) ? 1 : 0; Status_code = (gpio_input_bit_get(GPIOB, GPIO_PIN_2) == SET) ? 1 : 0;
target_angle_union.f = 0; target_angle_union.f = 0;
Target_Control_Mode = 0; Target_Control_Mode = 0;
target_velocity_union.f = 0; target_velocity_union.f = 0;
u_current_union.f = get_current('U'); u_current_union.f = get_current('U') * 1000;
w_current_union.f = get_current('W'); w_current_union.f = get_current('W') * 1000;
v_current_union.f = get_current('V'); v_current_union.f = get_current('V') * 1000;
} }
/*! /*!
\brief CAN 数据发送 \brief CAN 数据发送
*/ */
u8 CAN_transmiter::CAN_Send(u32 id, u8 length, u8 *data) { u8 CAN_transmiter::CAN_Send(u32 id, u8 length, u8 *data) {
// 检查数据长度是否符合CAN规范 timeout = 0xFFFF;
if (length > 8) { // 检查数据长度是否符合CAN规范
printf("CAN data length exceeds maximum of 8 bytes\r\n"); if (length > 8) {
return 0; printf("CAN data length exceeds maximum of 8 bytes\r\n");
}
// 检查数据指针是否有效
if (data == nullptr) {
printf("Invalid data pointer\r\n");
return 0;
}
/* 配置发送消息参数 */
transmit_message.tx_ft = CAN_FT_DATA; // 数据帧
transmit_message.tx_ff = CAN_FF_EXTENDED; // 扩展帧格式
transmit_message.tx_sfid = id; // 设置帧ID
transmit_message.tx_dlen = length; // 设置数据长度
// 复制数据到发送缓冲区
for (int i = 0; i < length && i < 8; i++) {
transmit_message.tx_data[i] = *(data + i);
}
// 自动选择空闲mailbox发送消息,不需要人为指定
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
// 检查是否成功获取mailbox
if (CAN_NOMAILBOX == transmit_mailbox) {
// 没有可用的mailbox,可能所有mailbox都在使用中
printf("No available mailbox for CAN transmission\r\n");
return 0;
}
// 等待发送完成,使用自动选择的mailbox进行状态检查
while ((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) &&
(0 != timeout)) {
timeout--;
}
// 超时检查
if (0 == timeout) {
printf("CAN transmission timeout for mailbox %d\r\n", transmit_mailbox);
return 0; return 0;
} }
// 检查数据指针是否有效
if (data == nullptr) {
printf("Invalid data pointer\r\n");
return 0;
}
/* 配置发送消息参数 */
transmit_message.tx_ft = CAN_FT_DATA; // 数据帧
transmit_message.tx_ff = CAN_FF_STANDARD; // 标准帧格式
transmit_message.tx_sfid = id; // 设置帧ID
transmit_message.tx_dlen = length; // 设置数据长度
// 复制数据到发送缓冲区
for (int i = 0; i < length && i < 8; i++) {
transmit_message.tx_data[i] = *(data + i);
}
// 自动选择空闲mailbox发送消息,不需要人为指定
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
// 检查是否成功获取mailbox
if (CAN_NOMAILBOX == transmit_mailbox) {
// 没有可用的mailbox,可能所有mailbox都在使用中
printf("No available mailbox for CAN transmission\r\n");
return 0;
}
// 等待发送完成,使用自动选择的mailbox进行状态检查
while ((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) &&
(0 != timeout)) {
timeout--;
}
// 超时检查
if (0 == timeout) {
printf("CAN transmission timeout for mailbox %d\r\n", transmit_mailbox);
return 0;
}
return 1; return 1;
} }
/*! /*!
\brief CANFD 数据发送 \brief CANFD 数据发送
*/ */
u8 CAN_transmiter::CANFD_Send(u32 id, u8 length, u8 *data) { u8 CAN_transmiter::CANFD_Send(u32 id, u8 length, u8 *data) {
// 检查CANFD模式是否启用 timeout = 0xFFFF;
if (!(CAN_CTL(CAN0) & CAN_CTL_DFZ)) { // 检查CANFD模式是否启用
printf("CANFD mode not enabled\r\n"); if (!(CAN_CTL(CAN0) & CAN_CTL_DFZ)) {
return 0; printf("CANFD mode not enabled\r\n");
} return 0;
}
// 检查数据指针是否有效 // 检查数据指针是否有效
if (data == nullptr) { if (data == nullptr) {
printf("Invalid data pointer\r\n"); printf("Invalid data pointer\r\n");
return 0;
}
// 检查数据长度是否符合CANFD规范
if (length > 64) {
printf("CANFD data length exceeds maximum of 64 bytes\r\n");
return 0;
}
/* 配置发送消息参数 */
transmit_message.tx_ft = CAN_FT_DATA; // 数据帧
transmit_message.tx_ff = CAN_FF_EXTENDED; // 扩展帧格式
transmit_message.tx_sfid = id; // 设置帧ID
transmit_message.tx_dlen = length; // 设置数据长度
// 设置CANFD特定参数
transmit_message.fd_flag = CAN_FDF_FDFRAME; // CANFD帧格式
transmit_message.fd_brs = ENABLE; // 使能比特率切换
transmit_message.fd_esi = DISABLE; // 错误状态指示
// 复制数据到发送缓冲区
for (int i = 0; i < length && i < 64; i++) {
transmit_message.tx_data[i] = *(data + i);
}
// 自动选择空闲mailbox发送消息,不需要人为指定
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
// 检查是否成功获取mailbox
if (CAN_NOMAILBOX == transmit_mailbox) {
// 没有可用的mailbox,可能所有mailbox都在使用中
printf("No available mailbox for CANFD transmission\r\n");
return 0;
}
// 等待发送完成,使用自动选择的mailbox进行状态检查
while ((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) &&
(0 != timeout)) {
timeout--;
}
// 超时检查
if (0 == timeout) {
printf("CANFD transmission timeout for mailbox %d\r\n", transmit_mailbox);
return 0; return 0;
} }
// 检查数据长度是否符合CANFD规范
if (length > 64) {
printf("CANFD data length exceeds maximum of 64 bytes\r\n");
return 0;
}
/* 配置发送消息参数 */
transmit_message.tx_ft = CAN_FT_DATA; // 数据帧
transmit_message.tx_ff = CAN_FF_EXTENDED; // 扩展帧格式
// transmit_message.tx_sfid = id; // 设置帧ID
transmit_message.tx_efid = id; // 扩展帧ID
transmit_message.tx_dlen = length; // 设置数据长度
// 设置CANFD特定参数
transmit_message.fd_flag = CAN_FDF_FDFRAME; // CANFD帧格式
transmit_message.fd_brs = ENABLE; // 使能比特率切换
transmit_message.fd_esi = DISABLE; // 错误状态指示
// 复制数据到发送缓冲区
for (int i = 0; i < length && i < 64; i++) {
transmit_message.tx_data[i] = *(data + i);
}
// 自动选择空闲mailbox发送消息,不需要人为指定
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
// 检查是否成功获取mailbox
if (CAN_NOMAILBOX == transmit_mailbox) {
// 没有可用的mailbox,可能所有mailbox都在使用中
printf("No available mailbox for CANFD transmission\r\n");
return 0;
}
// 等待发送完成,使用自动选择的mailbox进行状态检查
while ((CAN_TRANSMIT_OK != can_transmit_states(CAN0, transmit_mailbox)) &&
(0 != timeout)) {
timeout--;
}
// 超时检查
if (0 == timeout) {
printf("CANFD transmission timeout for mailbox %d\r\n",
transmit_mailbox);
return 0;
}
return 1; return 1;
} }
/** /**
* @brief CAN发送函数 * @brief CAN发送函数
* @retval 0: 发送失败 * @retval 0: 发送失败
* 1: 发送成功 * 1: 发送成功
*/ */
u8 CAN_transmiter::CAN_all_Send(){ u8 CAN_transmiter::CAN_all_Send() {
u32 success_flag = 0; u32 success_flag = 0;
constexpr u32 RT_Vel_Ang_FEED = 0x101; constexpr u32 RT_Vel_Ang_FEED = 0x101;
@@ -437,25 +505,32 @@ u8 CAN_transmiter::CAN_all_Send(){
constexpr u32 Status_FEED = 0x118; constexpr u32 Status_FEED = 0x118;
constexpr u32 Limit_Vel_Vol_FEED = 0x119; constexpr u32 Limit_Vel_Vol_FEED = 0x119;
//打包RT_Vel_Ang_FEED // 打包RT_Vel_Ang_FEED
pack_float_to_bytes(transmit_data, 0, rt_angle_union); pack_float_to_bytes(transmit_data, 0, rt_angle_union);
pack_float_to_bytes(transmit_data, 4, rt_velocity_union); pack_float_to_bytes(transmit_data, 4, rt_velocity_union);
//打包SET_Vel_Ang_FEED success_flag += CAN_Send(RT_Vel_Ang_FEED, 8, transmit_data);
// 打包SET_Vel_Ang_FEED
pack_float_to_bytes(transmit_data, 0, target_angle_union); pack_float_to_bytes(transmit_data, 0, target_angle_union);
pack_float_to_bytes(transmit_data, 4, target_velocity_union); pack_float_to_bytes(transmit_data, 4, target_velocity_union);
//打包Current_FEED success_flag += CAN_Send(SET_Vel_Ang_FEED, 8, transmit_data);
pack_float_to_bytes(transmit_data, 0, u_current_union); // 打包Current_FEED
pack_float_to_bytes(transmit_data, 4, w_current_union); pack_u16_to_bytes(transmit_data, 0, u16(u_current_union.f));
pack_float_to_bytes(transmit_data, 8, v_current_union); pack_u16_to_bytes(transmit_data, 2, u16(w_current_union.f));
//打包Status_FEED pack_u16_to_bytes(transmit_data, 4, u16(v_current_union.f));
success_flag += CAN_Send(Current_FEED, 6, transmit_data);
// 打包Status_FEED
transmit_data[0] = Status_code; transmit_data[0] = Status_code;
transmit_data[1] = controller_Mode; transmit_data[1] = controller_Mode;
pack_short_to_bytes(transmit_data, 2, motor_temp); pack_short_to_bytes(transmit_data, 2, motor_temp);
pack_short_to_bytes(transmit_data, 4, mcu_temp); pack_short_to_bytes(transmit_data, 4, mcu_temp);
pack_short_to_bytes(transmit_data, 6, Power_Voltage); pack_short_to_bytes(transmit_data, 6, Power_Voltage);
//打包Limit_Vel_Vol_FEED success_flag += CAN_Send(Status_FEED, 8, transmit_data);
// 打包Limit_Vel_Vol_FEED
pack_float_to_bytes(transmit_data, 0, limit_velocity_union); pack_float_to_bytes(transmit_data, 0, limit_velocity_union);
pack_short_to_bytes(transmit_data, 4, limit_voltage); pack_short_to_bytes(transmit_data, 4, limit_voltage);
success_flag += CAN_Send(Limit_Vel_Vol_FEED, 6, transmit_data);
return success_flag; return success_flag;
} }
@@ -464,24 +539,22 @@ u8 CAN_transmiter::CAN_all_Send(){
* @retval 0: 发送失败 * @retval 0: 发送失败
* 1: 发送成功 * 1: 发送成功
*/ */
u8 CAN_transmiter::CANFD_all_Send(){ u8 CAN_transmiter::CANFD_all_Send() {
u32 success_flag = 0; u32 success_flag = 0;
constexpr u32 STATUS_ID = 0x18FF100; constexpr u32 STATUS_ID = 0x18FF0100;
constexpr u32 CONFIG_ID = 0x18FF101; constexpr u32 CONFIG_ID = 0x18FF0101;
// 打包status数据 // 打包status数据
pack_short_to_bytes(transmit_data, 0, mcu_temp); pack_short_to_bytes(transmit_data, 0, mcu_temp);
pack_short_to_bytes(transmit_data, 2, motor_temp); pack_short_to_bytes(transmit_data, 2, motor_temp);
pack_float_to_bytes(transmit_data, 4, u_current_union); pack_u16_to_bytes(transmit_data, 4, u16(u_current_union.f));
pack_float_to_bytes(transmit_data, 8, w_current_union); pack_u16_to_bytes(transmit_data, 6, u16(w_current_union.f));
pack_float_to_bytes(transmit_data, 12, v_current_union); pack_u16_to_bytes(transmit_data, 8, u16(v_current_union.f));
transmit_data[16] = Status_code; transmit_data[10] = Status_code;
pack_u16_to_bytes(transmit_data, 17, Power_Voltage); pack_u16_to_bytes(transmit_data, 11, Power_Voltage);
pack_float_to_bytes(transmit_data, 19, rt_angle_union); pack_float_to_bytes(transmit_data, 13, rt_angle_union);
pack_float_to_bytes(transmit_data, 23, rt_velocity_union); pack_float_to_bytes(transmit_data, 17, rt_velocity_union);
success_flag += CANFD_Send(STATUS_ID, 20, transmit_data);
success_flag += CANFD_Send(STATUS_ID, 27, transmit_data);
// 打包config数据 // 打包config数据
transmit_data[0] = controller_Mode; transmit_data[0] = controller_Mode;
@@ -489,8 +562,65 @@ u8 CAN_transmiter::CANFD_all_Send(){
pack_float_to_bytes(transmit_data, 3, limit_velocity_union); pack_float_to_bytes(transmit_data, 3, limit_velocity_union);
pack_float_to_bytes(transmit_data, 7, target_angle_union); pack_float_to_bytes(transmit_data, 7, target_angle_union);
pack_float_to_bytes(transmit_data, 11, target_velocity_union); pack_float_to_bytes(transmit_data, 11, target_velocity_union);
success_flag += CANFD_Send(CONFIG_ID, 16, transmit_data);
success_flag += CANFD_Send(CONFIG_ID, 15, transmit_data);
return success_flag; return success_flag;
} }
/**
* @brief CAN通信检查函数
* @retval 0: 无新消息
* 1: 有新消息
*/
void CAN_transmiter::communication_check() {
uint8_t i = 0;
// CAN0 发送数据标志
if (SET == can0_send_flag) {
// printf("\r\n can0 %X receive data:", receive_message.rx_efid);
CAN0_transmiter.update();
// CAN0_transmiter.CAN_all_Send();
CAN0_transmiter.CANFD_all_Send();
can0_send_flag = RESET;
}
// CAN0 接收数据标志
if (SET == can0_receive_flag) {
// printf("\r\n can0 %X receive data:", receive_message.rx_efid);
// for (i = 0; i < receive_message.rx_dlen; i++) {
// printf(" %02x", receive_message.rx_data[i]);
// }
can0_receive_flag = RESET;
}
}
/**
* @brief CAN0中断服务程序
* @retval 无
*/
void CAN0_RX0_IRQHandler(void) {
// 检查是否是FIFO0消息挂起中断
if (can_interrupt_flag_get(CAN0, CAN_INT_FLAG_RFL0) != RESET) {
// 清除中断标志
can_interrupt_flag_clear(CAN0, CAN_INT_FLAG_RFL0);
// 读取接收到的数据
can_message_receive(CAN0, CAN_FIFO0, &CAN0_transmiter.receive_message);
// 接收标志位置1
CAN0_transmiter.can0_receive_flag = SET;
}
// 检查其他可能的中断源
if (can_interrupt_flag_get(CAN0, CAN_INT_FLAG_RFF0) != RESET) {
// FIFO0满中断
can_interrupt_flag_clear(CAN0, CAN_INT_FLAG_RFF0);
printf("CAN FIFO0 full\n");
}
if (can_interrupt_flag_get(CAN0, CAN_INT_FLAG_RFO0) != RESET) {
// FIFO0溢出中断
can_interrupt_flag_clear(CAN0, CAN_INT_FLAG_RFO0);
printf("CAN FIFO0 overflow\n");
}
}
+49 -44
View File
@@ -18,28 +18,31 @@ typedef union {
} float_union_t; } float_union_t;
// 添加辅助函数用于将short类型数据打包到u8数组中 // 添加辅助函数用于将short类型数据打包到u8数组中
static inline void pack_short_to_bytes(u8* buffer, u16 offset, short value) { static inline void pack_short_to_bytes(u8 *buffer, u16 offset, short value) {
buffer[offset] = (u8)(value & 0xFF); buffer[offset] = (u8)(value & 0xFF);
buffer[offset + 1] = (u8)((value >> 8) & 0xFF); buffer[offset + 1] = (u8)((value >> 8) & 0xFF);
} }
// 添加辅助函数用于将u16类型数据打包到u8数组中 // 添加辅助函数用于将u16类型数据打包到u8数组中
static inline void pack_u16_to_bytes(u8* buffer, u16 offset, u16 value) { static inline void pack_u16_to_bytes(u8 *buffer, u16 offset, u16 value) {
buffer[offset] = (u8)(value & 0xFF); buffer[offset] = (u8)(value & 0xFF);
buffer[offset + 1] = (u8)((value >> 8) & 0xFF); buffer[offset + 1] = (u8)((value >> 8) & 0xFF);
} }
// 添加辅助函数用于将float类型数据打包到u8数组中 // 添加辅助函数用于将float类型数据打包到u8数组中
static inline void pack_float_to_bytes(u8* buffer, u16 offset, float_union_t& float_union) { static inline void pack_float_to_bytes(u8 *buffer, u16 offset,
buffer[offset] = float_union.b[0]; float_union_t &float_union) {
buffer[offset + 1] = float_union.b[1]; buffer[offset] = float_union.b[0];
buffer[offset + 2] = float_union.b[2]; buffer[offset + 1] = float_union.b[1];
buffer[offset + 3] = float_union.b[3]; buffer[offset + 2] = float_union.b[2];
buffer[offset + 3] = float_union.b[3];
} }
u8 can_gpio_init(void); u8 can_gpio_init(void); // CAN引脚初始化
void can_config(void); void can_config(void); // CAN初始化
void canfd_config(void); void canfd_config(void);// CANFD初始化
void CAN0_RX0_IRQHandler(void);// CAN接收中断处理函数
void can_loopback_init(void); void can_loopback_init(void);
void can_loopback_test(void); void can_loopback_test(void);
@@ -50,42 +53,44 @@ void can_loopback_test(void);
class CAN_transmiter { class CAN_transmiter {
private: private:
u8 controller_Mode; u8 controller_Mode = 0; // 电机模式
float_union_t limit_velocity_union; float_union_t limit_velocity_union = {0}; // 限制速度
u16 limit_voltage; u16 limit_voltage = 0; // 限制电压
short mcu_temp; short mcu_temp = 0; // MCU温度
short motor_temp; short motor_temp = 0; // 电机温度
u16 Power_Voltage; u16 Power_Voltage = 0; // 电源电压
float_union_t rt_angle_union; float_union_t rt_angle_union = {0}; // 实时角度
float_union_t rt_velocity_union; float_union_t rt_velocity_union = {0}; // 实时速度
u8 Status_code; u8 Status_code = 0; // 状态码
float_union_t target_angle_union; float_union_t target_angle_union = {0}; // 目标角度
u8 Target_Control_Mode; u8 Target_Control_Mode = 0; // 目标控制模式
float_union_t target_velocity_union; float_union_t target_velocity_union = {0}; // 目标速度
float_union_t u_current_union; float_union_t u_current_union = {0}; // U相电流
float_union_t w_current_union; float_union_t w_current_union = {0}; // W相电流
float_union_t v_current_union; float_union_t v_current_union = {0}; // V相电流
u8 transmit_mailbox; // 初始化为无mailbox状态 can_trasnmit_message_struct transmit_message; // 发送消息结构体
u32 timeout; // 默认超时为0xFFFF u8 transmit_mailbox = CAN_NOMAILBOX; // 初始化为无mailbox状态
u8 transmit_data[64]; // CANFD最大64字节 u32 timeout = 0XFFFF; // 默认超时为0xFFFF
u8 transmit_data[64]; // CANFD最大64字节
can_trasnmit_message_struct transmit_message; void update(); // 更新数据
can_receive_message_struct receive_message; u8 CAN_Receive(); // CAN接收
u8 CANFD_Receive(); // CANFD接收
can_fdframe_struct can_fd_parameter; u8 CAN_Send(u32 ID, u8 length, u8 *data); // CAN发送
can_fd_tdc_struct can_fd_tdc_parameter; u8 CANFD_Send(u32 ID, u8 length, u8 *data); // CANFD发送
u8 CAN_all_Send(); // CAN发送
u8 CANFD_all_Send(); // CANFD发送
public: public:
// 添加构造函数声明 // 添加构造函数声明
CAN_transmiter(); CAN_transmiter();
u8 CAN_Send(u32 ID, u8 length, u8 *data);
u8 CANFD_Send(u32 ID, u8 length, u8 *data); can_receive_message_struct receive_message; // 接收消息结构体
void update(); FlagStatus can0_receive_flag; // CAN0接收标志
u8 CAN_all_Send(); FlagStatus can0_send_flag; // CAN0发送标志
u8 CANFD_all_Send();
u8 CAN_Receive(); void communication_check(); // 通信检查
u8 CANFD_Receive();
}; };
#ifdef __cplusplus #ifdef __cplusplus
+30 -29
View File
@@ -1,22 +1,31 @@
#include "Timer.h" #include "Timer.h"
#include "Can.h"
#include "adc.h" #include "adc.h"
#include "gd32c10x.h" #include "gd32c10x.h"
#include "gd32c10x_gpio.h" #include "gd32c10x_gpio.h"
#include "gd32c10x_timer.h" #include "gd32c10x_timer.h"
#include "initial.h" #include "initial.h"
#include <cstdio>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
constexpr int TIMER1_PRESCALER = 1199; // 配置定时器每100微秒中断一次
constexpr int TIMER1_PERIOD = 9; // 系统时钟为120MHz,要得到100微秒的中断周期
// 可以使用预分频器119,定时器时钟为120MHz/(119+1) = 1MHz
// 然后设置周期为99,即计数100次,1MHz/100 = 10kHz = 100微秒
constexpr int TIMER1_PRESCALER = 119; // 120MHz / 120 = 1MHz
constexpr int TIMER1_PERIOD = 99; // 1MHz / 100 = 100us
constexpr int TIMER0_PRESCALER = 5999; constexpr int TIMER0_PRESCALER = 5999;
constexpr int TIMER0_PERIOD = 15999; constexpr int TIMER0_PERIOD = 15999;
constexpr int TIMER0_CH0_PULSE = 4000; constexpr int TIMER0_CH0_PULSE = 4000;
constexpr int TIMER0_CH1_PULSE = 6000; constexpr int TIMER0_CH1_PULSE = 6000;
constexpr int TIMER0_CH2_PULSE = 8000; constexpr int TIMER0_CH2_PULSE = 8000;
static u32 total_us100_counter = 0; // 总计数器,每100微秒增加1
extern u16 adc_value[7]; extern u16 adc_value[7];
extern CAN_transmiter CAN0_transmiter;
/** /**
* @brief 设置引脚中断优先级 * @brief 设置引脚中断优先级
@@ -40,8 +49,8 @@ void nvic_config(void) {
void timer1_config(void) { void timer1_config(void) {
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
TIMER1 Configuration: TIMER1 Configuration:
TIMER1CLK = SystemCoreClock/12000 = 10KHz, the period is 1s(10000/10000 = TIMER1CLK = SystemCoreClock/120 = 1MHz, the period is 100us(100/1000000 =
1s). 100us).
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
*/ */
timer_parameter_struct timer_struct; timer_parameter_struct timer_struct;
@@ -55,11 +64,11 @@ void timer1_config(void) {
timer_struct_para_init(&timer_struct); timer_struct_para_init(&timer_struct);
/* TIMER1配置参数设置 */ /* TIMER1配置参数设置 */
timer_struct.prescaler = timer_struct.prescaler =
TIMER1_PRESCALER; /* 预分频值:12000分频(从0开始计数) */ TIMER1_PRESCALER; /* 预分频值:120分频(从0开始计数) */
timer_struct.alignedmode = TIMER_COUNTER_EDGE; /* 边沿对齐模式 */ timer_struct.alignedmode = TIMER_COUNTER_EDGE; /* 边沿对齐模式 */
timer_struct.counterdirection = TIMER_COUNTER_UP; /* 向上计数模式 */ timer_struct.counterdirection = TIMER_COUNTER_UP; /* 向上计数模式 */
timer_struct.period = timer_struct.period =
TIMER1_PERIOD; /* 自动重装载值:10000次计数(从0开始计数) */ TIMER1_PERIOD; /* 自动重装载值:100次计数(从0开始计数) */
timer_struct.clockdivision = TIMER_CKDIV_DIV1; /* 时钟分频值:1分频 */ timer_struct.clockdivision = TIMER_CKDIV_DIV1; /* 时钟分频值:1分频 */
timer_init(TIMER1, &timer_struct); timer_init(TIMER1, &timer_struct);
@@ -92,35 +101,27 @@ void TIMER1_IRQHandler(void) {
if (timer_interrupt_flag_get(TIMER1, TIMER_INT_UP) != RESET) { if (timer_interrupt_flag_get(TIMER1, TIMER_INT_UP) != RESET) {
// 清除更新中断标志 // 清除更新中断标志
timer_interrupt_flag_clear(TIMER1, TIMER_INT_UP); timer_interrupt_flag_clear(TIMER1, TIMER_INT_UP);
// 增加总计数器
total_us100_counter++;
// 使用静态变量来跟踪定时器事件 // 每100us执行一次的操作可以放在这里
static u8 ms_counter = 0;
static u8 tens_counter = 0;
static u8 hundreds_counter = 0;
static u16 seconds_counter = 0;
// 增加计数器 if (total_us100_counter % 10 == 0) {
ms_counter++;
if (ms_counter >= 10) {
ms_counter = 0;
tens_counter++;
// 每1ms执行的代码可以放在这里 // 每1ms执行的代码可以放在这里
if (tens_counter >= 10) { CAN0_transmiter.can0_send_flag = SET;
tens_counter = 0; if (total_us100_counter % 100 == 0) {
hundreds_counter++;
// 每10ms执行的代码可以放在这里 // 每10ms执行的代码可以放在这里
}
if (hundreds_counter >= 10) { if (total_us100_counter % 1000 == 0) {
hundreds_counter = 0; // 每100ms执行的代码可以放在这里
seconds_counter++; }
// 每100ms执行的代码可以放在这里
if (seconds_counter >= 10) { if (total_us100_counter % 10000 == 0) {
seconds_counter = 0; // 每1s执行的代码可以放在这里
// 每1s执行的代码可以放在这里
} // 重置计数器避免溢出
} total_us100_counter = 0;
} }
} }
} }
+38
View File
@@ -0,0 +1,38 @@
#include "Can.h"
#include "Filter.h"
#include "Timer.h"
#include "adc.h"
#include "core_cm4.h"
#include "device/tle5012b.h"
#include "initial.h"
#include "main.h"
#include "sys/initial.h"
#include "systick.h"
#include "tle5012b.h"
#include <cinttypes>
#include <cstdio>
constexpr int status_print = 0;
void test_1111() {
// 初始化CAN回环测试
// can_loopback_init();
// can_config();
if (status_print) {
/* value print */
printf(" the temperature data is %2.2f degrees Celsius\r\n",
get_mcu_temp());
printf(" the drv_temperature data is %2.2f degrees Celsius\r\n",
get_drv_temp());
printf(" the U current data is %2.2f mA\r\n", get_current('U'));
printf(" the V current data is %2.2f mA\r\n", get_current('V'));
printf(" the W current data is %2.2f mA\r\n", get_current('W'));
printf(" the VBUS is %2.2f V\r\n", get_vbus_voltage());
// printf(" the angle is %2.2f\r\n", tle5012b_read());
printf("\n----------------------------------------------------\n");
// TLI5012B测试
Test_TLI5012B();
}
// can_loopback_test();
}
+113 -88
View File
@@ -1,6 +1,9 @@
#include "tle5012b.h" #include "tle5012b.h"
#include "core_cmInstr.h"
#include "gd32c10x_gpio.h" #include "gd32c10x_gpio.h"
#include "gd32c10x_spi.h"
#include "stdbool.h" #include "stdbool.h"
#include "systick.h"
#define SPI_TX_OFF() \ #define SPI_TX_OFF() \
do { \ do { \
@@ -65,12 +68,10 @@ uint16_t spi_rw_half_word(uint32_t spi_periph, const uint16_t i_HalfWord)
{ {
uint32_t to; uint32_t to;
uint16_t data = 0xFFFF; uint16_t data = 0xFFFF;
bool ok = true; bool ok = true;
/* ---------- Send data ---------- */ /* ---------- Send data ---------- */
to = 200; to = 200;
while ((RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)) && --to); while ((RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)) && --to);
if (to == 0) ok = false; if (to == 0) ok = false;
@@ -89,7 +90,7 @@ uint16_t spi_rw_half_word(uint32_t spi_periph, const uint16_t i_HalfWord)
data = spi_i2s_data_receive(spi_periph); /* throw Dummy */ data = spi_i2s_data_receive(spi_periph); /* throw Dummy */
} }
/* ---------- wait bus idle ---------- */ /* ---------- wait bsu idle ---------- */
if (ok) if (ok)
{ {
to = 200; to = 200;
@@ -100,6 +101,7 @@ uint16_t spi_rw_half_word(uint32_t spi_periph, const uint16_t i_HalfWord)
return ok ? data : 0xFFFF; return ok ? data : 0xFFFF;
} }
/** /**
* @brief Write data to TLI5012B register * @brief Write data to TLI5012B register
* @param i_Cmd Command word to send * @param i_Cmd Command word to send
@@ -111,12 +113,16 @@ uint16_t cdd_TLI5012_WriteReg(uint16_t i_Cmd, uint16_t i_Data)
{ {
uint16_t result = 0xFFFF; /* Default error code */ uint16_t result = 0xFFFF; /* Default error code */
SPI_CS_ENABLE(); SPI_CS_ENABLE();
SPI_TX_ON(); __NOP(); __NOP(); __NOP(); // 添加小延时确保CS稳定
result = spi_rw_half_word(SPI0, i_Cmd); result = spi_rw_half_word(SPI0, i_Cmd);
result = spi_rw_half_word(SPI0, i_Data); result = spi_rw_half_word(SPI0, i_Data);
SPI_TX_OFF(); /* Configure MOSI as input to avoid conflicts */ SPI_TX_OFF(); /* Configure MOSI as input to avoid conflicts */
// result = spi_rw_half_word(SPI0, result); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); // 增加延时
result = spi_rw_half_word(SPI0, DUMMY_BYTE);
SPI_CS_DISABLE(); SPI_CS_DISABLE();
SPI_TX_ON(); /* Restore MOSI as output */
__NOP(); __NOP(); __NOP(); // 添加小延时确保CS稳定
return result; return result;
} }
@@ -131,12 +137,16 @@ uint16_t cdd_TLI5012_ReadReg(uint16_t i_Cmd, uint16_t * const i_Data)
{ {
uint16_t result = 0xFFFF; /* Default error code */ uint16_t result = 0xFFFF; /* Default error code */
SPI_CS_ENABLE(); SPI_CS_ENABLE();
SPI_TX_ON(); __NOP(); __NOP(); __NOP(); // 添加小延时确保CS稳定
*i_Data = spi_rw_half_word(SPI0, i_Cmd); *i_Data = spi_rw_half_word(SPI0, i_Cmd);
SPI_TX_OFF(); /* Configure MOSI as input to avoid conflicts */ SPI_TX_OFF(); /* Configure MOSI as input to avoid conflicts */
// *i_Data = spi_rw_half_word(SPI0, DUMMY_BYTE); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
result = spi_rw_half_word(SPI0, result); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); // 增加延时
*i_Data = spi_rw_half_word(SPI0, DUMMY_BYTE);
result = spi_rw_half_word(SPI0, DUMMY_BYTE);
SPI_CS_DISABLE(); SPI_CS_DISABLE();
SPI_TX_ON(); /* Restore MOSI as output */
__NOP(); __NOP(); __NOP(); // 添加小延时确保CS稳定
return result; return result;
} }
@@ -146,16 +156,17 @@ void tle5012b_gpio_init(void)
rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_SPI0); rcu_periph_clock_enable(RCU_SPI0);
rcu_periph_clock_enable(RCU_AF); rcu_periph_clock_enable(RCU_AF);
/* 关闭 JTAG,仅保留 SWD(释放 PA15、PB3、PB4) */
/* JTAG-DP disabled and SW-DP enabled, so SPI0 can use PB3 and PB4 */
gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE); gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
/* -------- SPI0 全 remap:PB3/4/5 + PA15 -------- */
gpio_pin_remap_config(GPIO_SPI0_REMAP, ENABLE); gpio_pin_remap_config(GPIO_SPI0_REMAP, ENABLE);
/* SPI0 GPIO config: NSS/PA15, SCK/PB3, MOSI/PB5 */ /* PA15 → NSS, 推挽输出 */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15); gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
/* PB3 → SCK, PB5 → MOSI, 推挽输出 */
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3 | GPIO_PIN_5); gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3 | GPIO_PIN_5);
/* SPI0 GPIO config: MISO/PB4 */ /* PB4 → MISO, 浮空输入 */
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4); gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_10);
} }
/** /**
@@ -168,15 +179,15 @@ void tle5012b_spi_init(void)
spi_parameter_struct spi_init_str; spi_parameter_struct spi_init_str;
spi_struct_para_init(&spi_init_str); spi_struct_para_init(&spi_init_str);
/* SPI0 parameter config */ /* SPI参数:16bit, 主机, 全双工, CPOL=0 CPHA=1, MSB first */
spi_init_str.device_mode = SPI_MASTER; spi_init_str.device_mode = SPI_MASTER;
spi_init_str.trans_mode = SPI_TRANSMODE_FULLDUPLEX; spi_init_str.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_str.frame_size = SPI_FRAMESIZE_16BIT; spi_init_str.frame_size = SPI_FRAMESIZE_16BIT;
spi_init_str.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE; spi_init_str.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
spi_init_str.nss = SPI_NSS_SOFT; spi_init_str.nss = SPI_NSS_SOFT;
spi_init_str.endian = SPI_ENDIAN_MSB; spi_init_str.endian = SPI_ENDIAN_MSB;
spi_init_str.prescale = SPI_PSC_128; spi_init_str.prescale = SPI_PSC_16; /* 8MHz @ 128MHz */
spi_init(SPI0, &spi_init_str); spi_init(SPI0, &spi_init_str);
spi_nss_output_enable(SPI0); spi_nss_output_enable(SPI0);
spi_nssp_mode_enable(SPI0); spi_nssp_mode_enable(SPI0);
@@ -185,7 +196,6 @@ void tle5012b_spi_init(void)
/** /**
* @brief Initialize TLI5012B magnetic angle sensor * @brief Initialize TLI5012B magnetic angle sensor
* @note This function configures the sensor registers for proper operation * @note This function configures the sensor registers for proper operation
@@ -201,114 +211,129 @@ void cdd_TLI5012_Init(void)
/* Read STAT register to get current status */ /* Read STAT register to get current status */
u16Command = READ_STAT_VALUE; u16Command = READ_STAT_VALUE;
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
printf("\r\n [TLI5012Init] [STAT] read u16Data: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] [STAT] read u16Data: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe);
/* Write STAT register, set Slave_Number = 00 */ /* Write STAT register, set Slave_Number = 00 */
u16Command = 0x0001; u16Command = 0x0001;
u16Data &= 0x9FFF; /* Clear bits 13-14 (Slave_Number) */ u16Data &= 0x9FFF; /* Clear bits 13-14 (Slave_Number) */
u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data); u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
printf("\r\n [TLI5012Init] [STAT] write u16Data: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] [STAT] write u16Data: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe);
/* Read STAT register again to verify write operation */ /* Read STAT register again to verify write operation */
u16Command = READ_STAT_VALUE; u16Command = READ_STAT_VALUE;
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
printf("\r\n [TLI5012Init] [STAT] read u16Data: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] [STAT] read u16Data: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe);
/* ---------- Step 2: Read ACSTAT register ---------- */ /* ---------- Step 2: Read ACSTAT register ---------- */
u16Command = READ_ACSTAT_VALUE; u16Command = READ_ACSTAT_VALUE;
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
printf("\r\n [TLI5012Init] read [ACSTAT]: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] read [ACSTAT]: 0x%04X SafeWord: 0x%04X \r\n", u16Data, u16Safe);
/* ---------- Step 3: Configure MOD1 register ---------- */ /* ---------- Step 3: Configure MOD1 register ---------- */
/* Read current MOD1 register value */ /* Read current MOD1 register value */
u16Command = RD_REG | WRITE_MOD1_VALUE; u16Command = RD_REG | WRITE_MOD1_VALUE;
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
printf("\r\n [TLI5012Init] read MOD1: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] read MOD1: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Write MOD1 register with configuration value */ /* Write MOD1 register with configuration value */
// u16Command = WRITE_MOD1_VALUE; u16Command = WRITE_MOD1_VALUE;
// u16Data = MOD1_VALUE; u16Data = MOD1_VALUE;
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data); u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
// printf("\r\n [TLI5012Init] [MOD1] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] [MOD1] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Verify MOD1 register write operation */ /* Verify MOD1 register write operation */
// u16Command = RD_REG | WRITE_MOD1_VALUE; u16Command = RD_REG | WRITE_MOD1_VALUE;
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// printf("\r\n [TLI5012Init] read MOD1: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] read MOD1: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* ---------- Step 4: Configure MOD2 register ---------- */ /* ---------- Step 4: Configure MOD2 register ---------- */
// /* Read current MOD2 register value */ /* Read current MOD2 register value */
// u16Command = RD_REG | WRITE_MOD2_VALUE; u16Command = RD_REG | WRITE_MOD2_VALUE;
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// printf("\r\n [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Write MOD2 register with configuration value */ /* Write MOD2 register with configuration value */
// u16Command = WRITE_MOD2_VALUE; u16Command = WRITE_MOD2_VALUE;
// u16Data = MOD2_VALUE; u16Data = MOD2_VALUE;
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data); u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
// printf("\r\n [TLI5012Init] [MOD2] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] [MOD2] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Verify MOD2 register write operation */ /* Verify MOD2 register write operation */
// u16Command = RD_REG | WRITE_MOD2_VALUE; u16Command = RD_REG | WRITE_MOD2_VALUE;
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// printf("\r\n [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* ---------- Step 5: Configure MOD3 register ---------- */ /* ---------- Step 5: Configure MOD3 register ---------- */
// /* Read current MOD3 register value */ /* Read current MOD3 register value */
// u16Command = RD_REG | WRITE_MOD3_VALUE; u16Command = RD_REG | WRITE_MOD3_VALUE;
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// printf("\r\n [TLI5012Init] read MOD3: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] read MOD3: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Write MOD3 register with configuration value */ /* Write MOD3 register with configuration value */
// u16Command = WRITE_MOD3_VALUE; u16Command = WRITE_MOD3_VALUE;
// u16Data = MOD3_VALUE; u16Data = MOD3_VALUE;
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data); u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
// printf("\r\n [TLI5012Init] [MOD3] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] [MOD3] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Verify MOD3 register write operation */ /* Verify MOD3 register write operation */
// u16Command = RD_REG | WRITE_MOD3_VALUE; u16Command = RD_REG | WRITE_MOD3_VALUE;
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// printf("\r\n [TLI5012Init] read MOD3: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); printf("\r\n @Joe [TLI5012Init] read MOD3: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Optional: Configure MOD3 register with SSC_OD = 1 (commented out) */ /* ---------- Step 6: Configure MOD4 register ---------- */
/* Read current MOD4 register value */
u16Command = RD_REG | WRITE_MOD4_VALUE;
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
printf("\r\n @Joe [TLI5012Init] read MOD4: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// u16Command = 0x5091; /* Write MOD4 register with configuration value */
// u16Data |= 0x0004; // Set SSC_OD bit u16Command = WRITE_MOD4_VALUE;
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data); u16Data = MOD4_VALUE;
// printf("\r\n [TLI5012Init] [MOD3] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe); u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
printf("\r\n @Joe [TLI5012Init] [MOD4] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
/* Verify MOD4 register write operation */
// /* ---------- Step 6: Configure MOD4 register ---------- */ u16Command = RD_REG | WRITE_MOD4_VALUE;
// /* Read current MOD4 register value */ u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// u16Command = RD_REG | WRITE_MOD4_VALUE; printf("\r\n @Joe [TLI5012Init] read MOD4: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// printf("\r\n [TLI5012Init] read MOD4: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Write MOD4 register with configuration value */
// u16Command = WRITE_MOD4_VALUE;
// u16Data = MOD4_VALUE;
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
// printf("\r\n [TLI5012Init] [MOD4] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
// /* Verify MOD4 register write operation */
// u16Command = RD_REG | WRITE_MOD4_VALUE;
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// printf("\r\n [TLI5012Init] read MOD4: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
} }
void Test_TLI5012B(void) void Test_TLI5012B(void)
{ {
uint16_t u16Command = READ_ANGLE_VALUE; uint16_t u16Command = 0xFFFF;
uint16_t u16Data = 0x0000; uint16_t u16Data = 0x0000;
uint16_t u16Safe = 0x0000; uint16_t u16Safe = 0x0000;
float angle = 0; float angle = 0;
u16Command = READ_ANGLE_VALUE; u16Command = READ_ANGLE_VALUE;
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data); u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
// 输出原始读取的数据,用于诊断
printf("\r\n @Joe RAW AVAL = 0x%04X, SafeWord = 0x%04X \r\n", u16Data, u16Safe);
// 检查是否有错误标志位
if (u16Safe != 0xFFFF && u16Safe != 0x0000) {
printf("\r\n @Joe Warning: Non-ideal SafeWord detected \r\n");
}
// 检查错误位(bit 15)
if (u16Data & 0x8000) {
printf("\r\n @Joe Error: Communication error detected (bit 15 set) \r\n");
}
// 提取角度值(15位)
u16Data = u16Data & 0x7FFF; u16Data = u16Data & 0x7FFF;
printf ( "\r\n AVAL = 0x%04X, SafeWord = 0x%04X \r\n", u16Data, u16Safe); printf ( "\r\n @Joe AVAL = 0x%04X, SafeWord = 0x%04X \r\n", u16Data, u16Safe);
// angle = 360*( ((int16_t)(u16Data << 1)) >> 1)/32768;
angle = ( 360*( ( (int16_t)(u16Data << 1) ) >> 1 ) ) >> 15; // 将15位角度值转换为角度(0-360度)
printf ( "\r\n angle = %f, AVAL = %d \r\n", angle, (((int16_t)(u16Data << 1)) >> 1)); // 0x7FFF = 32767 对应 360度
angle = ((float)u16Data * 360.0f) / 32767.0f;
printf ( "\r\n @Joe angle = %f, AVL = %d \r\n", angle, (int16_t)u16Data);
// 添加额外的传感器状态检查
uint16_t status_data, status_safe;
u16Command = READ_STAT_VALUE;
status_safe = cdd_TLI5012_ReadReg(u16Command, &status_data);
printf("\r\n @Joe STATUS = 0x%04X, Status SafeWord = 0x%04X \r\n", status_data, status_safe);
} }
+13 -32
View File
@@ -3,11 +3,11 @@
#include "Filter.h" #include "Filter.h"
#include "Timer.h" #include "Timer.h"
#include "adc.h" #include "adc.h"
#include "core_cm4.h"
#include "device/tle5012b.h" #include "device/tle5012b.h"
#include "initial.h" #include "initial.h"
#include "sys/initial.h" #include "sys/initial.h"
#include "systick.h" #include "systick.h"
#include "core_cm4.h"
#include "tle5012b.h" #include "tle5012b.h"
#include <cinttypes> #include <cinttypes>
#include <cstdio> #include <cstdio>
@@ -15,44 +15,25 @@
// 全局变量定义 // 全局变量定义
CurrentKalman kalman(0.0f, 0.0026f, 4.8f, 0.0001f, 1e-6f, 0.02f); CurrentKalman kalman(0.0f, 0.0026f, 4.8f, 0.0001f, 1e-6f, 0.02f);
CircularBuffer buffer;
CAN_transmiter CAN0_transmiter; CAN_transmiter CAN0_transmiter;
int main(void) { int main(void) {
systick_config(); // 系统时钟初始化 systick_config(); // 系统时钟初始化
USART0_init(); // 调试串口初始化 USART0_init(); // 调试串口初始化
User_timer_init(); // Timer初始化 User_timer_init(); // Timer初始化
adc_config(); // ADC初始化 adc_config(); // ADC初始化
dma_config(); // DMA采样ADC初始化 dma_config(); // DMA采样ADC初始化
tle5012b_gpio_init(); // TLI5012B初始化 tle5012b_gpio_init(); // TLI5012B初始化
tle5012b_spi_init(); tle5012b_spi_init();
cdd_TLI5012_Init(); // 初始化TLE5012B传感器 // cdd_TLI5012_Init(); // 初始化TLE5012B传感器
watchdog_init(1000); watchdog_init(5000);
// 初始化CAN回环测试
// can_loopback_init();
while (1) { while (1) {
/* clear the FWDGT reset flag */ /* clear the FWDGT reset flag */
fwdgt_counter_reload(); fwdgt_counter_reload();
// can_loopback_test(); CAN0_transmiter.communication_check();
/* value print */ // delay_1ms(2);
// printf(" the temperature data is %2.2f degrees Celsius\r\n",
// get_mcu_temp());
// printf(" the drv_temperature data is %2.2f degrees Celsius\r\n",
// get_drv_temp());
// printf(" the U current data is %2.2f mA\r\n",get_current('U'));
// printf(" the V current data is %2.2f mA\r\n",get_current('V'));
// printf(" the W current data is %2.2f mA\r\n",get_current('W'));
// printf(" the VBUS is %2.2f V\r\n",get_vbus_voltage());
// printf(" the angle is %2.2f\r\n", tle5012b_read());
printf("\n----------------------------------------------------\n");
delay_1ms(700);
// TLI5012B测试
Test_TLI5012B();
Set_Pwm(0, 1500); Set_Pwm(0, 1500);
} }
+14 -2
View File
@@ -56,7 +56,19 @@ void systick_config(void)
/* configure the systick handler priority */ /* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U); NVIC_SetPriority(SysTick_IRQn, 0x00U);
} }
/*!
\brief delay a time in seconds
\param[in] count: count in seconds
\param[out] none
\retval none
*/
void delay_1s(uint32_t count)
{
uint32_t i;
for(i = 0; i < count; i++){
delay_1ms(1000);
}
}
/*! /*!
\brief delay a time in milliseconds \brief delay a time in milliseconds
\param[in] count: count in milliseconds \param[in] count: count in milliseconds
@@ -66,8 +78,8 @@ void systick_config(void)
void delay_1ms(uint32_t count) void delay_1ms(uint32_t count)
{ {
delay = count; delay = count;
while(0U != delay){ while(0U != delay){
fwdgt_counter_reload();
} }
} }
+2
View File
@@ -44,6 +44,8 @@ extern "C" {
void systick_config(void); void systick_config(void);
/* delay a time in milliseconds */ /* delay a time in milliseconds */
void delay_1ms(uint32_t count); void delay_1ms(uint32_t count);
/* delay a time in seconds */
void delay_1s(uint32_t count);
/* delay decrement */ /* delay decrement */
void delay_decrement(void); void delay_decrement(void);