代码拉取完成,页面将自动刷新
同步操作将从 zhanshenrui/bldc 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
Copyright 2016 Benjamin Vedder benjamin@vedder.se
This file is part of the VESC firmware.
The VESC firmware is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The VESC firmware is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ch.h"
#include "hal.h"
#include "stm32f4xx_conf.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "mc_interface.h"
#include "mcpwm.h"
#include "mcpwm_foc.h"
#include "ledpwm.h"
#include "comm_usb.h"
#include "ledpwm.h"
#include "terminal.h"
#include "hw.h"
#include "app.h"
#include "packet.h"
#include "commands.h"
#include "timeout.h"
#include "comm_can.h"
#include "ws2811.h"
#include "led_external.h"
#include "encoder.h"
#include "servo_simple.h"
#include "utils.h"
#include "nrf_driver.h"
#include "rfhelp.h"
#include "spi_sw.h"
/*
* Timers used:
* TIM1: mcpwm
* TIM2: mcpwm
* TIM12: mcpwm
* TIM8: mcpwm
* TIM3: servo_dec/Encoder (HW_R2)/servo_simple
* TIM4: WS2811/WS2812 LEDs/Encoder (other HW)
*
* DMA/stream Device Function
* 1, 2 I2C1 Nunchuk, temp on rev 4.5
* 1, 7 I2C1 Nunchuk, temp on rev 4.5
* 1, 1 UART3 HW_R2
* 1, 3 UART3 HW_R2
* 2, 2 UART6 Other HW
* 2, 7 UART6 Other HW
* 2, 4 ADC mcpwm
* 1, 0 TIM4 WS2811/WS2812 LEDs CH1 (Ch 1)
* 1, 3 TIM4 WS2811/WS2812 LEDs CH2 (Ch 2)
*
*/
// Private variables
static THD_WORKING_AREA(periodic_thread_wa, 1024);
static THD_WORKING_AREA(timer_thread_wa, 128);
//亮灯,发送电机,编码器位置
static THD_FUNCTION(periodic_thread, arg) {
(void)arg;
chRegSetThreadName("Main periodic");
for(;;) {
if (mc_interface_get_state() == MC_STATE_RUNNING) {
ledpwm_set_intensity(LED_GREEN, 1.0);
} else {
ledpwm_set_intensity(LED_GREEN, 0.2);
}
mc_fault_code fault = mc_interface_get_fault();
if (fault != FAULT_CODE_NONE) {
for (int i = 0;i < (int)fault;i++) {
ledpwm_set_intensity(LED_RED, 1.0);
chThdSleepMilliseconds(250);
ledpwm_set_intensity(LED_RED, 0.0);
chThdSleepMilliseconds(250);
}
chThdSleepMilliseconds(500);
} else {
ledpwm_set_intensity(LED_RED, 0.0);
}
if (mc_interface_get_state() == MC_STATE_DETECTING) {
commands_send_rotor_pos(mcpwm_get_detect_pos());
}
disp_pos_mode display_mode = commands_get_disp_pos_mode();
switch (display_mode) {
case DISP_POS_MODE_ENCODER:
commands_send_rotor_pos(encoder_read_deg());
break;
case DISP_POS_MODE_PID_POS:
commands_send_rotor_pos(mc_interface_get_pid_pos_now());
break;
case DISP_POS_MODE_PID_POS_ERROR:
commands_send_rotor_pos(utils_angle_difference(mc_interface_get_pid_pos_set(), mc_interface_get_pid_pos_now()));
break;
default:
break;
}
if (mc_interface_get_configuration()->motor_type == MOTOR_TYPE_FOC) {
switch (display_mode) {
case DISP_POS_MODE_OBSERVER:
commands_send_rotor_pos(mcpwm_foc_get_phase_observer());
break;
case DISP_POS_MODE_ENCODER_OBSERVER_ERROR:
commands_send_rotor_pos(utils_angle_difference(mcpwm_foc_get_phase_observer(), mcpwm_foc_get_phase_encoder()));
break;
default:
break;
}
}
chThdSleepMilliseconds(10);
// chThdSleepMilliseconds(40);
// volatile const mc_configuration *conf = mc_interface_get_configuration();
// float vq = mcpwm_foc_get_vq();
// float iq = mc_interface_get_tot_current_directional();
// float linkage = conf->foc_motor_flux_linkage;
// float speed = ((2.0 * M_PI) / 60.0) * mc_interface_get_rpm();
//
// if (iq < -6.0) {
// float res = vq / (linkage * speed * iq);
// res *= 2.0 / 3.0;
// static float res_filtered = 0.0;
// UTILS_LP_FAST(res_filtered, res, 0.02);
// commands_printf("Res: %.4f", (double)res_filtered);
// }
// chThdSleepMilliseconds(40);
// commands_printf("Max: %.2f Min: %.2f",
// (double)mc_interface_get_configuration()->lo_current_motor_max_now,
// (double)mc_interface_get_configuration()->lo_current_motor_min_now);
}
}
//核查各个设备接收是否超时
static THD_FUNCTION(timer_thread, arg) {
(void)arg;
chRegSetThreadName("msec_timer");
for(;;) {
packet_timerfunc();
chThdSleepMilliseconds(1);
}
}
//主线程,_idle_thread线程,timer_thread_mc_interface,sample_send_thread_mc_interface,timer_thread_mcpwm,rpm_thread_mcpwm,detect_thread_commands
//serial_read_thread_comm_usb,serial_process_thread_comm_usb,timeout_thread_timeout,periodic_thread_main,timer_thread_main
//程序执行过程中,除了执行上述线程还会执行一些回调函数,主要有:mcpwm_adc_int_handler,send_packet(.send_func), process_packet(.process_func)
//还有中断函数,具体见irq_handlers.c文件里的中断函数
//还有些信号接收函数或线程,暂时未列出,具体见app_set_configuration()
/*
timer_thread_mc_interface
//定时检测驱动是否有错误
//检测MOS温度保护,电机温度保护,最大最小转速限制,电池低压保护,功率限制
//辅助功能开启
sample_send_thread_mc_interface
//将采集数据添加到buffer末尾, 申请互斥锁,然后将数据data添加到handler_num所在的发送缓冲区里,然后由handler_num代表的硬件发送缓冲区里的数据,最后释放互斥锁
timer_thread_mcpwm
//未知
rpm_thread_mcpwm
//转速PID控制,未细看
detect_thread_commands
//未细看
serial_read_thread_comm_usb
//从SDU1设备里读数据到serial_rx_buffer里,然后发信号给process_tp线程(serial_process_thread_comm_usb)
serial_process_thread_comm_usb
//等待到信号,接收字节,根据接收到的字节作不同处理,接收完一帧时调用process_packet函数(这个函数根据设备不同而不同,这里只分析USB)
//在process_packet函数里设置发送函数,根据不同上位机命令作不同处理,重点分析commands_process_packet这个函数
timeout_thread_timeout
//超时,设置刹车电流刹车
periodic_thread_main
//亮灯,发送电机,编码器位置
timer_thread_main
//核查各个设备接收是否超时
中断
ADC1_2_3_IRQHandler://ADC注入中断
HW_ENC_EXTI_ISR_VEC://编码器出错
HW_ENC_TIM_ISR_VEC://编码器定时发送位置信息
TIM8_CC_IRQHandler:未知
信号接收:以PPM为例,在app_set_configuration()里调用app_ppm_start函数,这个函数里创建线程,开启虚定时器
update:每2毫秒发送信号给PPM线程ppm_thread
*/
int main(void) {
halInit();//
chSysInit(); //初始化系统,并创建_idle_thread线程
// Initialize the enable pins here and disable them
// to avoid excessive current draw at boot because of
// floating pins.
#ifdef HW_HAS_DRV8313
INIT_BR();
#endif
chThdSleepMilliseconds(1000); //挂起任务多少毫秒,会引起CPU切换
hw_init_gpio();//设置相应管脚
LED_RED_OFF();
LED_GREEN_OFF();
//通用配置初始化,对数组VirtAddVarTab赋值,格式化EEPROM,擦除0x8004000起16KB,探险0x80080000起16KB地址,并对0x80040000写0x0000
conf_general_init();
ledpwm_init();
mc_configuration mcconf;
//读电调参数,如果没有,就使用默认参数
conf_general_read_mc_configuration(&mcconf);
//对静态变量m_conf传递电调参数值,并创建线程timer_thread_mcif,timer_thread_mcif
//初始化霍尔表,TIM1初始化(用于PWM产生),TIM8初始化(用于ADC采样),ADC普通及注入通道初始化,ADC对应DMA初始化及中断函数声明
//TIM2(用于计算RPM)初始化,设置ADC采样点,初始化TIM12,创建线程timer_thread,rpm_thread,设置看门狗
mc_interface_init(&mcconf);
commands_init();//创建线程detect_thread_commands
comm_usb_init();//初始化并启动USB串口,设置串口接收发送函数,分配互斥锁,创建线程serial_read_thread,serial_process_thread
#if CAN_ENABLE
comm_can_init();
#endif
app_configuration appconf;
conf_general_read_app_configuration(&appconf); //读APP配置,如果没有则创建默认配置
app_set_configuration(&appconf);
#ifdef HW_HAS_PERMANENT_NRF
conf_general_permanent_nrf_found = nrf_driver_init();
if (conf_general_permanent_nrf_found) {
rfhelp_restart();
} else {
nrf_driver_stop();
// Set the nrf SPI pins to the general SPI interface so that
// an external NRF can be used with the NRF app.
spi_sw_change_pins(
HW_SPI_PORT_NSS, HW_SPI_PIN_NSS,
HW_SPI_PORT_SCK, HW_SPI_PIN_SCK,
HW_SPI_PORT_MOSI, HW_SPI_PIN_MOSI,
HW_SPI_PORT_MISO, HW_SPI_PIN_MISO);
}
#endif
timeout_init();//创建超进线程timeout_thread
timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current);
#if WS2811_ENABLE
ws2811_init();
#if !WS2811_TEST
led_external_init();
#endif
#endif
#if SERVO_OUT_ENABLE
servo_simple_init();
#endif
// Threads
chThdCreateStatic(periodic_thread_wa, sizeof(periodic_thread_wa), NORMALPRIO, periodic_thread, NULL);//periodic_thread_main,timer_thread_main
chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL);
#if WS2811_TEST
unsigned int color_ind = 0;
const int num = 4;
const uint32_t colors[] = {COLOR_RED, COLOR_GOLD, COLOR_GRAY, COLOR_MAGENTA, COLOR_BLUE};
const int brightness_set = 100;
for (;;) {
chThdSleepMilliseconds(1000);
for (int i = 0;i < brightness_set;i++) {
ws2811_set_brightness(i);
chThdSleepMilliseconds(10);
}
chThdSleepMilliseconds(1000);
for(int i = -num;i <= WS2811_LED_NUM;i++) {
ws2811_set_led_color(i - 1, COLOR_BLACK);
ws2811_set_led_color(i + num, colors[color_ind]);
ws2811_set_led_color(0, COLOR_RED);
ws2811_set_led_color(WS2811_LED_NUM - 1, COLOR_GREEN);
chThdSleepMilliseconds(50);
}
for (int i = 0;i < brightness_set;i++) {
ws2811_set_brightness(brightness_set - i);
chThdSleepMilliseconds(10);
}
color_ind++;
if (color_ind >= sizeof(colors) / sizeof(uint32_t)) {
color_ind = 0;
}
static int asd = 0;
asd++;
if (asd >= 3) {
asd = 0;
for (unsigned int i = 0;i < sizeof(colors) / sizeof(uint32_t);i++) {
ws2811_set_all(colors[i]);
for (int i = 0;i < brightness_set;i++) {
ws2811_set_brightness(i);
chThdSleepMilliseconds(2);
}
chThdSleepMilliseconds(100);
for (int i = 0;i < brightness_set;i++) {
ws2811_set_brightness(brightness_set - i);
chThdSleepMilliseconds(2);
}
}
}
}
#endif
for(;;) {
chThdSleepMilliseconds(10);
if (encoder_is_configured()) {
// comm_can_set_pos(0, encoder_read_deg());
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。