fix(CAN): 使用DMA优化CAN通信数据收发
重新配置CAN引脚映射并实现基于DMA的数据收发机制,提升通信效率。增加了DMA通道4和5的中断处理函数,用于接收和发送CAN消息。修改了CAN发送函数以支持DMA传输,并去除了原有的轮询等待机制。 feat(ADC): 重新实现ADC与DMA初始化配置 将ADC和DMA的配置迁移至ADC.cpp文件中,完善了DMA循环采样模式配置及ADC多通道扫描功能。删除了initial.cpp中重复的初始化代码,并修正了相关头文件包含。 chore(headers): 清理冗余头文件引用 多个源文件中删除了不必要的标准库和硬件无关头文件引用,减少编译依赖,提高代码清晰度。
This commit is contained in:
@@ -157,6 +157,9 @@ void FOC_Controlroller::shut_down() {
|
||||
}
|
||||
|
||||
void FOC_Controlroller::resume() {
|
||||
over_current = 0;
|
||||
temp_error = 0;
|
||||
voltage_error = 0;
|
||||
is_shut_down = 0;
|
||||
gpio_bit_set(GPIOB, GPIO_PIN_12);
|
||||
}
|
||||
@@ -216,3 +219,4 @@ void FOC_Controlroller::DFOC_M0_setTorque(float Target) // 电流力矩环
|
||||
{
|
||||
// setTorque(current_loop_M0(Target-DFOC_M0_Current()),_electricalAngle());
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ class FOC_Controlroller {
|
||||
float limit_velocity = 0.0f;
|
||||
float target_angle = 0.0f;
|
||||
float target_velocity = 0.0f;
|
||||
float rt_angle = 0.0f;
|
||||
float rt_velocity = 0.0f;
|
||||
u8 over_current = 0;
|
||||
u8 temp_error = 0;
|
||||
u8 voltage_error = 0;
|
||||
u8 is_shut_down = 0;
|
||||
|
||||
float velocity_open_loop(float target_velocity);
|
||||
@@ -18,7 +23,7 @@ class FOC_Controlroller {
|
||||
void shut_down(void);
|
||||
void resume(void);
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::u64 last_time_us = 0;
|
||||
std::u64 now_us = 0;
|
||||
float shaft_angle = 0;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "Filter.h"
|
||||
#include "stdbool.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
+87
-1
@@ -1,10 +1,12 @@
|
||||
#include "adc.h"
|
||||
#include "Filter.h"
|
||||
#include "math.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "gd32c10x_eval.h"
|
||||
#include <gd32c10x_dma.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
constexpr float ERROR_ADC_VAL = 255.0f;
|
||||
constexpr float ADC_SCALE = 3.3f / 4096.0f;
|
||||
constexpr float TEMP_FACTOR = 1000.0f / 4.3f;
|
||||
@@ -21,11 +23,95 @@ constexpr float MAX_VCC = 65.0f;
|
||||
constexpr float MIN_VCC = -0.1f;
|
||||
|
||||
u16 adc_value[6] = {0}; // 显式初始化数组元素为0
|
||||
/*!
|
||||
\brief configure the DMA peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_config(void) {
|
||||
/* enable DMA0 clock */
|
||||
rcu_periph_clock_enable(RCU_DMA0);
|
||||
/* ADC_DMA_channel configuration */
|
||||
dma_parameter_struct dma_data_parameter;
|
||||
|
||||
/* ADC DMA_channel configuration */
|
||||
dma_deinit(DMA0, DMA_CH0);
|
||||
|
||||
/* initialize DMA single data mode */
|
||||
dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
|
||||
dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||||
dma_data_parameter.memory_addr = (uint32_t)(adc_value);
|
||||
dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
||||
dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
|
||||
dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
|
||||
dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;
|
||||
dma_data_parameter.number = 6;
|
||||
dma_data_parameter.priority = DMA_PRIORITY_HIGH;
|
||||
dma_init(DMA0, DMA_CH0, &dma_data_parameter);
|
||||
|
||||
dma_circulation_enable(DMA0, DMA_CH0);
|
||||
|
||||
/* enable DMA channel */
|
||||
dma_channel_enable(DMA0, DMA_CH0);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the ADC peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_config(void) {
|
||||
/* enable ADC clock */
|
||||
rcu_periph_clock_enable(RCU_ADC0);
|
||||
/* config ADC clock */
|
||||
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
|
||||
|
||||
/* 复位ADC */
|
||||
adc_deinit(ADC0);
|
||||
/* ADC模式配置 */
|
||||
adc_mode_config(ADC_MODE_FREE);
|
||||
/* 使能ADC连续转换功能 */
|
||||
adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
|
||||
/* 使能ADC扫描模式 */
|
||||
adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
|
||||
/* ADC数据右对齐配置 */
|
||||
adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
|
||||
/* 使能ADC温度传感器和内部参考电压 */
|
||||
adc_tempsensor_vrefint_enable();
|
||||
|
||||
/* 配置ADC通道长度 */
|
||||
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 6);
|
||||
/* 配置ADC规则通道 */
|
||||
adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_16,
|
||||
ADC_SAMPLETIME_239POINT5);
|
||||
adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 4, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 5, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);
|
||||
|
||||
/* ADC触发配置 */
|
||||
adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL,
|
||||
ADC0_1_EXTTRIG_REGULAR_NONE);
|
||||
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
|
||||
|
||||
/* 使能ADC接口 */
|
||||
adc_enable(ADC0);
|
||||
/* ADC校准 */
|
||||
adc_calibration_enable(ADC0);
|
||||
/* 使能ADC DMA功能 */
|
||||
adc_dma_mode_enable(ADC0);
|
||||
/* 使能ADC软件触发 */
|
||||
adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
|
||||
}
|
||||
/**
|
||||
* @brief 采样类初始化
|
||||
*/
|
||||
void sampler::init() {
|
||||
dma_config(); // DMA采样ADC初始化
|
||||
adc_config(); // ADC初始化
|
||||
for (int i = 0; i < FILTER_SIZE + 1; i++) {
|
||||
mcu_temp_samples[i] =
|
||||
(1.43f - adc_value[0] * ADC_SCALE) * TEMP_FACTOR + 35.0f;
|
||||
|
||||
+137
-33
@@ -1,11 +1,13 @@
|
||||
#include "Can.h"
|
||||
#include "DengFOC.h"
|
||||
#include "adc.h"
|
||||
#include "ang_sensor.h"
|
||||
#include "gd32c10x.h"
|
||||
#include "gd32c10x_can.h"
|
||||
#include "gd32c10x_dma.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <inttypes.h>
|
||||
#include <random>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -21,6 +23,12 @@ extern CAN_transmiter CAN0_transmiter;
|
||||
extern FOC_Controlroller FOC;
|
||||
extern sampler sampler;
|
||||
|
||||
// 添加DMA相关变量
|
||||
dma_parameter_struct dma_rx_parameter;
|
||||
dma_parameter_struct dma_tx_parameter;
|
||||
uint8_t can_rx_buffer[8]; // CAN接收缓冲区
|
||||
uint8_t can_tx_buffer[8]; // CAN发送缓冲区
|
||||
|
||||
/*!
|
||||
\brief initialize CAN GPIO
|
||||
\param[in] none
|
||||
@@ -30,20 +38,65 @@ extern sampler sampler;
|
||||
u8 can_gpio_init() {
|
||||
/* enable CAN clock */
|
||||
rcu_periph_clock_enable(RCU_CAN0);
|
||||
rcu_periph_clock_enable(RCU_GPIOA);
|
||||
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);
|
||||
gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_8); // rx
|
||||
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); // tx
|
||||
gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP, ENABLE);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 初始化CAN DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_dma_init(void) {
|
||||
// 使能DMA时钟
|
||||
rcu_periph_clock_enable(RCU_DMA0);
|
||||
|
||||
// 配置接收DMA
|
||||
dma_struct_para_init(&dma_rx_parameter);
|
||||
dma_rx_parameter.periph_addr =
|
||||
(uint32_t)(&CAN_RFIFOMDATA0(CAN0, CAN_FIFO0)); // CAN接收数据寄存器地址
|
||||
dma_rx_parameter.memory_addr = (uint32_t)can_rx_buffer; // 接收缓冲区地址
|
||||
dma_rx_parameter.direction = DMA_PERIPHERAL_TO_MEMORY; // 外设到内存
|
||||
dma_rx_parameter.memory_width = DMA_MEMORY_WIDTH_8BIT; // 内存宽度8位
|
||||
dma_rx_parameter.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; // 外设宽度8位
|
||||
dma_rx_parameter.priority = DMA_PRIORITY_HIGH; // 高优先级
|
||||
dma_rx_parameter.number = 8; // 传输字节数
|
||||
dma_rx_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
|
||||
dma_rx_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
|
||||
dma_init(DMA0, DMA_CH4, &dma_rx_parameter); // 使用DMA通道4
|
||||
|
||||
// 配置发送DMA
|
||||
dma_struct_para_init(&dma_tx_parameter);
|
||||
dma_tx_parameter.periph_addr =
|
||||
(uint32_t)(&CAN_TMI0(CAN0)); // CAN发送数据寄存器地址
|
||||
dma_tx_parameter.memory_addr = (uint32_t)can_tx_buffer; // 发送缓冲区地址
|
||||
dma_tx_parameter.direction = DMA_MEMORY_TO_PERIPHERAL; // 内存到外设
|
||||
dma_tx_parameter.memory_width = DMA_MEMORY_WIDTH_8BIT; // 内存宽度8位
|
||||
dma_tx_parameter.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; // 外设宽度8位
|
||||
dma_tx_parameter.priority = DMA_PRIORITY_HIGH; // 高优先级
|
||||
dma_tx_parameter.number = 8; // 传输字节数
|
||||
dma_tx_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
|
||||
dma_tx_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
|
||||
dma_init(DMA0, DMA_CH5, &dma_tx_parameter); // 使用DMA通道5
|
||||
|
||||
// 使能DMA通道
|
||||
dma_channel_enable(DMA0, DMA_CH4);
|
||||
dma_channel_enable(DMA0, DMA_CH5);
|
||||
|
||||
// 使能CAN接收DMA
|
||||
// can_dma_enable(CAN0, CAN_DMA_RECEIVE);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 初始化CAN0 2.0B 模式
|
||||
\param[in] none
|
||||
@@ -52,6 +105,7 @@ u8 can_gpio_init() {
|
||||
*/
|
||||
void can_config(void) {
|
||||
can_gpio_init();
|
||||
can_dma_init(); // 初始化DMA
|
||||
can_parameter_struct can_parameter;
|
||||
can_filter_parameter_struct can_filter;
|
||||
|
||||
@@ -96,6 +150,10 @@ void can_config(void) {
|
||||
nvic_irq_enable(CAN0_RX0_IRQn, 1, 0);
|
||||
/* enable can receive FIFO0 not empty interrupt */
|
||||
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
|
||||
|
||||
// 使能DMA中断
|
||||
nvic_irq_enable(DMA0_Channel4_IRQn, 1, 1);
|
||||
dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -356,6 +414,10 @@ CAN_transmiter::CAN_transmiter() {
|
||||
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &transmit_message);
|
||||
/* initialize receive message */
|
||||
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &receive_message);
|
||||
|
||||
// 初始化DMA缓冲区
|
||||
memset(can_rx_buffer, 0, sizeof(can_rx_buffer));
|
||||
memset(can_tx_buffer, 0, sizeof(can_tx_buffer));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -367,7 +429,7 @@ void CAN_transmiter::update(void) {
|
||||
mcu_temp = sampler.get_mcu_temp() * 100;
|
||||
motor_temp = sampler.get_drv_temp() * 100;
|
||||
Power_Voltage = sampler.get_vbus_voltage() * 1000;
|
||||
rt_angle_union.f = 0.0f;
|
||||
rt_angle_union.f = KHT7823_readAngle();
|
||||
rt_velocity_union.f = 0.0f;
|
||||
Status_code = (gpio_input_bit_get(GPIOB, GPIO_PIN_2) == SET) ? 0 : 1;
|
||||
|
||||
@@ -383,9 +445,11 @@ void CAN_transmiter::update(void) {
|
||||
|
||||
/*!
|
||||
\brief CAN 数据发送
|
||||
\param id CAN ID
|
||||
\param length 数据长度
|
||||
\param data 数据
|
||||
*/
|
||||
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");
|
||||
@@ -408,6 +472,17 @@ 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);
|
||||
}
|
||||
|
||||
// 将数据复制到DMA缓冲区
|
||||
memcpy(can_tx_buffer, data, length);
|
||||
|
||||
// 配置DMA发送参数
|
||||
dma_tx_parameter.number = length;
|
||||
dma_init(DMA0, DMA_CH5, &dma_tx_parameter);
|
||||
|
||||
// 启动DMA传输
|
||||
dma_channel_enable(DMA0, DMA_CH5);
|
||||
|
||||
// 自动选择空闲mailbox发送消息,不需要人为指定
|
||||
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
|
||||
|
||||
@@ -417,26 +492,16 @@ u8 CAN_transmiter::CAN_Send(u32 id, u8 length, u8 *data) {
|
||||
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;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CANFD 数据发送
|
||||
\param id CAN消息ID
|
||||
\param length CAN消息长度
|
||||
\param data CAN消息数据
|
||||
*/
|
||||
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");
|
||||
@@ -471,6 +536,17 @@ 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);
|
||||
}
|
||||
|
||||
// 将数据复制到DMA缓冲区
|
||||
memcpy(can_tx_buffer, data, length);
|
||||
|
||||
// 配置DMA发送参数
|
||||
dma_tx_parameter.number = length;
|
||||
dma_init(DMA0, DMA_CH5, &dma_tx_parameter);
|
||||
|
||||
// 启动DMA传输
|
||||
dma_channel_enable(DMA0, DMA_CH5);
|
||||
|
||||
// 自动选择空闲mailbox发送消息,不需要人为指定
|
||||
transmit_mailbox = can_message_transmit(CAN0, &transmit_message);
|
||||
|
||||
@@ -480,19 +556,6 @@ u8 CAN_transmiter::CANFD_Send(u32 id, u8 length, u8 *data) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -628,6 +691,13 @@ void CAN0_RX0_IRQHandler(void) {
|
||||
// 清除中断标志
|
||||
can_interrupt_flag_clear(CAN0, CAN_INT_FLAG_RFL0);
|
||||
|
||||
// 使用DMA读取接收到的数据
|
||||
dma_channel_disable(DMA0, DMA_CH4);
|
||||
dma_rx_parameter.number =
|
||||
can_receive_message_length_get(CAN0, CAN_FIFO0);
|
||||
dma_init(DMA0, DMA_CH4, &dma_rx_parameter);
|
||||
dma_channel_enable(DMA0, DMA_CH4);
|
||||
|
||||
// 读取接收到的数据
|
||||
can_message_receive(CAN0, CAN_FIFO0, &CAN0_transmiter.receive_message);
|
||||
|
||||
@@ -648,3 +718,37 @@ void CAN0_RX0_IRQHandler(void) {
|
||||
printf("CAN FIFO0 overflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA通道4中断服务程序(CAN接收DMA)
|
||||
* @retval 无
|
||||
*/
|
||||
void DMA0_Channel4_IRQHandler(void) {
|
||||
if (dma_interrupt_flag_get(DMA0, DMA_CH4, DMA_INT_FLAG_FTF)) {
|
||||
// 清除DMA传输完成中断标志
|
||||
dma_interrupt_flag_clear(DMA0, DMA_CH4, DMA_INT_FLAG_G);
|
||||
|
||||
// 将DMA缓冲区的数据复制到接收消息结构体
|
||||
for (int i = 0; i < CAN0_transmiter.receive_message.rx_dlen && i < 8;
|
||||
i++) {
|
||||
CAN0_transmiter.receive_message.rx_data[i] = can_rx_buffer[i];
|
||||
}
|
||||
|
||||
// 接收标志位置1
|
||||
CAN0_transmiter.can0_receive_flag = SET;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA通道5中断服务程序(CAN/CANFD发送DMA)
|
||||
* @retval 无
|
||||
*/
|
||||
void DMA0_Channel5_IRQHandler(void) {
|
||||
if (dma_interrupt_flag_get(DMA0, DMA_CH5, DMA_INT_FLAG_FTF)) {
|
||||
// 清除DMA传输完成中断标志
|
||||
dma_interrupt_flag_clear(DMA0, DMA_CH5, DMA_INT_FLAG_G);
|
||||
|
||||
// 发送完成标志位置1
|
||||
CAN0_transmiter.can0_send_flag = RESET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "adc.h"
|
||||
#include "gd32c10x_can.h"
|
||||
#include "stdint.h"
|
||||
#include <stdio.h>
|
||||
@@ -57,7 +56,10 @@ static inline float_union_t unpack_bytes_to_float(u8 *buffer, u16 offset) {
|
||||
u8 can_gpio_init(void); // CAN引脚初始化
|
||||
void can_config(void); // CAN初始化
|
||||
void canfd_config(void);// CANFD初始化
|
||||
void can_dma_init(void); // CAN DMA初始化
|
||||
void CAN0_RX0_IRQHandler(void);// CAN接收中断处理函数
|
||||
void DMA0_Channel4_IRQHandler(void); // DMA通道4中断处理函数(CAN接收)
|
||||
void DMA0_Channel5_IRQHandler(void); // DMA通道5中断处理函数(CAN发送)
|
||||
|
||||
void can_loopback_init(void);
|
||||
void can_loopback_test(void);
|
||||
|
||||
+15
-14
@@ -1,7 +1,6 @@
|
||||
#include "Timer.h"
|
||||
#include "Can.h"
|
||||
#include "DengFOC.h"
|
||||
#include "ang_sensor.h"
|
||||
#include "Timer.h"
|
||||
#include "adc.h"
|
||||
#include "gd32c10x.h"
|
||||
@@ -9,8 +8,6 @@
|
||||
#include "gd32c10x_misc.h"
|
||||
#include "gd32c10x_rcu.h"
|
||||
#include "gd32c10x_timer.h"
|
||||
#include "systick.h"
|
||||
#include <cstdio>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -176,40 +173,43 @@ void TIMER2_IRQHandler(void) {
|
||||
// 每100us执行一次的操作
|
||||
sampler.update_current();
|
||||
|
||||
// 每1ms执行的代码 (100us * 10 = 1ms)
|
||||
if (total_us100_counter >= 10) {
|
||||
// 每1ms执行的代码
|
||||
total_us100_counter = 0; // 重置计数器
|
||||
|
||||
// 设置CAN发送标志
|
||||
CAN0_transmiter.can0_send_flag = SET;
|
||||
|
||||
if (sampler.get_current('U') > 2000 ||
|
||||
sampler.get_current('V') > 2000 ||
|
||||
sampler.get_current('W') > 2000) {
|
||||
FOC.over_current++;
|
||||
} else {
|
||||
FOC.over_current = 0;
|
||||
}
|
||||
|
||||
// 更新各种传感器数据
|
||||
sampler.update_mcu_temp();
|
||||
sampler.update_drv_temp();
|
||||
sampler.update_vbus_voltage();
|
||||
|
||||
// 每10ms执行的代码 (1ms * 10 = 10ms)
|
||||
// 停机判断及冷却
|
||||
if (FOC.over_current > 10) {
|
||||
FOC.is_shut_down = 10;
|
||||
}
|
||||
|
||||
static u8 ms10_counter = 0;
|
||||
ms10_counter++;
|
||||
if (ms10_counter >= 10) {
|
||||
ms10_counter = 0;
|
||||
// 可以添加每10ms执行的代码
|
||||
|
||||
// 每100ms执行的代码 (10ms * 10 = 100ms)
|
||||
static u8 ms100_counter = 0;
|
||||
ms100_counter++;
|
||||
if (ms100_counter >= 10) {
|
||||
ms100_counter = 0;
|
||||
// 可以添加每100ms执行的代码
|
||||
// if (sampler.get_current('U') > 1.0 ||
|
||||
// sampler.get_current('V') > 1.0 ||
|
||||
// sampler.get_current('W') > 1.0) {
|
||||
// if (FOC.is_shut_down == 0) {
|
||||
// FOC.shut_down();
|
||||
// }
|
||||
// }
|
||||
|
||||
// 每1s执行的代码 (100ms * 10 = 1s)
|
||||
static u8 sec_counter = 0;
|
||||
sec_counter++;
|
||||
if (sec_counter >= 10) {
|
||||
@@ -233,6 +233,7 @@ void TIMER3_IRQHandler(void) {
|
||||
timer_interrupt_flag_clear(TIMER3, TIMER_INT_UP);
|
||||
static u8 count = 0;
|
||||
count++;
|
||||
|
||||
if (FOC.is_shut_down > 0)
|
||||
FOC.is_shut_down--;
|
||||
else
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#include "ang_sensor.h"
|
||||
#include "core_cmInstr.h"
|
||||
#include "gd32c10x_gpio.h"
|
||||
#include "gd32c10x_spi.h"
|
||||
#include "stdbool.h"
|
||||
#include "systick.h"
|
||||
#include <cstdio>
|
||||
|
||||
#define SPI_CS_ENABLE() gpio_bit_reset(GPIOA, GPIO_PIN_15)
|
||||
#define SPI_CS_DISABLE() gpio_bit_set(GPIOA, GPIO_PIN_15)
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
#include "Can.h"
|
||||
#include "Filter.h"
|
||||
#include "Timer.h"
|
||||
#include "adc.h"
|
||||
#include "core_cm4.h"
|
||||
#include "initial.h"
|
||||
#include "main.h"
|
||||
#include "sys/initial.h"
|
||||
#include "systick.h"
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
|
||||
constexpr int status_print = 0;
|
||||
|
||||
+3
-10
@@ -1,28 +1,22 @@
|
||||
#include "main.h"
|
||||
#include "Can.h"
|
||||
#include "DengFOC.h"
|
||||
#include "Filter.h"
|
||||
#include "Timer.h"
|
||||
#include "adc.h"
|
||||
#include "core_cm4.h"
|
||||
#include "core_cm4.h"
|
||||
#include "ang_sensor.h"
|
||||
#include "gd32c10x_gpio.h"
|
||||
#include "initial.h"
|
||||
#include "systick.h"
|
||||
#include <cstdio>
|
||||
|
||||
// 全局变量定义
|
||||
CAN_transmiter CAN0_transmiter;
|
||||
FOC_Controlroller FOC;
|
||||
sampler sampler;
|
||||
CAN_transmiter CAN0_transmiter; //CAN初始化
|
||||
FOC_Controlroller FOC; // FOC控制初始化
|
||||
sampler sampler; // 采样器初始化
|
||||
|
||||
int main(void) {
|
||||
systick_config(); // 系统时钟初始化
|
||||
USART0_init(); // 调试串口初始化
|
||||
User_timer_init(); // Timer初始化
|
||||
adc_config(); // ADC初始化
|
||||
dma_config(); // DMA采样ADC初始化
|
||||
sampler.init(); // 采样器初始化
|
||||
driver_init(); // 电机驱动初始化
|
||||
|
||||
@@ -32,7 +26,6 @@ int main(void) {
|
||||
|
||||
while (1) {
|
||||
/* clear the FWDGT reset flag */
|
||||
// std::printf("1\n");
|
||||
// delay_1ms(100);
|
||||
fwdgt_counter_reload();
|
||||
CAN0_transmiter.communication_check();
|
||||
|
||||
@@ -1,96 +1,7 @@
|
||||
#include "initial.h"
|
||||
#include "gd32c10x_timer.h"
|
||||
#include "systick.h"
|
||||
#include <stdint.h>
|
||||
#include "Timer.h"
|
||||
#include <stdint.h>
|
||||
|
||||
extern u16 adc_value[7];
|
||||
|
||||
/*!
|
||||
\brief configure the DMA peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_config(void) {
|
||||
/* enable DMA0 clock */
|
||||
rcu_periph_clock_enable(RCU_DMA0);
|
||||
/* ADC_DMA_channel configuration */
|
||||
dma_parameter_struct dma_data_parameter;
|
||||
|
||||
/* ADC DMA_channel configuration */
|
||||
dma_deinit(DMA0, DMA_CH0);
|
||||
|
||||
/* initialize DMA single data mode */
|
||||
dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
|
||||
dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||||
dma_data_parameter.memory_addr = (uint32_t)(adc_value);
|
||||
dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
||||
dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
|
||||
dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
|
||||
dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;
|
||||
dma_data_parameter.number = 6;
|
||||
dma_data_parameter.priority = DMA_PRIORITY_HIGH;
|
||||
dma_init(DMA0, DMA_CH0, &dma_data_parameter);
|
||||
|
||||
dma_circulation_enable(DMA0, DMA_CH0);
|
||||
|
||||
/* enable DMA channel */
|
||||
dma_channel_enable(DMA0, DMA_CH0);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the ADC peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_config(void) {
|
||||
/* enable ADC clock */
|
||||
rcu_periph_clock_enable(RCU_ADC0);
|
||||
/* config ADC clock */
|
||||
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
|
||||
|
||||
/* 复位ADC */
|
||||
adc_deinit(ADC0);
|
||||
/* ADC模式配置 */
|
||||
adc_mode_config(ADC_MODE_FREE);
|
||||
/* 使能ADC连续转换功能 */
|
||||
adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
|
||||
/* 使能ADC扫描模式 */
|
||||
adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
|
||||
/* ADC数据右对齐配置 */
|
||||
adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
|
||||
/* 使能ADC温度传感器和内部参考电压 */
|
||||
adc_tempsensor_vrefint_enable();
|
||||
|
||||
/* 配置ADC通道长度 */
|
||||
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 6);
|
||||
/* 配置ADC规则通道 */
|
||||
adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_16,
|
||||
ADC_SAMPLETIME_239POINT5);
|
||||
adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 4, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
|
||||
adc_regular_channel_config(ADC0, 5, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);
|
||||
|
||||
/* ADC触发配置 */
|
||||
adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL,
|
||||
ADC0_1_EXTTRIG_REGULAR_NONE);
|
||||
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
|
||||
|
||||
/* 使能ADC接口 */
|
||||
adc_enable(ADC0);
|
||||
/* ADC校准 */
|
||||
adc_calibration_enable(ADC0);
|
||||
|
||||
/* 使能ADC DMA功能 */
|
||||
adc_dma_mode_enable(ADC0);
|
||||
|
||||
/* 使能ADC软件触发 */
|
||||
adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
|
||||
}
|
||||
|
||||
void GPIO_config(void) {
|
||||
// 使能GPIOB时钟
|
||||
@@ -126,7 +37,6 @@ void driver_init(void) {
|
||||
timer1_gpio_config();
|
||||
timer1_pwm_config();
|
||||
TIMER3_config();
|
||||
|
||||
}
|
||||
|
||||
int fputc(int ch, FILE *f) throw() {
|
||||
|
||||
@@ -4,15 +4,11 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "gd32c10x.h"
|
||||
#include "stdint.h"
|
||||
#include <stdio.h>
|
||||
#include "gd32c10x_eval.h"
|
||||
|
||||
void rcu_config(void);
|
||||
void adc_config(void);
|
||||
void dma_config(void);
|
||||
|
||||
static volatile uint32_t timer_delay_count = 0; // volatile 很重要!
|
||||
int fputc(int ch, FILE *f); // 声明fputc函数以重载标准库实现
|
||||
|
||||
|
||||
Reference in New Issue
Block a user