1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wojialaomuzhu-foc-tutorial

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
README.txt 12 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 08.06.2025 03:02 f4ecd94
Среда:
Программирование с использованием библиотеки HAL,
Documents: документы
FOC-407-Demo: собственная печатная плата V1.0.0, двухканальный безщеточный драйвер
ODrive: платформа ODrive, одноканальный драйвер
Использование ресурсов микроконтроллера:
PWM:
Используется центральное синхронизированное режим 2, сначала происходит подсчет вверх, затем вниз, и прерывание переполнения происходит только при подсчете вверх.
Используется режим PWM 1, подсчет вверх, CNT<CCR для активного уровня, активный уровень - высокий.
ODrive: включено прерывание сравнения для канала 4, CCR канала 4 - максимальное значение CCR каналов 1, 2, 3 + 1 мкс. 1 мкс для устойчивости АЦП.
FOC-407-Demo: используется прерывание переполнения, в функции прерывания выбирается прерывание переполнения вверх.
В коде FOC-407-Demo используются основной и вспомогательный таймеры для разделения времени вычисления токовых циклов двух двигателей, чтобы они не мешали друг другу.
ABZ энкодер:
Используется ABZ ортогональный инкрементальный энкодер.
При каждом включении требуется калибровка электрического угла.
Используется Z-ось для сброса при каждом обороте.
Абсолютный энкодер:
Калибровка производится только при первом включении и при демонтаже двигателя.
Выбран чип TLE5012B1000.
Сampling тока:
Сampling тока выполняется с помощью однократного сканирования, DMA + прерывания.
ADC sampling запускается в прерывании таймера 1 канала 4.Контрольный процесс:
Прерывание таймера, выполнение одного ADC sampling.
Завершение ADC sampling запускает прерывание DMA, в котором выполняется токовый цикл FOC.
Процесс FOC (FOC.c):
1. Получение токов фаз B и C, вычисление тока фазы A
2. Получение текущего электрического угла
3. Вычисление действительных токов IQ и ID с помощью преобразований Кларка и Парка
4. Сравнение с целевыми IQ и ID и вычисление UQ и UD с помощью PID
5. Преобразование UQ и UD обратным преобразованием Парка для получения Uα и Uβ
6. Передача Uα и Uβ в модуль генерации SVPWM
Процесс SVPWM (Svpwm.c):
1. Получение Uα и Uβ
2. Вычисление текущего сектора с помощью Uα и Uβ
3. Вычисление времени действия каждого вектора с помощью 7-сегментного PWM
4. Вычисление времени высокого уровня таймера на основе времени действия вектора
5. Вычисление значения CCR для каждого канала на основе времени высокого уровня таймера
6. Выбор максимального значения CCR для канала 4, подготовка к следующему прерыванию таймера
Прерывание сравнения таймера:
Запуск ADC для выполнения одного ADC sampling
Прерывание DMA:
Чтение данных ADC для управления FOCПрерывание Z-оси энкодера:
Калибровка угла файлового описания:
Все файлы размещены в директории User.
APP: Главный вход для приложения, реализует управление процессом инициализации и циклическим выполнением.
Function: Размещает функциональные программы, в настоящее время не реализовано, например, для размещения T-образного ускорения и замедления.
MCUDriver: Размещает код периферийных устройств микроконтроллера, таких как SPI, GPIO, TIM, ADC.
Framework: Размещает кодовые библиотеки, отделяет код драйверов от аппаратной платформы.
PeripheralsDriver: Размещает драйверы, объединяет код аппаратной платформы и кодовых библиотек, реализует конкретные функции, то есть (MCUDriver + Framework).
RTT: Использует Segger RTT для отладочного вывода, также можно немного изменить для вывода через последовательный порт.
Известные ошибки
1. В двуканальном коде FOC (FOC-407-Demo) последовательность инициализации, созданная CUBE, приводит к тому, что ADC2 не может войти в DMA прерывание. Поэтому порядок инициализации периферийных устройств должен быть изменен на такой, как в моем коде.
2. Невозможно установить связь с DRV8301 через SPI, даже после изучения данных из справочника по устройству и попыток отладки. Если кто-то имеет опыт в этом, прошу поделиться.
3. Отсутствует обработка торможенияОбъявление:
1. Из-за влияния платформы аппаратного обеспечения код может не запускаться напрямую, но его можно использовать в качестве примера.
2. Сначала отладьте SVPWM, затем отладьте измерение тока, затем замкните цикл, и SVPWM позволит двигателю вращаться.
3. При замкнутом цикле сначала настраивайте цикл тока, затем цикл скорости.
4. При цикле тока сначала настраивайте ID, затем IQ.
5. Если у вас есть вопросы, пожалуйста, задавайте их, если вы нашли ошибки, пожалуйста, сообщите об этом.
Контакты:
QQ: 965552797@qq.comСтиль написания кода:
При реализации функции мы делим её на три шага:
1. Настройка выводов микроконтроллера.
2. Настройка логики функционирования датчиков, то есть запуск датчиков, или протоколы связи, или управление двигателем, или управление временем.
3. Создание небольших логических приложений в зависимости от функций датчиков, таких как мигание светодиодов или управление скоростью двигателя.
На самом деле, мы обнаружили, что шаги 1 и 3 зависят от платформы аппаратного обеспечения и от функций, которые мы хотим реализовать, и их нужно постоянно изменять. Однако шаг 2 остаётся неизменным, независимо от используемой платформы аппаратного обеспечения. Например, логика связи TLE5012B кодека через SPI остаётся неизменной.
Поэтому мы абстрагировали шаг 2, и для TLE5012B мы представили этот датчик в виде структуры, предполагая, что у него есть функции передачи данных через SPI, чтения данных через SPI, управления выводом SPI_CS, микросекундной задержки. Имея эти функции, мы можем использовать этот датчик.
Но сейчас эти функции являются виртуальными, и мы используем эти псевдофункции, чтобы сначала написать логику работы датчиков, а затем реализуем настоящую функцию связи через SPI на микроконтроллере и передаём адреса этих настоящих функций в структуру TLE5012B.В одноканальном коде FOC создаётся впечатление, что такой подход к написанию кода сложен и избыточен. Однако в двуканальном коде FOC преимущества такого подхода становятся очевидными. Пример использования LEDControl
Мы обычно начинаем с включения одного LED, когда работаем с платой. Однако мы обнаруживаем, что каждый раз, когда нужно включить LED, нам приходится переписывать функции. Если добавить эффект мигания, это становится ещё более утомительным. Чтобы не влиять на реальное время основного цикла, нам даже приходится использовать таймерное прерывание, что делает работу невыносимой. В данном коде мы объявляем структуру для управления LED:
```c
struct SLEDControl_Struct {
uint8_t state; // Состояние работы LED: 0 - LED всегда выключен, 1 - LED всегда включен, 2 - мигание
uint8_t onoff; // Текущее состояние LED
float cycle; // Период мигания (в миллисекундах)
uint8_t onLeave; // Уровень включения LED
uint32_t startTime;
void(*SetLEDLeave)(uint8_t leave); // Функция для установки уровня включения LED
};
```
Для LED нам нужно знать уровень включения, управление пином, поэтому мы объявляем эти две функции в структуре и используем виртуальные функции для реализации логики, например:
```c
void SetLEDON(PLEDControl_Struct gLED)
{
gLED->state = LEDState_ON;
gLED->SetLEDLeave(gLED->onLeave);
}
```
Затем мы реализуем функцию управления пином:
```c
void SetLedLeave(uint8_t leave)
{
HAL_GPIO_WritePin(SYS_LED_GPIO_Port, SYS_LED_Pin, leave);
}
```И, наконец, передаём адрес функции SetLedLeave через интерфейс в структуру:
```c
LED_EXPORT(gSysLed, 1, SetLedLeave);
#define LED_EXPORT(x, xOnLeave, xSetLEDLeave) \
LEDControl_Struct x = { \
.state = LEDState_OFF, \
.onoff = 0, \
.cycle = 0.0, \
.onLeave = xOnLeave, \
.startTime = 0, \
.SetLEDLeave = xSetLEDLeave, \
};
```

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/wojialaomuzhu-foc-tutorial.git
git@api.gitlife.ru:oschina-mirror/wojialaomuzhu-foc-tutorial.git
oschina-mirror
wojialaomuzhu-foc-tutorial
wojialaomuzhu-foc-tutorial
main