diff --git a/.gitignore b/.gitignore index a7f0d2f..0479bf4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /Debug/ +/Release/ /UKSSTMS320F28335.CS_/ diff --git a/Bin/CCS12/.gitignore b/Bin/CCS12/.gitignore new file mode 100644 index 0000000..30b9b2d --- /dev/null +++ b/Bin/CCS12/.gitignore @@ -0,0 +1,3 @@ +# CCS 12 output files +* +!.gitignore diff --git a/PHASE_COMPARISON_BALSAM_165_167.md b/PHASE_COMPARISON_BALSAM_165_167.md new file mode 100644 index 0000000..22c617f --- /dev/null +++ b/PHASE_COMPARISON_BALSAM_165_167.md @@ -0,0 +1,598 @@ +# Сравнение фазовой части Balsam 165 и Balsam 167 + +## Область сравнения + +Сравнивались: + +- захват фазных сигналов АЦП; +- удаление нулевого смещения; +- масштабирование в физические единицы; +- расчёт общего действующего значения; +- расчёт уровней отдельных фаз A, B и C; +- диагностика перекоса и обрыва фаз; +- диагностические биты и регистры Modbus; +- пороги напряжения и выдержки времени. + +Исходные проекты: + +- `K:/git_project/Balsam_165_periph`; +- `K:/git_project/Balsam_167_periph`. + +Основные файлы: + +| Проект | Файл | +|---|---| +| Balsam 165 | `K:/git_project/Balsam_165_periph/Source/Internal/measure.c` | +| Balsam 165 | `K:/git_project/Balsam_165_periph/Source/Internal/ADC.c` | +| Balsam 165 | `K:/git_project/Balsam_165_periph/Source/Internal/Include/measure.h` | +| Balsam 165 | `K:/git_project/Balsam_165_periph/Doc/Balsam 165 data stru.xls` | +| Balsam 167 | `Source/Internal/measure.c` | +| Balsam 167 | `Source/Internal/ADC.c` | +| Balsam 167 | `Source/Internal/Include/measure.h` | +| Balsam 167 | `Doc/Balsam 167 data stru.xls` | + +## Вывод + +Balsam 167 использует более правильный способ расчёта действующих значений +отдельных фаз: усреднение квадрата с последующим извлечением корня. Balsam 165 +сглаживает модуль сигнала, что не является настоящим RMS. + +При этом в Balsam 167 появились две ошибки индексации: + +1. Парный канал записывается по абсолютному индексу, но читается по + относительному. +2. Бит `Ignor` устанавливается у абсолютного номера датчика, но проверяется у + относительного `chan`. + +Для УМП, где `pow_addr == 0`, первая ошибка не проявляется. Для силового блока +она может приводить к дублированию фазных уровней и ложному `Wry + Stop`. + +Рекомендуемый вариант: сохранить RMS-алгоритм Balsam 167, исправить индексацию +и выполнять диагностику трёх фаз один раз после обработки всей пары каналов. + +## Сводная таблица + +| Параметр | Balsam 165 | Balsam 167 | Оценка | +|---|---|---|---| +| Частота АЦП | 5000 Гц | 3750 Гц | Изменена | +| Выбор фазных входов АЦП | `CONV02…CONV05` | `CONV02…CONV05` | Одинаковый | +| Формула `im_calc()` | Одинаковая | Одинаковая | Без изменений | +| Фаза B | `-A-C`, для `dsk_COMM` эквивалентная разность | `-A-C` после смены знака A | По модулю эквивалентно | +| Уровень отдельной фазы | EMA от `abs(x)` | `sqrt(EMA(x²))` | 167 корректнее | +| Частота фильтра результата | 5 Гц | 3 Гц | 167 медленнее | +| Тип `lev_count[]` | `float` | `int` | В 167 раньше теряется дробная часть | +| Порог перекоса | 20% | 30% | 167 менее чувствителен | +| Выдержка измеряемой фазы | около 1,5 с | около 3 с | 167 медленнее | +| Выдержка восстановленной фазы | около 0,75 с | около 1,5 с | В обеих версиях вдвое короче | +| `Curr_Edge`, УМП | 100 | 300 | Порог существенно повышен | +| `Curr_Edge`, силовой блок | 40 | 200 | Порог существенно повышен | +| Низкое `Utr` | без выдержки | счётчик около 3 с | Улучшено, но блокируется `Ignor` | +| Верхнее `Utr` | без выдержки | без выдержки | Без улучшения | +| Калибровка входов | жёсткий `curK[]` | Modbus/EEPROM `Caliber[]` | 167 гибче | +| Пары каналов силового блока | корректные относительные индексы | несогласованные индексы | Регрессия 167 | +| Обработка `Ignor` | правильный абсолютный датчик | проверяется `chan` | Регрессия 167 | +| Отдельные биты фаз A/B/C | нет | нет | Общий недостаток | +| Контроль пределов АЦП U/I | нет | нет | Общий недостаток | + +## 1. Захват сигналов АЦП + +Для УМП обе версии используют одинаковые входы: + +```c +CONV02 = 0x5; // напряжение 1 +CONV03 = 0x4; // напряжение 2 +CONV04 = 0x7; // ток 1 +CONV05 = 0x2; // ток 2 +``` + +Данные читаются из результатов `ADCRESULT2…ADCRESULT5`, после чего вызывается +`Current_count(i)`. + +Различается частота обработки: + +```text +Balsam 165: ADC_FREQ = 5000 Гц +Balsam 167: ADC_FREQ = 3750 Гц +``` + +Назначение входов УМП: + +| `chan` | Сигнал | +|---:|---| +| 0 | `Utr A` | +| 1 | `Utr C` | +| 2 | `Itr A` | +| 3 | `Itr C` | + +Фаза B физически не измеряется. + +## 2. Нулевое смещение + +В обеих версиях используется медленное усреднение: + +```text +zero[n] = zero[n-1] + (ADC-zero[n-1]) / (5 * ADC_FREQ) +``` + +### Balsam 165 + +Ноль записывается постоянно: + +```c +Zero_lev[chan] = filterbat(&out_filter[chan], zer_count[chan]); +``` + +Для подстройки используются те же `out_filter[]`, которые участвуют в другой +обработке сигналов. + +### Balsam 167 + +Добавлены отдельные фильтры `zer_filter[]`: + +```c +Zer = filterbat(&zer_filter[chan], zer_count[chan]); +if (WAKE < (WAKE_TIME / 2)) Zero_lev[chan] = Zer; +``` + +Разделение фильтров является улучшением. Однако после того как `WAKE` достиг +нуля, условие остаётся истинным. Подстройка нуля фактически продолжается во +время всей работы. + +Если подстройка нужна только при запуске, должно проверяться также `WAKE > 0`. + +## 3. Масштабирование + +### Balsam 165 + +Используются жёстко заданные коэффициенты `curK[]`: + +| Устройство | Напряжение | Ток | +|---|---:|---:| +| УМП 1/2 | `0.386` | `4.82` | +| Силовой блок | `0.402` | — | + +Коэффициенты одинаковы для однотипных каналов и не берутся из EEPROM. + +### Balsam 167 + +Коэффициенты вычисляются из `Caliber[0…3]`: + +```text +напряжение: powK = Caliber / 10000 +ток: powK = Caliber / 1000 +``` + +Преимущества: + +- индивидуальная калибровка каждого входа; +- отдельные значения для экземпляров устройств; +- сохранение и загрузка через EEPROM. + +Значения тока заметно отличаются от Balsam 165. Например, для УМП 1 в +Balsam 167 используются `3.505` и `3.380` вместо `4.82`. Это может быть связано +с изменением аппаратной части или новой калибровкой и требует стендовой сверки. + +## 4. Общий уровень трёхфазного сигнала + +Функция `im_calc()` в проектах совпадает: + +```text +isA = -1.5 * (a + b) +isB = cos(π/6) * (a - b) +Amplitude = 2/3 * sqrt(isA² + isB²) +Level = Amplitude / sqrt(2) +``` + +Эквивалентная формула амплитуды: + +```text +Amplitude = 2/sqrt(3) * sqrt(a² + a*b + b²) +``` + +### Фильтрация общего уровня + +Balsam 165 сначала делит амплитуду на `sqrt(2)`, затем фильтрует `Level` +фильтром 5 Гц. Для тока и всех каналов `dsk_COMM` используется дополнительная +статическая переменная `ffLev`. + +`ffLev` одна на все вызовы функции. На силовом блоке результаты разных пар +могут влиять друг на друга. + +Balsam 167 фильтрует амплитуду отдельным фильтром текущего датчика: + +```c +Amplitude = filterbat(&out_filter[sens], im_calc(Current, aCurrent)); +Level = Amplitude / RADIX2; +``` + +Это устраняет общий `ffLev` и разделяет состояния фильтров разных пар. + +### Зона нечувствительности + +Balsam 165: + +```text +Level < Curr_Edge -> Level = 0 +``` + +Для УМП порог равен 100 единицам RMS. + +Balsam 167: + +```text +напряжение: Amplitude < 20 -> 0 +ток: Amplitude < 75 -> 0 +``` + +В пересчёте на RMS это примерно 14,1 для напряжения и 53,0 для тока. Поэтому +Balsam 167 публикует слабые сигналы, которые Balsam 165 обнулял. + +## 5. Уровни отдельных фаз + +### Balsam 165: среднее модуля + +```c +lev_count[chan] += + (fabs(Current) - lev_count[chan]) / (ADC_FREQ / 5); +``` + +Для синусоиды установившееся значение соответствует среднему модулю: + +```text +MeanAbs = 2/π * Amplitude ≈ 0.6366 * Amplitude +``` + +### Balsam 167: настоящий RMS + +```c +lev_quadr[chan] += + (Current * Current - lev_quadr[chan]) / ADC_FREQ; +lev_count[chan] = sqrt(lev_quadr[chan]); +``` + +Для синусоиды: + +```text +RMS = 1/sqrt(2) * Amplitude ≈ 0.7071 * Amplitude +``` + +При одинаковом входном масштабе Balsam 167 показывает примерно в 1,1107 раза, +или на 11,1%, больше Balsam 165. + +Это изменение влияет на абсолютные фазные уровни, но почти не влияет на +отношение минимальной фазы к максимальной, используемое для `Wry`. + +### Скорость сглаживания + +Balsam 165 использует коэффициент `5/ADC_FREQ`, что соответствует постоянной +времени около 0,2 с. + +Balsam 167 использует коэффициент `1/ADC_FREQ`, что соответствует постоянной +времени около 1 с. Фазные уровни Balsam 167 изменяются медленнее и стабильнее. + +## 6. Восстановление фазы B + +Для УМП в обеих версиях: + +```text +B = -A - C +``` + +Для силового блока в Balsam 165 используется: + +```text +third = current_channel - first_channel +``` + +В Balsam 167 сначала меняется знак сохранённого первого канала, затем +применяется общая формула `-Current-aCurrent`. Результат отличается знаком, но +для RMS знак не имеет значения. + +Основной недостаток общий: фаза B не измеряется. Неисправность B определяется +только через математическую связь с A и C. + +## 7. Карта фазных регистров + +В Balsam 165 код записывает: + +```text +0x68 + n*3 + 0 = текущий нечётный канал, для УМП фаза C +0x68 + n*3 + 1 = парный канал, для УМП фаза A +0x68 + n*3 + 2 = восстановленная фаза B +``` + +То есть фактический порядок для УМП: + +```text +C, A, B +``` + +В Balsam 167 первые две записи переставлены: + +```text +0x68 + n*3 + 0 = парный канал A +0x68 + n*3 + 1 = текущий канал C +0x68 + n*3 + 2 = восстановленная фаза B +``` + +Порядок соответствует карте Balsam 167: + +| Регистр | УМП | +|---:|---| +| `0x68` | `Utr A` | +| `0x69` | `Utr C` | +| `0x6A` | `Utr B` | +| `0x6B` | `Itr A` | +| `0x6C` | `Itr C` | +| `0x6D` | `Itr B` | + +В карте Balsam 165 эти регистры не описаны как фазные. Адрес `0x68` обозначен +как яркость ламп, хотя исходный код записывает туда фазный уровень. Это риск +несовместимости прошивки с внешним ПО и документацией. + +## 8. Диагностика `Wry` + +В обеих версиях используется отношение: + +```text +Max = max(phase_A, phase_C, phase_B) +deviation = (Max - phase) / Max +``` + +### Balsam 165 + +```text +deviation > 20% +Max > Curr_Edge +выдержка измеряемой фазы ≈ 1,5 с +``` + +`Curr_Edge`: + +| Режим | Значение | +|---|---:| +| УМП | 100 | +| Силовой блок | 40 | + +### Balsam 167 + +```text +deviation > 30% +Max > Curr_Edge +выдержка измеряемой фазы ≈ 3 с +``` + +`Curr_Edge`: + +| Режим | Значение | +|---|---:| +| УМП | 300 | +| Силовой блок | 200 | + +Balsam 167 значительно менее чувствителен к перекосу и реагирует медленнее. + +### Ошибка выдержки восстановленной фазы + +Один счётчик `err_count[thrd]` вызывается при обработке обоих каналов пары. +Поэтому он увеличивается дважды за цикл АЦП. + +Фактическая выдержка постоянного дефекта фазы B: + +| Проект | Заданная | Фактическая для B | +|---|---:|---:| +| Balsam 165 | 1,5 с | около 0,75 с | +| Balsam 167 | 3 с | около 1,5 с | + +Проблема присутствует в обеих версиях. + +### Деление на ноль + +Обе версии сначала вычисляют отношение с делением на `Max`, а затем проверяют +нижний порог: + +```c +((Max - phase) / Max > limit) && (Max > Curr_Edge) +``` + +При `Max == 0` выполняется `0/0`. Безопасный порядок: + +```c +(Max > Curr_Edge) && (((Max - phase) / Max) > limit) +``` + +## 9. Различия обработки `Ignor` + +### Balsam 165 + +Используется правильный абсолютный номер датчика: + +```c +sens = tpl_cans + chan; +ignor = sens_error[sens].bit.Ignor; +``` + +Ошибки `Wry`, `Out` и `Hyper` продолжают вычисляться и передаваться, но +`Stop` не устанавливается для игнорируемого канала. + +### Balsam 167 + +Проверяется относительный индекс: + +```c +sens = pow_addr + chan; +if (WAKE || sens_error[chan].bit.Ignor) goto fin; +``` + +Последствия различаются по типу устройства. + +#### УМП + +Для УМП `pow_addr == 0`, поэтому индекс формально совпадает. Каналам напряжения +`0x00` и `0x01` по умолчанию устанавливается `Ignor`. В результате Balsam 167 +полностью пропускает для напряжения: + +- `Wry`; +- `Out` при `Utr < 300 В`; +- `Hyper` при `Utr > 420 В`; +- `Stop`. + +В Balsam 165 эти информационные биты вычислялись, но `Stop` блокировался. + +#### Силовой блок + +На силовом блоке `pow_addr != 0`. `Ignor` устанавливается в +`sens_error[pow_addr+chan]`, но проверяется `sens_error[chan]`. + +Из-за этого игнорирование может не сработать, а `Wry + Stop` сформироваться для +канала, который должен быть исключён из диагностики. + +## 10. Регрессия `sens_pair` в Balsam 167 + +В Balsam 165 пары хранятся относительно `chan`: + +```c +sens_pair[0] = 1; +sens_pair[1] = 0; +sens_pair[2] = 3; +sens_pair[3] = 2; +pair = sens_pair[chan]; +``` + +В Balsam 167 пары записываются по абсолютному индексу: + +```c +sens_pair[pow_addr+i] = pow_addr+(i^1); +``` + +Но чтение осталось старым: + +```c +pair = sens_pair[chan]; +``` + +Для силового блока элементы `sens_pair[0…3]` после общей инициализации равны +`0, 1, 2, 3`. Следовательно, `pair` указывает на текущий канал, а не на +соседний. + +Последствия: + +- один фазный уровень может записываться дважды; +- максимальная фаза выбирается из неполного набора; +- `Wry` может быть пропущен или сформирован ошибочно; +- карта `0x68…0x6D` для силового блока не соответствует ожидаемой. + +Вероятное исправление: + +```c +pair = sens_pair[sens] - pow_addr; +``` + +Окончательный вариант следует подтвердить стендовым тестом и ожидаемым +порядком фаз в регистрах. + +## 11. Пороговые уровни УМП + +Заводские уставки в проектах совпадают: + +| Сигнал | Нижний порог | Верхний порог | +|---|---:|---:| +| `Utr` | 300 В | 420 В | +| `Itr` | 800 А, предупреждение | 900 А, авария | + +Различается обработка нижнего напряжения: + +| Проект | Реакция `Utr < 300 В` | +|---|---| +| Balsam 165 | `Out` сразу; `Stop` блокируется при штатном `Ignor` | +| Balsam 167 | счётчик около 3 с, но при штатном `Ignor` проверка не выполняется | + +Верхний порог `Utr > 420 В` в обеих версиях не имеет отдельной выдержки и +гистерезиса. + +## 12. Диагностические биты + +Расположение основных битов не изменилось: + +| Бит | Маска | Имя | Назначение | +|---:|---:|---|---| +| 0 | `0x0001` | `Tear` | обрыв датчика/предельное значение АЦП | +| 2 | `0x0004` | `Wry` | перекос фаз | +| 3 | `0x0008` | `Out` | ниже нижнего порога | +| 4 | `0x0010` | `Over` | выше предупредительного порога | +| 5 | `0x0020` | `Hyper` | выше аварийного порога | +| 8 | `0x0100` | `Stop` | авария | +| 9 | `0x0200` | `Ready` | готовность | +| 14 | `0x4000` | `Ignor` | игнорировать аварию | +| 15 | `0x8000` | `Bypas` | отключить канал | + +В обеих версиях `Current_count()` не формирует `Tear` для фазных входов U/I. +Поэтому неисправность измерительного тракта нельзя надёжно отличить от +пропадания напряжения или тока. + +## 13. Что следует перенести из Balsam 165 + +В Balsam 167 полезно вернуть следующие свойства реализации 165: + +1. Согласованную систему индексов `sens_pair`. +2. Проверку `Ignor` через абсолютный индекс `sens_error[sens]`. +3. Использование `float` для внутренних фазных уровней до момента публикации. + +Не следует возвращать: + +- усреднение `fabs()` вместо RMS; +- общий статический фильтр `ffLev`; +- немедленное срабатывание нижнего напряжения; +- жёсткие коэффициенты `curK[]`. + +## 14. Рекомендуемая итоговая реализация + +1. Считать все абсолютные номера датчиков один раз: + + ```c + sens = pow_addr + chan; + ``` + +2. Хранить `sens_pair[]` либо полностью в относительных, либо полностью в + абсолютных индексах. Не смешивать системы адресации. +3. Сохранить RMS Balsam 167, но хранить `lev_count[]` как `float`. +4. После поступления обоих отсчётов пары вычислять A, C и B в одном месте. +5. Один раз за цикл обновлять три RMS и три диагностических счётчика. +6. Проверять `Max > Curr_Edge` до деления. +7. Проверять `Ignor` через `sens_error[sens]`. +8. Разделить понятия: + + - информационная ошибка присутствует; + - ошибка участвует в формировании `Stop`. + +9. Добавить отдельную маску фаз A/B/C. +10. Добавить `Tear` по сырому значению АЦП. +11. Добавить выдержку и гистерезис для 300/420 В. +12. Явно определить, должна ли подстройка нуля работать после запуска. + +## 15. Минимальные сравнительные тесты + +| Тест | Что проверить | +|---|---| +| Одинаковая синусоида на обеих версиях | Разницу MeanAbs и RMS около 11,1% | +| Номинальные A и C | Правильный порядок A/C/B в `0x68…0x6D` | +| Обрыв A | RMS A, `Wry`, выдержку | +| Обрыв C | RMS C, `Wry`, выдержку | +| Нарушение вычисленной B | Отсутствие двойной скорости счётчика | +| Перекос 20%, 25%, 30%, 35% | Различия порогов 165 и 167 | +| `Max == 0` | Отсутствие деления на ноль | +| `Utr = 299 В` | `Out` и выдержку | +| `Utr = 421 В` | `Hyper` и отсутствие дребезга | +| `Ignor = 1` | Ошибка видна, но не создаёт `Stop`, если это требуемая семантика | +| Силовой блок, две пары | Отсутствие дублирования фазных RMS | +| АЦП около 0 и 4095 | Формирование `Tear` | + +## Заключение + +Фазовый расчёт Balsam 167 является хорошей основой благодаря настоящему RMS, +раздельным фильтрам и калибровке из регистров. Главный риск версии 167 находится +не в математике RMS, а в адресации состояния каналов. + +До исправления `sens_pair` и `Ignor` фазные регистры и `Wry` силового блока +нельзя считать надёжными. Для УМП необходимо отдельно решить, должны ли +напряжения с установленным `Ignor` продолжать формировать информационные +`Wry`, `Out` и `Hyper`, как это происходило в Balsam 165. diff --git a/PHASE_VOLTAGE_CALCULATION.md b/PHASE_VOLTAGE_CALCULATION.md new file mode 100644 index 0000000..1437234 --- /dev/null +++ b/PHASE_VOLTAGE_CALCULATION.md @@ -0,0 +1,342 @@ +# Расчёт входных фаз, диагностика обрыва и уровни напряжения + +Документ составлен по исходникам прошивки Balsam 167 и карте регистров +`Doc/Balsam 167 data stru.xls`. + +## Где находится код + +Основная обработка входных напряжений и токов находится в +`Source/Internal/measure.c`: + +- `im_calc()` — восстановление амплитуды трёхфазного сигнала, строки 82–89; +- `Current_count()` — смещение АЦП, масштабирование, RMS фаз, общий уровень и + диагностика перекоса/пропадания, строки 444–614; +- `Power_count()` — контроль отдельных источников питания шкафа ВЭП, + строки 769–841; +- `er_anal()` — выдержка времени для диагностических признаков, + строки 423–432. + +Частота расчёта задаётся как `ADC_FREQ = 3750 Гц` в +`Source/Internal/Include/measure.h:73`. Выбор каналов АЦП выполняется в +`Source/Internal/ADC.c`, а пороги по умолчанию — в +`Source/Internal/message.c:24–135`. + +## 1. Получение входных отсчётов + +Для плат с измерением напряжения/тока обрабатываются четыре входа: + +| `chan` | Назначение для УМП (`dsk_LOAD`) | Сырой регистр | +|---:|---|---:| +| 0 | напряжение фазы A (`Utr A`) | `0x64` | +| 1 | напряжение фазы C (`Utr C`) | `0x65` | +| 2 | ток фазы A (`Itr A`) | `0x66` | +| 3 | ток фазы C (`Itr C`) | `0x67` | + +В `ADC.c:228–233` результат АЦП читается так: + +```c +adc_table_lem[i] = *((&AdcRegs.ADCRESULT0)+i+2) >> 4; +Current_count(i); +``` + +То есть используются 12 старших значащих бит результата АЦП. + +### Удаление нулевого смещения и перевод в физические единицы + +В `Current_count()` выполняется: + +```text +N = adc_table_lem[chan] +X = (N - Zero_lev[chan]) * powK[chan] +``` + +`Zero_lev[0..3]` хранится в регистрах `0x70…0x73`; значение по умолчанию — +`0x800 = 2048`. Ноль дополнительно подстраивается медленным фильтром: + +```text +zero[n] = zero[n-1] + (N - zero[n-1]) / (5 * 3750) +``` + +Коэффициент `powK` формируется из калибровки `Caliber[0..3]`: + +```text +для напряжения: powK = Caliber / 10000 +для тока: powK = Caliber / 1000 +``` + +Калибровочные значения находятся в Modbus-регистрах `0x74…0x77`, могут быть +загружены из EEPROM и поэтому не обязаны совпадать со значениями по умолчанию. + +Для Balsam 167 значения по умолчанию такие: + +| Устройство | Каналы | `Caliber` | `powK` | +|---|---|---|---| +| Силовой 1, адрес 3 | `UA1, UB1, UA2, UB2` | `4936, 4877, 4972, 4857` | `0.4936, 0.4877, 0.4972, 0.4857` | +| Силовой 2, адрес 4 | `UA1, UB1, UA2, UB2` | `4876, 5005, 4876, 4847` | `0.4876, 0.5005, 0.4876, 0.4847` | +| УМП 1, адрес 5 | `Utr A, Utr C, Itr A, Itr C` | `3820, 3790, 3505, 3380` | `0.3820, 0.3790, 3.505, 3.380` | +| УМП 2, адрес 6 | `Utr A, Utr C, Itr A, Itr C` | `3835, 3785, 3522, 3332` | `0.3835, 0.3785, 3.522, 3.332` | + +Источник значений: `Source/Internal/Include/caliber.h`, секция +`#if BALSAM == 167`. + +## 2. Расчёт амплитуды и действующего значения + +Функция `im_calc(a, b)` использует два измеренных фазных сигнала: + +```text +isA = -1.5 * (a + b) +isB = cos(π/6) * (a - b) +Amplitude = 2/3 * sqrt(isA² + isB²) +``` + +Эквивалентная свёрнутая формула: + +```text +Amplitude = 2/sqrt(3) * sqrt(a² + a*b + b²) +``` + +После цифрового фильтра Баттерворта 3 Гц получается амплитуда сигнала. +Действующее значение вычисляется как: + +```text +Level = Amplitude / sqrt(2) +``` + +Для каналов напряжения амплитуда принудительно обнуляется при +`Amplitude < 20`; для каналов тока — при `Amplitude < 75`. + +Результат пары записывается в два регистра данных: + +```text +sens_data[нечётный канал] = Amplitude +sens_data[чётный канал] = Level +``` + +Для УМП это даёт: + +| Регистр | Значение | +|---:|---| +| `0x18` | действующее `Utr` | +| `0x19` | амплитудное `Utr` | +| `0x1A` | действующее `Itr` | +| `0x1B` | амплитудное `Itr` | + +Для силового блока адреса данных сдвинуты из-за температурных каналов: +`0x28/0x29` — действующее/амплитудное `Uвх1`, `0x2A/0x2B` — +действующее/амплитудное `Uвх2`. + +## 3. Действующие значения отдельных фаз + +Для каждой пары измеряются две фазы, третья восстанавливается по условию +трёхпроводной системы: + +```text +x3 = -x1 - x2 +``` + +Для каждого из трёх сигналов считается скользящее среднеквадратичное значение: + +```text +Qphase[n] = Qphase[n-1] + (xphase² - Qphase[n-1]) / 3750 +RMSphase = sqrt(Qphase) +``` + +`lev_count[]` имеет тип `int`, поэтому сохранённый RMS усекается до целого. + +Карта регистров фаз для УМП: + +| Регистр | Пара входов | Значение | +|---:|---|---| +| `0x68` | напряжение | RMS фазы A (`Utr A`) | +| `0x69` | напряжение | RMS фазы C (`Utr C`) | +| `0x6A` | напряжение | RMS восстановленной фазы B (`Utr B`) | +| `0x6B` | ток | RMS фазы A (`Itr A`) | +| `0x6C` | ток | RMS фазы C (`Itr C`) | +| `0x6D` | ток | RMS восстановленной фазы B (`Itr B`) | + +В коде назначение пары определяется как `feed = chan >> 1`, а начальный адрес +фазных уровней — как `0x68 + feed * 3`. + +## 4. Диагностика обрыва или сильного перекоса фазы + +Отдельных битов «обрыв фазы A», «обрыв фазы B» и «обрыв фазы C» в прошивке +нет. Есть общий признак сильного отличия одной из трёх фаз — `Wry`. +Конкретную пропавшую фазу надо определять по минимальному значению среди +регистров `0x68…0x6A` или `0x6B…0x6D`. + +Алгоритм в `Current_count()`: + +```text +Max = max(RMS_A, RMS_B, RMS_C) + +перекос фазы = ((Max - RMS_phase) / Max > 0.30) AND (Max > Curr_Edge) +``` + +Условие проходит через реверсивный счётчик `er_anal()`: при наличии ошибки он +увеличивается, а при исчезновении уменьшается, но не сбрасывается сразу. Порог +для измеряемой фазы равен примерно 3 секундам +(`time_3sec = 3 * ADC_FREQ = 11250` отсчётов). Для восстановленной фазы один и +тот же счётчик вызывается из обоих каналов пары, поэтому при постоянной ошибке +порог фактически достигается примерно вдвое быстрее — около 1,5 секунды. +После достижения порога устанавливаются: + +| Бит диагностического слова | Маска | Имя | Значение | +|---:|---:|---|---| +| 2 | `0x0004` | `Wry` | перекос/пропадание одной из фаз более чем на 30% от максимальной | +| 8 | `0x0100` | `Stop` | авария, устанавливается вместе с `Wry` | + +Для УМП `Curr_Edge = 300`. Поэтому фазовая диагностика не работает при +`Max <= 300` и не реагирует на слабый сигнал/шум около нуля. + +Диагностические слова УМП: + +| Регистр | Канал | +|---:|---| +| `0x00` | `Utr A` | +| `0x01` | `Utr C` | +| `0x02` | `Itr A` | +| `0x03` | `Itr C` | + +При одиночном пропадании фаз ожидается следующая комбинация: + +| Пропавшая фаза | Напряжение | Ток | +|---|---|---| +| A | `0x00.Wry` | `0x02.Wry` | +| C | `0x01.Wry` | `0x03.Wry` | +| B, восстановленная | `0x00.Wry` и `0x01.Wry` | `0x02.Wry` и `0x03.Wry` | + +Вместе с каждым `Wry` ставится `Stop`. Эта комбинация выведена из порядка +проверок в коде, но при сложном перекосе она неоднозначна. Надёжнее определять +проблемную фазу по тройке RMS-регистров. + +В месте чтения Modbus признаки можно проверять масками: + +```c +// Напряжение УМП +bool phase_a_fault = (modbus[0x00] & 0x0004) != 0; +bool phase_c_fault = (modbus[0x01] & 0x0004) != 0; +bool voltage_stop = ((modbus[0x00] | modbus[0x01]) & 0x0100) != 0; + +// Ток УМП +bool current_a_fault = (modbus[0x02] & 0x0004) != 0; +bool current_c_fault = (modbus[0x03] & 0x0004) != 0; +bool current_stop = ((modbus[0x02] | modbus[0x03]) & 0x0100) != 0; +``` + +Названия `phase_a_fault` и `phase_c_fault` здесь условные: каждый `Wry` также +участвует в контроле восстановленной фазы B. Для точной индикации следует +сравнить сами уровни `0x68…0x6D`. + +### Другие связанные биты диагностики + +Структура диагностического слова задана в +`Source/Internal/Include/measure.h:19–46`: + +| Бит | Маска | Имя | Назначение | +|---:|---:|---|---| +| 0 | `0x0001` | `Tear` | обрыв датчика/крайнее значение АЦП; в фазовом расчёте не формируется | +| 2 | `0x0004` | `Wry` | перекос парных датчиков/фаз | +| 3 | `0x0008` | `Out` | уровень ниже нижней уставки | +| 4 | `0x0010` | `Over` | уровень выше предупредительной уставки | +| 5 | `0x0020` | `Hyper` | уровень выше аварийной верхней уставки | +| 6 | `0x0040` | `Contr` | нет сигнала на одном из дискретных входов контроля | +| 8 | `0x0100` | `Stop` | аварийный останов | +| 9 | `0x0200` | `Ready` | готовность, равна `!Stop` | +| 10–13 | `0x0400…0x2000` | `Discr1…Discr4` | отдельные дискретные входы контроля | +| 14 | `0x4000` | `Ignor` | игнорировать диагностику | +| 15 | `0x8000` | `Bypas` | отключить канал | + +`reset_errs()` сохраняет управляющие биты 13–15 маской `NOER = 0xE000`, +добавляет вычисленные ошибки и каждый цикл формирует `Ready = !Stop`. + +## 5. Уровни напряжения УМП + +Проверка уровня выполняется только после расчёта общей амплитуды/RMS пары и +только для нечётного канала пары (`Current_count():569–591`). + +### Входное напряжение `Utr` + +| Условие | Выдержка | Устанавливаемые биты | +|---|---:|---| +| `Level < 300 В` | около 3 с | `Out` (бит 3) + `Stop` (бит 8) | +| `Level > 420 В` | без отдельной выдержки | `Hyper` (бит 5) + `Stop` (бит 8) | + +Уставки находятся в `sens_lo_edge[0/1]` (Modbus `0x48/0x49`) и +`sens_hi_edge[0/1]` (Modbus `0x30/0x31`). Значения выше — заводские; записью +по Modbus или загрузкой EEPROM они могут быть изменены. + +### Ток `Itr` + +Для полноты связанной логики: + +| Условие | Биты | +|---|---| +| `Level > 800 А` | `Over` (бит 4), предупреждение | +| `Level > 900 А` | `Hyper` (бит 5) + `Stop` (бит 8) | + +## 6. Контроль напряжений шкафа ВЭП (`Power_count`) + +На плате шкафа каждый канал масштабируется напрямую: + +```text +Power = ADC_table[chan] * powK[sens_type[chan]] +``` + +Коэффициенты заданы в `measure.c:52–65`: `0.127` для каналов 380 В и +`0.0076` для низковольтных каналов. + +Нижние уровни по умолчанию: + +| Каналы | Контролируемое напряжение | Нижний уровень | +|---:|---|---:| +| 0, 1 | 380 В, фидеры 1 и 2 | 300 В | +| 2, 3 | 31 В, фидеры 1 и 2 | 15 В | +| 4, 5 | 31 В UC, фидеры 1 и 2 | 15 В | +| 6 | 24 В ПУ | 20 В | +| 7 | 27 В ФА | 22 В | +| 8 | 24 В ПК | 20 В | +| 9 | 15 В ДР | 10 В | +| 10 | +24 В ДТ | 20 В | +| 11 | −24 В ДТ | 20 В по модулю измеряемого значения | +| 12 | 24 В ПМУ | 20 В | + +Если `Power < sens_lo_edge[chan]`, ставится `Out` (бит 3). `Stop` (бит 8) +ставится, когда `Out` уже установлен и у парного канала. Пары заданы как +`0↔1`, `2↔3`, `4↔5`; одиночные каналы спарены сами с собой. Поэтому для +двухфидерных источников аварийный останов означает пропадание обоих фидеров, +а пропадание одного фидера даёт только `Out` в его диагностическом слове. + +Проверка превышения верхней уставки в `Power_count():829–835` закомментирована +и фактически не выполняется. + +## 7. Особенности текущей реализации + +1. На силовых блоках (`dsk_COMM`) четырём каналам назначается `Ignor` по + абсолютным индексам `pow_addr…pow_addr+3` (`measure.c:359–365`), но проверка + в `Current_count()` обращается к `sens_error[chan].Ignor`. Из-за разных + индексов назначенный `Ignor` может не отключать фазовую диагностику. +2. В `Current_count()` используется `pair = sens_pair[chan]`, тогда как для + силового блока пары инициализируются по абсолютному индексу + `sens_pair[pow_addr + chan]`. Для УМП, где `pow_addr == 0`, это работает как + задумано. На силовом блоке индекс `pair` остаётся равен текущему `chan`, что + может дублировать один фазовый RMS вместо чтения парного канала. +3. Следствие двух ошибок индексации: на силовом блоке `Wry` может формироваться, + хотя для канала выставлен `Ignor`, и опираться на неверно сопоставленные + фазовые уровни. Эту часть логики нельзя считать надёжной без исправления или + стендовой проверки. +4. В выражении перекоса деление на `Max` записано раньше проверки + `Max > Curr_Edge`. При `Max == 0` сначала вычисляется деление `0/0`. + Безопаснее сначала проверять порог, затем выполнять деление. +5. Все публикуемые значения и пороги хранятся в 16-битных регистрах как целые числа; + дробная часть после вычислений отбрасывается. + +## Краткий итог + +- Фазы: два сигнала измеряются, третий восстанавливается как `-x1-x2`. +- RMS каждой фазы: корень из экспоненциально усреднённого квадрата. +- Общий RMS входа: амплитуда `im_calc()` после фильтра, делённая на `sqrt(2)`. +- Обрыв/перекос одной фазы: `Wry`, бит 2; авария: `Stop`, бит 8. +- Определение конкретной фазы: по минимальному из трёх RMS-регистров, отдельного + фазового бита нет. +- Низкое `Utr`: ниже 300 В около 3 секунд — `Out + Stop`. +- Высокое `Utr`: выше 420 В — `Hyper + Stop`. diff --git a/PHASE_VOLTAGE_WEAK_POINTS.md b/PHASE_VOLTAGE_WEAK_POINTS.md new file mode 100644 index 0000000..0bd81e3 --- /dev/null +++ b/PHASE_VOLTAGE_WEAK_POINTS.md @@ -0,0 +1,287 @@ +# Слабые места расчёта фаз и контроля напряжения + +Документ относится к алгоритмам из `Source/Internal/measure.c`, структуре +диагностики из `Source/Internal/Include/measure.h` и карте регистров +`Doc/Balsam 167 data stru.xls`. + +## Критические проблемы + +### 1. Неверная индексация парного канала на силовом блоке + +В `Current_count()` используется: + +```c +pair = sens_pair[chan]; +``` + +При этом пары каналов инициализируются по абсолютному адресу: + +```c +sens_pair[pow_addr+i] = pow_addr+(i^1); +``` + +Для УМП `pow_addr == 0`, поэтому ошибка не проявляется. На силовом блоке +`pow_addr != 0`, и `sens_pair[chan]` остаётся равным самому `chan`. + +Последствия: + +- вместо парного фазового RMS может использоваться текущий канал; +- регистры `0x68…0x6D` могут содержать дублирующиеся значения; +- расчёт максимальной фазы и диагностика `Wry` могут быть неверными. + +Рекомендуемое исправление требует определить, в какой системе индексов должен +работать `lev_count[]`. Вероятный вариант: + +```c +pair = sens_pair[sens] - pow_addr; +``` + +Перед изменением необходимо проверить ожидаемую карту каналов на силовом блоке. + +### 2. Бит `Ignor` проверяется по неверному индексу + +В `Init_sensors_more()` бит устанавливается так: + +```c +Modbus[pow_addr+i].bit.bitE = 1; +``` + +Но в `Current_count()` проверяется: + +```c +if (WAKE || sens_error[chan].bit.Ignor) goto fin; +``` + +Следует проверять диагностическое слово текущего датчика: + +```c +if (WAKE || sens_error[sens].bit.Ignor) goto fin; +``` + +Последствие текущего кода: `Wry` может формироваться для канала, который должен +быть исключён из диагностики. + +### 3. Деление на ноль в расчёте перекоса + +Текущее условие: + +```c +((Numb - lev_count[chan]) / Numb > 0.3) && (Numb > Curr_Edge) +``` + +Левая часть вычисляется раньше проверки `Numb > Curr_Edge`. При `Numb == 0` +сначала выполняется деление `0/0`. + +Безопасный порядок: + +```c +(Numb > Curr_Edge) && +(((Numb - lev_count[chan]) / Numb) > 0.3) +``` + +Такое же изменение требуется для проверки `lev_count[thrd]`. + +## Высокий приоритет + +### 4. Нет независимых признаков обрыва фаз A, B и C + +Прошивка формирует общий бит: + +| Бит | Маска | Имя | +|---:|---:|---| +| 2 | `0x0004` | `Wry` | + +Отдельных битов `PhaseA`, `PhaseB`, `PhaseC` нет. Конкретная фаза определяется +косвенно по RMS-регистрам `0x68…0x6D`. + +Фаза B физически не измеряется и восстанавливается: + +```text +B = -A - C +``` + +Из-за этого повреждение фазы B не всегда можно однозначно отличить от +изменения измеряемых фаз A и C. + +Рекомендуется формировать отдельную маску состояния фаз, например: + +| Бит | Назначение | +|---:|---| +| 0 | низкий RMS фазы A | +| 1 | низкий RMS фазы B | +| 2 | низкий RMS фазы C | +| 3 | общий перекос фаз | + +### 5. Выдержка восстановленной фазы примерно вдвое короче + +Для восстановленной фазы используется `err_count[thrd]`. Одна и та же ячейка +счётчика проверяется при обработке обоих каналов пары. Поэтому она может +увеличиваться два раза за один цикл АЦП. + +Ожидаемое время: + +```text +11250 / 3750 = 3 секунды +``` + +Фактическое время для восстановленной фазы при двух вызовах за цикл: + +```text +11250 / (2 * 3750) ≈ 1,5 секунды +``` + +Рекомендуется выполнять проверку всех трёх фаз один раз после обновления всей +пары каналов. + +### 6. Для входов U/I не формируется `Tear` + +Бит `Tear` объявлен как бит 0 диагностического слова, но `Current_count()` его +не устанавливает. Нет отдельной проверки АЦП на значения около 0 или 4095. + +Последствия: + +- обрыв или короткое замыкание измерительного тракта может выглядеть как + обычное отсутствие напряжения; +- невозможно отличить пропадание сети от неисправности самого датчика. + +Рекомендуется добавить контроль сырого значения АЦП с выдержкой времени и +отдельными порогами около нижней и верхней границ диапазона. + +### 7. Подстройка нуля продолжается после запуска + +Ноль обновляется при условии: + +```c +if (WAKE < (WAKE_TIME / 2)) Zero_lev[chan] = Zer; +``` + +`WAKE` уменьшается до нуля. После запуска выражение `0 < WAKE_TIME/2` остаётся +истинным, поэтому `Zero_lev` продолжает изменяться во время работы. + +Риск: медленная постоянная составляющая или неисправность входа может частично +компенсироваться алгоритмом нуля. + +Если подстройка нужна только при запуске, условие должно ограничивать окно: + +```c +if ((WAKE > 0) && (WAKE < (WAKE_TIME / 2))) { + Zero_lev[chan] = Zer; +} +``` + +Если непрерывная подстройка задумана, её следует явно документировать и +ограничить допустимым диапазоном изменения. + +## Средний приоритет + +### 8. Жёсткая зона нечувствительности + +Для напряжения применяется: + +```c +if (Amplitude < 20) Amplitude = 0; +``` + +Для тока применяется порог 75. Реальный слабый сигнал ниже порога становится +неотличим от полного отсутствия сигнала. + +Рекомендуется использовать отдельные пороги включения и выключения +(гистерезис), а также сохранить необрезанное диагностическое значение. + +### 9. Несимметричная запись ошибок пары + +Проверки общего уровня `Level` выполняются только при `!ist`, то есть в +нечётном канале пары. Поэтому `Out` и `Hyper` записываются только в одно из двух +диагностических слов. + +Например, для напряжения УМП низкий общий уровень записывается в `0x01`, хотя +само измерение относится ко всей трёхфазной системе. + +Рекомендуется выделить отдельное диагностическое слово системы или явно +дублировать общий признак в оба слова пары. + +### 10. Контроль перенапряжения шкафа ВЭП отключён + +В `Power_count()` проверка: + +```c +if (Power > sens_hi_edge[chan]) +``` + +закомментирована. В рабочем коде контролируется только падение напряжения. +Неисправность с повышением напряжения не создаёт `Hyper` и `Stop`. + +Перед включением проверки необходимо задать и проверить верхние уставки для +всех типов источников питания. + +### 11. Недостаточный гистерезис порогов + +Верхний порог `Utr > 420 В` проверяется непосредственно, без отдельного +счётчика и без порога возврата. При шуме около 420 В диагностический бит может +часто переключаться. + +Для нижнего порога используется реверсивный счётчик, но состояние также не +имеет явно заданных разных порогов срабатывания и возврата. + +Рекомендуется добавить: + +- выдержку времени для перенапряжения; +- разные пороги срабатывания и возврата; +- насыщение и явный сброс диагностических счётчиков. + +### 12. Потеря дробной части RMS + +`lev_count[]` и Modbus-регистры имеют целочисленный тип. Результат `sqrt()` +сохраняется с отбрасыванием дробной части. + +Для текущих порогов в сотнях вольт это не критично, но ухудшает точность +индикации и поведение около границы. При необходимости можно передавать +значения в десятых долях единицы. + +## Дополнительные риски + +### Разная задержка аварии у парных источников + +В `Power_count()` бит `Stop` устанавливается, если `Out` уже присутствует у +парного канала. Из-за последовательной обработки второй канал пары может +получить `Stop` раньше первого. Первый получит его только при следующем опросе. + +### Одиночный источник спарен сам с собой + +Для непарных источников `sens_pair[chan] == chan`. После первого обнаружения +`Out` бит `Stop` появится при следующем вызове, когда будет прочитано собственное +предыдущее состояние `Out`. Это неочевидная зависимость от предыдущего цикла. + +### Уставки доступны для записи без локальной проверки диапазона + +Команда Modbus записывает переданное значение непосредственно в массив +регистров. В расчёте не видно проверки допустимого диапазона порогов. Ошибочная +уставка может полностью отключить контроль или вызвать постоянную аварию. + +## Рекомендуемый порядок исправлений + +1. Исправить индексацию `sens_pair` и `sens_error[].Ignor`. +2. Переставить проверку `Numb > Curr_Edge` перед делением. +3. Перенести расчёт и диагностику трёх фаз в один вызов на пару каналов. +4. Добавить отдельные признаки состояния фаз A/B/C. +5. Добавить диагностику предельных значений АЦП (`Tear`). +6. Определить требуемый режим подстройки нуля и ограничить его. +7. Добавить выдержку и гистерезис верхнего/нижнего напряжения. +8. Проверить все изменения стендовыми тестами: нормальная сеть, обрыв каждой + фазы, перекос, пропадание обоих фидеров, пониженное и повышенное напряжение. + +## Минимальный набор тестов + +| Тест | Ожидаемый результат | +|---|---| +| Номинальное трёхфазное напряжение | `Wry=0`, `Out=0`, `Hyper=0`, `Stop=0` | +| Обрыв измеряемой фазы A | снижение RMS A, отдельный признак A, затем `Stop` | +| Обрыв измеряемой фазы C | снижение RMS C, отдельный признак C, затем `Stop` | +| Нарушение восстановленной фазы B | снижение вычисленного RMS B без двойной скорости счётчика | +| Перекос ровно 30% | проверка граничного условия `>` | +| `Max = 0` | отсутствие деления на ноль | +| `Utr < 300 В` | `Out`, после выдержки `Stop` | +| `Utr > 420 В` | `Hyper`, после заданной выдержки `Stop` | +| АЦП около 0 или 4095 | `Tear`, отличие от пропадания сети | +| Канал с `Ignor=1` | отсутствие новых автоматических ошибок этого канала | +| Отключённый канал `Bypas=1` | нулевые данные, сохранён только `Bypas` | diff --git a/README_CCS12.md b/README_CCS12.md new file mode 100644 index 0000000..84c5a65 --- /dev/null +++ b/README_CCS12.md @@ -0,0 +1,29 @@ +# Сборка проекта в Code Composer Studio 12 + +Проект поддерживает обе IDE параллельно: + +- CCS 3 использует корневой файл `UKSSTMS320F28335.pjt`; +- CCS 12 использует проект из каталога `UKSSTMS320F28335`. + +Файлы CCS 3 не изменялись. Объектные файлы и итоговые образы двух систем +сборки разнесены по разным каталогам и не перезаписывают друг друга. + +## Импорт + +1. Откройте **File → Import → Code Composer Studio → CCS Projects**. +2. В **Select search-directory** укажите каталог репозитория. +3. Выберите проект **UKSSTMS320F28335** и нажмите **Finish**. +4. Выберите конфигурацию **Debug** или **Release** и выполните **Build Project**. + +Проект настроен для `TMS320F28335`, COFF ABI и C2000 Compiler +`22.6.0.LTS`, входящего в CCS 12.3. + +## Результаты сборки + +- CCS 3 продолжает использовать прежние каталоги `Debug`, `Release` и `Bin`. +- CCS 12 Debug создаёт `.out`, `.hex`, `.bin` и `.map` в `Bin/CCS12`. +- CCS 12 Release создаёт `UKSSTMS320F28335_Release.out` и + `UKSSTMS320F28335_Release.map` в `Bin/CCS12`. + +Все пути к исходникам заданы относительно каталога проекта через `SRC_ROOT`; +перенос репозитория в другой каталог не требует изменения настроек. diff --git a/UKSSTMS320F28335/.ccsproject b/UKSSTMS320F28335/.ccsproject index 269c339..ee2d31d 100644 --- a/UKSSTMS320F28335/.ccsproject +++ b/UKSSTMS320F28335/.ccsproject @@ -2,9 +2,9 @@ - + - + diff --git a/UKSSTMS320F28335/.cproject b/UKSSTMS320F28335/.cproject index e7b4248..32344c9 100644 --- a/UKSSTMS320F28335/.cproject +++ b/UKSSTMS320F28335/.cproject @@ -1,193 +1,82 @@ - + - - + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -200,162 +89,72 @@ - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -364,10 +163,9 @@ - + - - \ No newline at end of file + diff --git a/UKSSTMS320F28335/.gitignore b/UKSSTMS320F28335/.gitignore index 6d4a3d8..c744cf6 100644 --- a/UKSSTMS320F28335/.gitignore +++ b/UKSSTMS320F28335/.gitignore @@ -3,3 +3,4 @@ /.launches/ /targetConfigs/ /project.log +/Release/ diff --git a/UKSSTMS320F28335/.settings/org.eclipse.core.resources.prefs b/UKSSTMS320F28335/.settings/org.eclipse.core.resources.prefs index 5dbaf64..07cfcde 100644 --- a/UKSSTMS320F28335/.settings/org.eclipse.core.resources.prefs +++ b/UKSSTMS320F28335/.settings/org.eclipse.core.resources.prefs @@ -14,3 +14,18 @@ encoding//Debug/objects.mk=UTF-8 encoding//Debug/sources.mk=UTF-8 encoding//Debug/subdir_rules.mk=UTF-8 encoding//Debug/subdir_vars.mk=UTF-8 +encoding//Release/Libraries/subdir_rules.mk=UTF-8 +encoding//Release/Libraries/subdir_vars.mk=UTF-8 +encoding//Release/Source/External/v120/DSP2833x_common/source/subdir_rules.mk=UTF-8 +encoding//Release/Source/External/v120/DSP2833x_common/source/subdir_vars.mk=UTF-8 +encoding//Release/Source/External/v120/DSP2833x_headers/cmd/subdir_rules.mk=UTF-8 +encoding//Release/Source/External/v120/DSP2833x_headers/cmd/subdir_vars.mk=UTF-8 +encoding//Release/Source/External/v120/DSP2833x_headers/source/subdir_rules.mk=UTF-8 +encoding//Release/Source/External/v120/DSP2833x_headers/source/subdir_vars.mk=UTF-8 +encoding//Release/Source/Internal/subdir_rules.mk=UTF-8 +encoding//Release/Source/Internal/subdir_vars.mk=UTF-8 +encoding//Release/makefile=UTF-8 +encoding//Release/objects.mk=UTF-8 +encoding//Release/sources.mk=UTF-8 +encoding//Release/subdir_rules.mk=UTF-8 +encoding//Release/subdir_vars.mk=UTF-8 diff --git a/UKSSTMS320F28335/postBuildStep_Debug.bat b/UKSSTMS320F28335/postBuildStep_Debug.bat index a054feb..bbbe0d4 100644 --- a/UKSSTMS320F28335/postBuildStep_Debug.bat +++ b/UKSSTMS320F28335/postBuildStep_Debug.bat @@ -1,34 +1,14 @@ @echo off setlocal -for %%I in ("%~dp0..") do set "SRC_ROOT=%%~fI" +set "HEX_TOOL=%~1" +set "OUT_FILE=%~2" +set "BIN_DIR=%~3" -:process_arg -if "%1"=="" goto end_process_arg -set name=%1 -set value= +if not exist "%BIN_DIR%" mkdir "%BIN_DIR%" -:process_arg_value -if NOT "%value%"=="" set value=%value% %2 -if "%value%"=="" set value=%2 -shift -if "%2"=="!" goto set_arg -if "%2"=="" goto set_arg -goto process_arg_value +"%HEX_TOOL%" "%OUT_FILE%" -boot -sci8 -map "%BIN_DIR%\UKSSTMS320F28335.map" -o "%BIN_DIR%\UKSSTMS320F28335.hex" -i +if errorlevel 1 exit /b %errorlevel% -:set_arg -set %name%=%value% -shift -shift -goto process_arg -:end_process_arg - -echo. > temp_postBuildStep_Debug.bat - -echo "%SRC_ROOT%\Bin\hex2000.exe" "%SRC_ROOT%\Bin\UKSSTMS320F28335.out" -boot -sci8 -map "%SRC_ROOT%\Bin\UKSSTMS320F28335.map" -o "%SRC_ROOT%\Bin\UKSSTMS320F28335.hex" -i >> temp_postBuildStep_Debug.bat -echo "%SRC_ROOT%\Bin\hex2000.exe" "%SRC_ROOT%\Bin\UKSSTMS320F28335.out" -boot -sci8 -map "%SRC_ROOT%\Bin\UKSSTMS320F28335.map" -o "%SRC_ROOT%\Bin\UKSSTMS320F28335.bin" -b >> temp_postBuildStep_Debug.bat - -call temp_postBuildStep_Debug.bat -del temp_postBuildStep_Debug.bat - -endlocal +"%HEX_TOOL%" "%OUT_FILE%" -boot -sci8 -map "%BIN_DIR%\UKSSTMS320F28335.map" -o "%BIN_DIR%\UKSSTMS320F28335.bin" -b +exit /b %errorlevel%