FOC开环调试成功
This commit is contained in:
@@ -77,7 +77,10 @@ CurrentKalman::CurrentKalman(float initial_current, float L, float R, float T,
|
||||
: x(initial_current), P(1.0f), // 初始误差协方差
|
||||
Q(Q), // 过程噪声
|
||||
R(R_noise), // 测量噪声
|
||||
L(L), R_m(R), T(T) {}
|
||||
L(L), R_m(R), T(T) {
|
||||
|
||||
CircularBuffer buffer;
|
||||
}
|
||||
/*!
|
||||
\brief 更新卡尔曼滤波器状态
|
||||
\param[in] measured_current 测量电流值
|
||||
|
||||
@@ -66,9 +66,6 @@ class CurrentKalman {
|
||||
void setMeasurementNoise(float r);
|
||||
};
|
||||
|
||||
extern CurrentKalman kalman;
|
||||
extern CircularBuffer buffer;
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#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)));
|
||||
|
||||
} 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 {
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# A project translates into one executable or library.
|
||||
project:
|
||||
groups:
|
||||
- group: Source Files
|
||||
@@ -21,6 +20,7 @@ project:
|
||||
- file: device/adc.h
|
||||
- file: device/Timer.cpp
|
||||
- file: device/Timer.h
|
||||
- file: device/test.cpp
|
||||
- group: Algorithm
|
||||
files:
|
||||
- file: Algorithm/Filter.cpp
|
||||
|
||||
@@ -7,7 +7,7 @@ constexpr float ERROR_ADC_VAL = 255.0f;
|
||||
constexpr float ADC_SCALE = 3.3f / 4096.0f;
|
||||
constexpr float TEMP_FACTOR = 1000.0f / 4.3f;
|
||||
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 MIN_TEMP = -40.0f;
|
||||
constexpr float MAX_CURRENT = 50.0f;
|
||||
@@ -102,7 +102,7 @@ float get_vbus_voltage() {
|
||||
float vcc_latest = ERROR_ADC_VAL;
|
||||
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) {
|
||||
|
||||
+264
-134
@@ -1,26 +1,41 @@
|
||||
#include "Can.h"
|
||||
#include "gd32c10x.h"
|
||||
#include "gd32c10x_can.h"
|
||||
#include "gd32c10x_eval.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <inttypes.h>
|
||||
#include <random>
|
||||
#include <stdint.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_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() {
|
||||
/* enable CAN clock */
|
||||
rcu_periph_clock_enable(RCU_CAN0);
|
||||
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_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_bit_reset(GPIOB, GPIO_PIN_13);
|
||||
return 0;
|
||||
@@ -33,6 +48,7 @@ u8 can_gpio_init() {
|
||||
\retval none
|
||||
*/
|
||||
void can_config(void) {
|
||||
can_gpio_init();
|
||||
can_parameter_struct can_parameter;
|
||||
can_filter_parameter_struct can_filter;
|
||||
|
||||
@@ -52,31 +68,31 @@ void can_config(void) {
|
||||
can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
|
||||
can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;
|
||||
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
|
||||
can_parameter.prescaler = 12;
|
||||
can_parameter.prescaler = 6;
|
||||
/* initialize CAN */
|
||||
can_init(CAN0, &can_parameter);
|
||||
if (can_init(CAN0, &can_parameter) != SUCCESS) {
|
||||
while (1)
|
||||
printf("can init error \r\n");
|
||||
}
|
||||
|
||||
/* initialize filter */
|
||||
/* configure filter mode */
|
||||
can_filter.filter_mode = CAN_FILTERMODE_MASK;
|
||||
can_filter.filter_bits = CAN_FILTERBITS_32BIT;
|
||||
/* configure filter ID */
|
||||
can_filter.filter_list_high = (uint16_t)(DEV_CAN_LOOPBACK_ID >> 13U);
|
||||
can_filter.filter_list_low = ((uint16_t)(DEV_CAN_LOOPBACK_ID)) << 3U | (1U << 2);
|
||||
/* 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 */
|
||||
nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
|
||||
nvic_irq_enable(CAN0_RX0_IRQn, 1, 0);
|
||||
/* enable can receive FIFO0 not empty interrupt */
|
||||
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -86,18 +102,16 @@ void can_config(void) {
|
||||
\retval none
|
||||
*/
|
||||
void canfd_config(void) {
|
||||
can_gpio_init();
|
||||
can_parameter_struct can_parameter;
|
||||
can_fdframe_struct can_fd_parameter;
|
||||
can_fd_tdc_struct can_fd_tdc_parameter;
|
||||
can_filter_parameter_struct can_filter;
|
||||
|
||||
/* enable CAN clock */
|
||||
rcu_periph_clock_enable(RCU_CAN0);
|
||||
|
||||
/* initialize CAN register */
|
||||
can_deinit(CAN0);
|
||||
|
||||
/* initialize CAN parameters */
|
||||
/* initialize CAN */
|
||||
can_parameter.time_triggered = DISABLE;
|
||||
can_parameter.auto_bus_off_recovery = 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.time_segment_1 = CAN_BT_BS1_7TQ;
|
||||
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
|
||||
can_parameter.prescaler = 12;
|
||||
/* initialize CAN */
|
||||
can_parameter.prescaler = 6;
|
||||
can_init(CAN0, &can_parameter);
|
||||
|
||||
can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);
|
||||
@@ -129,15 +142,27 @@ void canfd_config(void) {
|
||||
can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ;
|
||||
/* CAN-FD data segement prescaler should be the same as non-data segement
|
||||
* prescaler */
|
||||
can_fd_parameter.data_prescaler = 12;
|
||||
can_fd_parameter.data_prescaler = 6;
|
||||
can_fd_init(CAN0, &can_fd_parameter);
|
||||
|
||||
/* initialize filter */
|
||||
can1_filter_start_bank(14);
|
||||
can_filter_mask_mode_init(DEV_CAN0_ID, DEV_CAN0_MASK, CAN_EXTENDED_FIFO0, 0);
|
||||
can_filter.filter_mode = CAN_FILTERMODE_MASK;
|
||||
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 */
|
||||
nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
|
||||
nvic_irq_enable(CAN0_RX0_IRQn, 1, 0);
|
||||
/* enable can receive FIFO0 not empty interrupt */
|
||||
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
|
||||
}
|
||||
@@ -149,103 +174,100 @@ void canfd_config(void) {
|
||||
\retval none
|
||||
*/
|
||||
void can_loopback_init(void) {
|
||||
can_gpio_init();
|
||||
can_parameter_struct can_parameter;
|
||||
can_fdframe_struct can_fd_parameter;
|
||||
can_fd_tdc_struct can_fd_tdc_parameter;
|
||||
can_filter_parameter_struct can_filter;
|
||||
|
||||
/* enable CAN clock */
|
||||
rcu_periph_clock_enable(RCU_CAN0);
|
||||
|
||||
/* initialize CAN register */
|
||||
can_deinit(CAN0);
|
||||
can_deinit(CANX);
|
||||
|
||||
/* initialize CAN parameters */
|
||||
/* initialize CAN */
|
||||
can_parameter.time_triggered = DISABLE;
|
||||
can_parameter.auto_bus_off_recovery = DISABLE;
|
||||
can_parameter.auto_wake_up = DISABLE;
|
||||
can_parameter.auto_retrans = ENABLE;
|
||||
can_parameter.rec_fifo_overwrite = ENABLE;
|
||||
can_parameter.trans_fifo_order = ENABLE;
|
||||
can_parameter.working_mode = CAN_LOOPBACK_MODE;
|
||||
can_parameter.auto_retrans = DISABLE;
|
||||
can_parameter.rec_fifo_overwrite = DISABLE;
|
||||
can_parameter.trans_fifo_order = DISABLE;
|
||||
can_parameter.working_mode = CAN_NORMAL_MODE;
|
||||
/* baudrate 1Mbps, sample piont at 80% */
|
||||
can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
|
||||
can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;
|
||||
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
|
||||
can_parameter.prescaler = 12;
|
||||
/* initialize CAN */
|
||||
can_init(CAN0, &can_parameter);
|
||||
|
||||
can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);
|
||||
can_fd_parameter.fd_frame = ENABLE;
|
||||
can_fd_parameter.excp_event_detect = ENABLE;
|
||||
can_fd_parameter.delay_compensation = ENABLE;
|
||||
can_fd_tdc_parameter.tdc_filter = 0x04;
|
||||
can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET;
|
||||
can_fd_tdc_parameter.tdc_offset = 0x04;
|
||||
can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter;
|
||||
can_fd_parameter.iso_bosch = CAN_FDMOD_ISO;
|
||||
can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE;
|
||||
/* FD mode data baudrate 2Mbps, sample piont at 80% */
|
||||
can_fd_parameter.data_resync_jump_width = CAN_BT_SJW_1TQ;
|
||||
can_fd_parameter.data_time_segment_1 = CAN_BT_BS1_3TQ;
|
||||
can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ;
|
||||
/* CAN-FD data segement prescaler should be the same as non-data segement
|
||||
* prescaler */
|
||||
can_fd_parameter.data_prescaler = 12;
|
||||
can_fd_init(CAN0, &can_fd_parameter);
|
||||
can_parameter.prescaler = 6;
|
||||
if (can_init(CANX, &can_parameter) != SUCCESS) {
|
||||
while (1)
|
||||
printf("can init error \r\n");
|
||||
}
|
||||
|
||||
/* initialize filter */
|
||||
can1_filter_start_bank(14);
|
||||
can_filter_mask_mode_init(DEV_CAN_LOOPBACK_ID, DEV_CAN0_MASK, CAN_EXTENDED_FIFO0, 0);
|
||||
/* configure filter mode */
|
||||
can_filter.filter_mode = CAN_FILTERMODE_MASK;
|
||||
can_filter.filter_bits = CAN_FILTERBITS_32BIT;
|
||||
/* configure filter ID */
|
||||
can_filter.filter_list_high = (uint16_t)(DEV_CAN_LOOPBACK_ID >> 13U);
|
||||
can_filter.filter_list_low =
|
||||
((uint16_t)(DEV_CAN_LOOPBACK_ID)) << 3U | (1U << 2);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CAN0 loopback test
|
||||
\brief CAN0 FD回环测试
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ErrStatus
|
||||
*/
|
||||
void can_loopback_test(void) {
|
||||
void canfd_loopback_test(void) {
|
||||
can_trasnmit_message_struct transmit_message;
|
||||
can_receive_message_struct receive_message;
|
||||
uint32_t timeout = 0xFFFF;
|
||||
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);
|
||||
transmit_message.tx_sfid = DEV_CAN_LOOPBACK_ID;
|
||||
transmit_message.tx_efid = 0x00;
|
||||
transmit_message.tx_ft = CAN_FT_DATA;
|
||||
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_brs = 1;
|
||||
transmit_message.fd_esi = 0;
|
||||
|
||||
int i = 0;
|
||||
while (i++<transmit_message.tx_dlen) {
|
||||
transmit_message.tx_data[i] = i;
|
||||
while (i++ < transmit_message.tx_dlen) {
|
||||
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)) {
|
||||
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)) {
|
||||
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) ) {
|
||||
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");
|
||||
} else {
|
||||
@@ -254,38 +276,84 @@ void can_loopback_test(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\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");
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CAN_transmiter构造函数
|
||||
\note 初始化CAN通信相关参数和硬件配置
|
||||
*/
|
||||
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_gpio_init();
|
||||
can_config();
|
||||
|
||||
printf("CAN_transmiter initialized successfully\r\n");
|
||||
|
||||
transmit_mailbox = CAN_NOMAILBOX; // 初始化为无mailbox状态
|
||||
timeout = 0xFFFF; // 默认超时时间 0xFFFF
|
||||
// can_config();
|
||||
canfd_config();
|
||||
|
||||
// 初始化发送消息结构体
|
||||
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
|
||||
/* initialize receive message */
|
||||
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -293,25 +361,26 @@ CAN_transmiter::CAN_transmiter() {
|
||||
*/
|
||||
void CAN_transmiter::update(void) {
|
||||
limit_velocity_union.f = 0;
|
||||
limit_voltage = 0;
|
||||
mcu_temp = get_mcu_temp();
|
||||
motor_temp = get_drv_temp();
|
||||
Power_Voltage = get_vbus_voltage();
|
||||
limit_voltage = 0 * 1000;
|
||||
mcu_temp = get_mcu_temp() * 100;
|
||||
motor_temp = get_drv_temp() * 100;
|
||||
Power_Voltage = get_vbus_voltage() * 1000;
|
||||
rt_angle_union.f = 0;
|
||||
rt_velocity_union.f = 0;
|
||||
Status_code = (gpio_input_bit_get(GPIOB, GPIO_PIN_2) == SET) ? 1 : 0;
|
||||
target_angle_union.f = 0;
|
||||
Target_Control_Mode = 0;
|
||||
target_velocity_union.f = 0;
|
||||
u_current_union.f = get_current('U');
|
||||
w_current_union.f = get_current('W');
|
||||
v_current_union.f = get_current('V');
|
||||
u_current_union.f = get_current('U') * 1000;
|
||||
w_current_union.f = get_current('W') * 1000;
|
||||
v_current_union.f = get_current('V') * 1000;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CAN 数据发送
|
||||
*/
|
||||
u8 CAN_transmiter::CAN_Send(u32 id, u8 length, u8 *data) {
|
||||
timeout = 0xFFFF;
|
||||
// 检查数据长度是否符合CAN规范
|
||||
if (length > 8) {
|
||||
printf("CAN data length exceeds maximum of 8 bytes\r\n");
|
||||
@@ -326,7 +395,7 @@ u8 CAN_transmiter::CAN_Send(u32 id, u8 length, u8 *data) {
|
||||
|
||||
/* 配置发送消息参数 */
|
||||
transmit_message.tx_ft = CAN_FT_DATA; // 数据帧
|
||||
transmit_message.tx_ff = CAN_FF_EXTENDED; // 扩展帧格式
|
||||
transmit_message.tx_ff = CAN_FF_STANDARD; // 标准帧格式
|
||||
transmit_message.tx_sfid = id; // 设置帧ID
|
||||
transmit_message.tx_dlen = length; // 设置数据长度
|
||||
|
||||
@@ -334,7 +403,6 @@ u8 CAN_transmiter::CAN_Send(u32 id, u8 length, u8 *data) {
|
||||
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);
|
||||
|
||||
@@ -359,11 +427,11 @@ u8 CAN_transmiter::CAN_Send(u32 id, u8 length, u8 *data) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief CANFD 数据发送
|
||||
*/
|
||||
u8 CAN_transmiter::CANFD_Send(u32 id, u8 length, u8 *data) {
|
||||
timeout = 0xFFFF;
|
||||
// 检查CANFD模式是否启用
|
||||
if (!(CAN_CTL(CAN0) & CAN_CTL_DFZ)) {
|
||||
printf("CANFD mode not enabled\r\n");
|
||||
@@ -385,7 +453,8 @@ u8 CAN_transmiter::CANFD_Send(u32 id, u8 length, u8 *data) {
|
||||
/* 配置发送消息参数 */
|
||||
transmit_message.tx_ft = CAN_FT_DATA; // 数据帧
|
||||
transmit_message.tx_ff = CAN_FF_EXTENDED; // 扩展帧格式
|
||||
transmit_message.tx_sfid = id; // 设置帧ID
|
||||
// transmit_message.tx_sfid = id; // 设置帧ID
|
||||
transmit_message.tx_efid = id; // 扩展帧ID
|
||||
transmit_message.tx_dlen = length; // 设置数据长度
|
||||
|
||||
// 设置CANFD特定参数
|
||||
@@ -397,7 +466,6 @@ u8 CAN_transmiter::CANFD_Send(u32 id, u8 length, u8 *data) {
|
||||
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);
|
||||
|
||||
@@ -416,19 +484,19 @@ u8 CAN_transmiter::CANFD_Send(u32 id, u8 length, u8 *data) {
|
||||
|
||||
// 超时检查
|
||||
if (0 == timeout) {
|
||||
printf("CANFD transmission timeout for mailbox %d\r\n", transmit_mailbox);
|
||||
printf("CANFD transmission timeout for mailbox %d\r\n",
|
||||
transmit_mailbox);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief CAN发送函数
|
||||
* @retval 0: 发送失败
|
||||
* 1: 发送成功
|
||||
*/
|
||||
u8 CAN_transmiter::CAN_all_Send(){
|
||||
u8 CAN_transmiter::CAN_all_Send() {
|
||||
u32 success_flag = 0;
|
||||
|
||||
constexpr u32 RT_Vel_Ang_FEED = 0x101;
|
||||
@@ -437,25 +505,32 @@ u8 CAN_transmiter::CAN_all_Send(){
|
||||
constexpr u32 Status_FEED = 0x118;
|
||||
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, 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, 4, target_velocity_union);
|
||||
//打包Current_FEED
|
||||
pack_float_to_bytes(transmit_data, 0, u_current_union);
|
||||
pack_float_to_bytes(transmit_data, 4, w_current_union);
|
||||
pack_float_to_bytes(transmit_data, 8, v_current_union);
|
||||
//打包Status_FEED
|
||||
success_flag += CAN_Send(SET_Vel_Ang_FEED, 8, transmit_data);
|
||||
// 打包Current_FEED
|
||||
pack_u16_to_bytes(transmit_data, 0, u16(u_current_union.f));
|
||||
pack_u16_to_bytes(transmit_data, 2, u16(w_current_union.f));
|
||||
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[1] = controller_Mode;
|
||||
pack_short_to_bytes(transmit_data, 2, motor_temp);
|
||||
pack_short_to_bytes(transmit_data, 4, mcu_temp);
|
||||
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_short_to_bytes(transmit_data, 4, limit_voltage);
|
||||
success_flag += CAN_Send(Limit_Vel_Vol_FEED, 6, transmit_data);
|
||||
|
||||
return success_flag;
|
||||
}
|
||||
|
||||
@@ -464,24 +539,22 @@ u8 CAN_transmiter::CAN_all_Send(){
|
||||
* @retval 0: 发送失败
|
||||
* 1: 发送成功
|
||||
*/
|
||||
u8 CAN_transmiter::CANFD_all_Send(){
|
||||
u8 CAN_transmiter::CANFD_all_Send() {
|
||||
u32 success_flag = 0;
|
||||
|
||||
constexpr u32 STATUS_ID = 0x18FF100;
|
||||
constexpr u32 CONFIG_ID = 0x18FF101;
|
||||
|
||||
constexpr u32 STATUS_ID = 0x18FF0100;
|
||||
constexpr u32 CONFIG_ID = 0x18FF0101;
|
||||
// 打包status数据
|
||||
pack_short_to_bytes(transmit_data, 0, mcu_temp);
|
||||
pack_short_to_bytes(transmit_data, 2, motor_temp);
|
||||
pack_float_to_bytes(transmit_data, 4, u_current_union);
|
||||
pack_float_to_bytes(transmit_data, 8, w_current_union);
|
||||
pack_float_to_bytes(transmit_data, 12, v_current_union);
|
||||
transmit_data[16] = Status_code;
|
||||
pack_u16_to_bytes(transmit_data, 17, Power_Voltage);
|
||||
pack_float_to_bytes(transmit_data, 19, rt_angle_union);
|
||||
pack_float_to_bytes(transmit_data, 23, rt_velocity_union);
|
||||
|
||||
success_flag += CANFD_Send(STATUS_ID, 27, transmit_data);
|
||||
pack_u16_to_bytes(transmit_data, 4, u16(u_current_union.f));
|
||||
pack_u16_to_bytes(transmit_data, 6, u16(w_current_union.f));
|
||||
pack_u16_to_bytes(transmit_data, 8, u16(v_current_union.f));
|
||||
transmit_data[10] = Status_code;
|
||||
pack_u16_to_bytes(transmit_data, 11, Power_Voltage);
|
||||
pack_float_to_bytes(transmit_data, 13, rt_angle_union);
|
||||
pack_float_to_bytes(transmit_data, 17, rt_velocity_union);
|
||||
success_flag += CANFD_Send(STATUS_ID, 20, transmit_data);
|
||||
|
||||
// 打包config数据
|
||||
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, 7, target_angle_union);
|
||||
pack_float_to_bytes(transmit_data, 11, target_velocity_union);
|
||||
|
||||
success_flag += CANFD_Send(CONFIG_ID, 15, transmit_data);
|
||||
success_flag += CANFD_Send(CONFIG_ID, 16, transmit_data);
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
+40
-35
@@ -18,28 +18,31 @@ typedef union {
|
||||
} float_union_t;
|
||||
|
||||
// 添加辅助函数用于将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 + 1] = (u8)((value >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
// 添加辅助函数用于将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 + 1] = (u8)((value >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
// 添加辅助函数用于将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,
|
||||
float_union_t &float_union) {
|
||||
buffer[offset] = float_union.b[0];
|
||||
buffer[offset + 1] = float_union.b[1];
|
||||
buffer[offset + 2] = float_union.b[2];
|
||||
buffer[offset + 3] = float_union.b[3];
|
||||
}
|
||||
|
||||
u8 can_gpio_init(void);
|
||||
void can_config(void);
|
||||
void canfd_config(void);
|
||||
u8 can_gpio_init(void); // CAN引脚初始化
|
||||
void can_config(void); // CAN初始化
|
||||
void canfd_config(void);// CANFD初始化
|
||||
void CAN0_RX0_IRQHandler(void);// CAN接收中断处理函数
|
||||
|
||||
void can_loopback_init(void);
|
||||
void can_loopback_test(void);
|
||||
|
||||
@@ -50,42 +53,44 @@ void can_loopback_test(void);
|
||||
class CAN_transmiter {
|
||||
|
||||
private:
|
||||
u8 controller_Mode;
|
||||
float_union_t limit_velocity_union;
|
||||
u16 limit_voltage;
|
||||
short mcu_temp;
|
||||
short motor_temp;
|
||||
u16 Power_Voltage;
|
||||
float_union_t rt_angle_union;
|
||||
float_union_t rt_velocity_union;
|
||||
u8 Status_code;
|
||||
float_union_t target_angle_union;
|
||||
u8 Target_Control_Mode;
|
||||
float_union_t target_velocity_union;
|
||||
float_union_t u_current_union;
|
||||
float_union_t w_current_union;
|
||||
float_union_t v_current_union;
|
||||
u8 controller_Mode = 0; // 电机模式
|
||||
float_union_t limit_velocity_union = {0}; // 限制速度
|
||||
u16 limit_voltage = 0; // 限制电压
|
||||
short mcu_temp = 0; // MCU温度
|
||||
short motor_temp = 0; // 电机温度
|
||||
u16 Power_Voltage = 0; // 电源电压
|
||||
float_union_t rt_angle_union = {0}; // 实时角度
|
||||
float_union_t rt_velocity_union = {0}; // 实时速度
|
||||
u8 Status_code = 0; // 状态码
|
||||
float_union_t target_angle_union = {0}; // 目标角度
|
||||
u8 Target_Control_Mode = 0; // 目标控制模式
|
||||
float_union_t target_velocity_union = {0}; // 目标速度
|
||||
float_union_t u_current_union = {0}; // U相电流
|
||||
float_union_t w_current_union = {0}; // W相电流
|
||||
float_union_t v_current_union = {0}; // V相电流
|
||||
|
||||
u8 transmit_mailbox; // 初始化为无mailbox状态
|
||||
u32 timeout; // 默认超时为0xFFFF
|
||||
can_trasnmit_message_struct transmit_message; // 发送消息结构体
|
||||
u8 transmit_mailbox = CAN_NOMAILBOX; // 初始化为无mailbox状态
|
||||
u32 timeout = 0XFFFF; // 默认超时为0xFFFF
|
||||
u8 transmit_data[64]; // CANFD最大64字节
|
||||
|
||||
can_trasnmit_message_struct transmit_message;
|
||||
can_receive_message_struct receive_message;
|
||||
|
||||
can_fdframe_struct can_fd_parameter;
|
||||
can_fd_tdc_struct can_fd_tdc_parameter;
|
||||
void update(); // 更新数据
|
||||
u8 CAN_Receive(); // CAN接收
|
||||
u8 CANFD_Receive(); // CANFD接收
|
||||
u8 CAN_Send(u32 ID, u8 length, u8 *data); // CAN发送
|
||||
u8 CANFD_Send(u32 ID, u8 length, u8 *data); // CANFD发送
|
||||
u8 CAN_all_Send(); // CAN发送
|
||||
u8 CANFD_all_Send(); // CANFD发送
|
||||
|
||||
public:
|
||||
// 添加构造函数声明
|
||||
CAN_transmiter();
|
||||
u8 CAN_Send(u32 ID, u8 length, u8 *data);
|
||||
u8 CANFD_Send(u32 ID, u8 length, u8 *data);
|
||||
void update();
|
||||
u8 CAN_all_Send();
|
||||
u8 CANFD_all_Send();
|
||||
u8 CAN_Receive();
|
||||
u8 CANFD_Receive();
|
||||
|
||||
can_receive_message_struct receive_message; // 接收消息结构体
|
||||
FlagStatus can0_receive_flag; // CAN0接收标志
|
||||
FlagStatus can0_send_flag; // CAN0发送标志
|
||||
|
||||
void communication_check(); // 通信检查
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+28
-27
@@ -1,22 +1,31 @@
|
||||
#include "Timer.h"
|
||||
#include "Can.h"
|
||||
#include "adc.h"
|
||||
#include "gd32c10x.h"
|
||||
#include "gd32c10x_gpio.h"
|
||||
#include "gd32c10x_timer.h"
|
||||
#include "initial.h"
|
||||
#include <cstdio>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
constexpr int TIMER1_PRESCALER = 1199;
|
||||
constexpr int TIMER1_PERIOD = 9;
|
||||
// 配置定时器每100微秒中断一次
|
||||
// 系统时钟为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_PERIOD = 15999;
|
||||
constexpr int TIMER0_CH0_PULSE = 4000;
|
||||
constexpr int TIMER0_CH1_PULSE = 6000;
|
||||
constexpr int TIMER0_CH2_PULSE = 8000;
|
||||
|
||||
static u32 total_us100_counter = 0; // 总计数器,每100微秒增加1
|
||||
extern u16 adc_value[7];
|
||||
extern CAN_transmiter CAN0_transmiter;
|
||||
|
||||
/**
|
||||
* @brief 设置引脚中断优先级
|
||||
@@ -40,8 +49,8 @@ void nvic_config(void) {
|
||||
void timer1_config(void) {
|
||||
/* ----------------------------------------------------------------------------
|
||||
TIMER1 Configuration:
|
||||
TIMER1CLK = SystemCoreClock/12000 = 10KHz, the period is 1s(10000/10000 =
|
||||
1s).
|
||||
TIMER1CLK = SystemCoreClock/120 = 1MHz, the period is 100us(100/1000000 =
|
||||
100us).
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
timer_parameter_struct timer_struct;
|
||||
@@ -55,11 +64,11 @@ void timer1_config(void) {
|
||||
timer_struct_para_init(&timer_struct);
|
||||
/* TIMER1配置参数设置 */
|
||||
timer_struct.prescaler =
|
||||
TIMER1_PRESCALER; /* 预分频值:12000分频(从0开始计数) */
|
||||
TIMER1_PRESCALER; /* 预分频值:120分频(从0开始计数) */
|
||||
timer_struct.alignedmode = TIMER_COUNTER_EDGE; /* 边沿对齐模式 */
|
||||
timer_struct.counterdirection = TIMER_COUNTER_UP; /* 向上计数模式 */
|
||||
timer_struct.period =
|
||||
TIMER1_PERIOD; /* 自动重装载值:10000次计数(从0开始计数) */
|
||||
TIMER1_PERIOD; /* 自动重装载值:100次计数(从0开始计数) */
|
||||
timer_struct.clockdivision = TIMER_CKDIV_DIV1; /* 时钟分频值:1分频 */
|
||||
timer_init(TIMER1, &timer_struct);
|
||||
|
||||
@@ -92,35 +101,27 @@ void TIMER1_IRQHandler(void) {
|
||||
if (timer_interrupt_flag_get(TIMER1, TIMER_INT_UP) != RESET) {
|
||||
// 清除更新中断标志
|
||||
timer_interrupt_flag_clear(TIMER1, TIMER_INT_UP);
|
||||
// 增加总计数器
|
||||
total_us100_counter++;
|
||||
|
||||
// 使用静态变量来跟踪定时器事件
|
||||
static u8 ms_counter = 0;
|
||||
static u8 tens_counter = 0;
|
||||
static u8 hundreds_counter = 0;
|
||||
static u16 seconds_counter = 0;
|
||||
// 每100us执行一次的操作可以放在这里
|
||||
|
||||
// 增加计数器
|
||||
ms_counter++;
|
||||
if (ms_counter >= 10) {
|
||||
ms_counter = 0;
|
||||
tens_counter++;
|
||||
if (total_us100_counter % 10 == 0) {
|
||||
// 每1ms执行的代码可以放在这里
|
||||
if (tens_counter >= 10) {
|
||||
tens_counter = 0;
|
||||
hundreds_counter++;
|
||||
|
||||
CAN0_transmiter.can0_send_flag = SET;
|
||||
if (total_us100_counter % 100 == 0) {
|
||||
// 每10ms执行的代码可以放在这里
|
||||
}
|
||||
|
||||
if (hundreds_counter >= 10) {
|
||||
hundreds_counter = 0;
|
||||
seconds_counter++;
|
||||
if (total_us100_counter % 1000 == 0) {
|
||||
// 每100ms执行的代码可以放在这里
|
||||
}
|
||||
|
||||
if (seconds_counter >= 10) {
|
||||
seconds_counter = 0;
|
||||
if (total_us100_counter % 10000 == 0) {
|
||||
// 每1s执行的代码可以放在这里
|
||||
}
|
||||
}
|
||||
|
||||
// 重置计数器避免溢出
|
||||
total_us100_counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
+112
-87
@@ -1,6 +1,9 @@
|
||||
#include "tle5012b.h"
|
||||
#include "core_cmInstr.h"
|
||||
#include "gd32c10x_gpio.h"
|
||||
#include "gd32c10x_spi.h"
|
||||
#include "stdbool.h"
|
||||
#include "systick.h"
|
||||
|
||||
#define SPI_TX_OFF() \
|
||||
do { \
|
||||
@@ -69,8 +72,6 @@ uint16_t spi_rw_half_word(uint32_t spi_periph, const uint16_t i_HalfWord)
|
||||
|
||||
/* ---------- Send data ---------- */
|
||||
to = 200;
|
||||
|
||||
|
||||
while ((RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)) && --to);
|
||||
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 */
|
||||
}
|
||||
|
||||
/* ---------- wait bus idle ---------- */
|
||||
/* ---------- wait bsu idle ---------- */
|
||||
if (ok)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write data to TLI5012B register
|
||||
* @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 */
|
||||
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_Data);
|
||||
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_TX_ON(); /* Restore MOSI as output */
|
||||
__NOP(); __NOP(); __NOP(); // 添加小延时确保CS稳定
|
||||
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 */
|
||||
SPI_CS_ENABLE();
|
||||
SPI_TX_ON();
|
||||
__NOP(); __NOP(); __NOP(); // 添加小延时确保CS稳定
|
||||
*i_Data = spi_rw_half_word(SPI0, i_Cmd);
|
||||
SPI_TX_OFF(); /* Configure MOSI as input to avoid conflicts */
|
||||
// *i_Data = spi_rw_half_word(SPI0, DUMMY_BYTE);
|
||||
result = spi_rw_half_word(SPI0, result);
|
||||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||||
__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_TX_ON(); /* Restore MOSI as output */
|
||||
__NOP(); __NOP(); __NOP(); // 添加小延时确保CS稳定
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -146,16 +156,17 @@ void tle5012b_gpio_init(void)
|
||||
rcu_periph_clock_enable(RCU_GPIOB);
|
||||
rcu_periph_clock_enable(RCU_SPI0);
|
||||
rcu_periph_clock_enable(RCU_AF);
|
||||
|
||||
/* JTAG-DP disabled and SW-DP enabled, so SPI0 can use PB3 and PB4 */
|
||||
/* 关闭 JTAG,仅保留 SWD(释放 PA15、PB3、PB4) */
|
||||
gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
|
||||
|
||||
/* -------- SPI0 全 remap:PB3/4/5 + PA15 -------- */
|
||||
gpio_pin_remap_config(GPIO_SPI0_REMAP, ENABLE);
|
||||
/* SPI0 GPIO config: NSS/PA15, SCK/PB3, MOSI/PB5 */
|
||||
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
|
||||
/* PA15 → NSS, 推挽输出 */
|
||||
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);
|
||||
/* SPI0 GPIO config: MISO/PB4 */
|
||||
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
|
||||
/* PB4 → MISO, 浮空输入 */
|
||||
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_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.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
|
||||
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.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_nss_output_enable(SPI0);
|
||||
spi_nssp_mode_enable(SPI0);
|
||||
@@ -185,7 +196,6 @@ void tle5012b_spi_init(void)
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize TLI5012B magnetic angle sensor
|
||||
* @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 */
|
||||
u16Command = READ_STAT_VALUE;
|
||||
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 */
|
||||
u16Command = 0x0001;
|
||||
u16Data &= 0x9FFF; /* Clear bits 13-14 (Slave_Number) */
|
||||
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 */
|
||||
u16Command = READ_STAT_VALUE;
|
||||
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 ---------- */
|
||||
u16Command = READ_ACSTAT_VALUE;
|
||||
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 ---------- */
|
||||
/* Read current MOD1 register value */
|
||||
u16Command = RD_REG | WRITE_MOD1_VALUE;
|
||||
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 */
|
||||
// u16Command = WRITE_MOD1_VALUE;
|
||||
// u16Data = MOD1_VALUE;
|
||||
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
|
||||
// printf("\r\n [TLI5012Init] [MOD1] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* Write MOD1 register with configuration value */
|
||||
u16Command = WRITE_MOD1_VALUE;
|
||||
u16Data = MOD1_VALUE;
|
||||
u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
|
||||
printf("\r\n @Joe [TLI5012Init] [MOD1] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// /* Verify MOD1 register write operation */
|
||||
// u16Command = RD_REG | WRITE_MOD1_VALUE;
|
||||
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
// printf("\r\n [TLI5012Init] read MOD1: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* Verify MOD1 register write operation */
|
||||
u16Command = RD_REG | WRITE_MOD1_VALUE;
|
||||
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
printf("\r\n @Joe [TLI5012Init] read MOD1: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// /* ---------- Step 4: Configure MOD2 register ---------- */
|
||||
// /* Read current MOD2 register value */
|
||||
// u16Command = RD_REG | WRITE_MOD2_VALUE;
|
||||
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
// printf("\r\n [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* ---------- Step 4: Configure MOD2 register ---------- */
|
||||
/* Read current MOD2 register value */
|
||||
u16Command = RD_REG | WRITE_MOD2_VALUE;
|
||||
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
printf("\r\n @Joe [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// /* Write MOD2 register with configuration value */
|
||||
// u16Command = WRITE_MOD2_VALUE;
|
||||
// u16Data = MOD2_VALUE;
|
||||
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
|
||||
// printf("\r\n [TLI5012Init] [MOD2] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* Write MOD2 register with configuration value */
|
||||
u16Command = WRITE_MOD2_VALUE;
|
||||
u16Data = MOD2_VALUE;
|
||||
u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
|
||||
printf("\r\n @Joe [TLI5012Init] [MOD2] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// /* Verify MOD2 register write operation */
|
||||
// u16Command = RD_REG | WRITE_MOD2_VALUE;
|
||||
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
// printf("\r\n [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* Verify MOD2 register write operation */
|
||||
u16Command = RD_REG | WRITE_MOD2_VALUE;
|
||||
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
printf("\r\n @Joe [TLI5012Init] read MOD2: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// /* ---------- Step 5: Configure MOD3 register ---------- */
|
||||
// /* Read current MOD3 register value */
|
||||
// u16Command = RD_REG | WRITE_MOD3_VALUE;
|
||||
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
// printf("\r\n [TLI5012Init] read MOD3: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* ---------- Step 5: Configure MOD3 register ---------- */
|
||||
/* Read current MOD3 register value */
|
||||
u16Command = RD_REG | WRITE_MOD3_VALUE;
|
||||
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
printf("\r\n @Joe [TLI5012Init] read MOD3: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// /* Write MOD3 register with configuration value */
|
||||
// u16Command = WRITE_MOD3_VALUE;
|
||||
// u16Data = MOD3_VALUE;
|
||||
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
|
||||
// printf("\r\n [TLI5012Init] [MOD3] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* Write MOD3 register with configuration value */
|
||||
u16Command = WRITE_MOD3_VALUE;
|
||||
u16Data = MOD3_VALUE;
|
||||
u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
|
||||
printf("\r\n @Joe [TLI5012Init] [MOD3] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// /* Verify MOD3 register write operation */
|
||||
// u16Command = RD_REG | WRITE_MOD3_VALUE;
|
||||
// u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
// printf("\r\n [TLI5012Init] read MOD3: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
/* Verify MOD3 register write operation */
|
||||
u16Command = RD_REG | WRITE_MOD3_VALUE;
|
||||
u16Safe = cdd_TLI5012_ReadReg(u16Command, &u16Data);
|
||||
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;
|
||||
// u16Data |= 0x0004; // Set SSC_OD bit
|
||||
// u16Safe = cdd_TLI5012_WriteReg(u16Command, u16Data);
|
||||
// printf("\r\n [TLI5012Init] [MOD3] write u16Data: 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 @Joe [TLI5012Init] [MOD4] write u16Data: 0x%04X, SafeWord: 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
|
||||
// /* ---------- 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 [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);
|
||||
/* Verify MOD4 register write operation */
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Test_TLI5012B(void)
|
||||
{
|
||||
uint16_t u16Command = READ_ANGLE_VALUE;
|
||||
uint16_t u16Command = 0xFFFF;
|
||||
uint16_t u16Data = 0x0000;
|
||||
uint16_t u16Safe = 0x0000;
|
||||
float angle = 0;
|
||||
u16Command = READ_ANGLE_VALUE;
|
||||
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;
|
||||
printf ( "\r\n 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;
|
||||
printf ( "\r\n angle = %f, AVAL = %d \r\n", angle, (((int16_t)(u16Data << 1)) >> 1));
|
||||
printf ( "\r\n @Joe AVAL = 0x%04X, SafeWord = 0x%04X \r\n", u16Data, u16Safe);
|
||||
|
||||
// 将15位角度值转换为角度(0-360度)
|
||||
// 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);
|
||||
}
|
||||
+5
-24
@@ -3,11 +3,11 @@
|
||||
#include "Filter.h"
|
||||
#include "Timer.h"
|
||||
#include "adc.h"
|
||||
#include "core_cm4.h"
|
||||
#include "device/tle5012b.h"
|
||||
#include "initial.h"
|
||||
#include "sys/initial.h"
|
||||
#include "systick.h"
|
||||
#include "core_cm4.h"
|
||||
#include "tle5012b.h"
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
@@ -15,9 +15,7 @@
|
||||
|
||||
// 全局变量定义
|
||||
CurrentKalman kalman(0.0f, 0.0026f, 4.8f, 0.0001f, 1e-6f, 0.02f);
|
||||
CircularBuffer buffer;
|
||||
CAN_transmiter CAN0_transmiter;
|
||||
|
||||
int main(void) {
|
||||
systick_config(); // 系统时钟初始化
|
||||
USART0_init(); // 调试串口初始化
|
||||
@@ -27,32 +25,15 @@ int main(void) {
|
||||
|
||||
tle5012b_gpio_init(); // TLI5012B初始化
|
||||
tle5012b_spi_init();
|
||||
cdd_TLI5012_Init(); // 初始化TLE5012B传感器
|
||||
// cdd_TLI5012_Init(); // 初始化TLE5012B传感器
|
||||
|
||||
watchdog_init(1000);
|
||||
// 初始化CAN回环测试
|
||||
// can_loopback_init();
|
||||
watchdog_init(5000);
|
||||
while (1) {
|
||||
/* clear the FWDGT reset flag */
|
||||
fwdgt_counter_reload();
|
||||
|
||||
// can_loopback_test();
|
||||
/* 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");
|
||||
|
||||
delay_1ms(700);
|
||||
// TLI5012B测试
|
||||
Test_TLI5012B();
|
||||
CAN0_transmiter.communication_check();
|
||||
// delay_1ms(2);
|
||||
|
||||
Set_Pwm(0, 1500);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,19 @@ void systick_config(void)
|
||||
/* configure the systick handler priority */
|
||||
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
|
||||
\param[in] count: count in milliseconds
|
||||
@@ -66,8 +78,8 @@ void systick_config(void)
|
||||
void delay_1ms(uint32_t count)
|
||||
{
|
||||
delay = count;
|
||||
|
||||
while(0U != delay){
|
||||
fwdgt_counter_reload();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ extern "C" {
|
||||
void systick_config(void);
|
||||
/* delay a time in milliseconds */
|
||||
void delay_1ms(uint32_t count);
|
||||
/* delay a time in seconds */
|
||||
void delay_1s(uint32_t count);
|
||||
/* delay decrement */
|
||||
void delay_decrement(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user