Update CCS12 peripheral firmware and documentation

This commit is contained in:
2026-09-04 19:34:10 +03:00
parent 55bee25b4f
commit 8cd81736cf
56 changed files with 3808 additions and 504 deletions

View File

@@ -1,3 +1,13 @@
/**
* @file ADC.c
* @brief Сбор аналоговых отсчётов и первичная обработка измерительных каналов.
*
* Модуль настраивает АЦП TMS320F28335 и обслуживает прерывание окончания
* преобразования. Отсчёты накапливаются в ADC_table и adc_table_lem, после
* чего передаются измерительному контуру. Обработчик работает в контексте
* прерывания, поэтому его время выполнения ограничено частотой дискретизации,
* а разделяемые таблицы должны читаться основным циклом согласованно.
*/
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP281x Examples Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"
@@ -14,20 +24,37 @@
#include "peripher.h"
/** @brief Сырые отсчёты четырёх силовых каналов, передаваемые Current_count(). */
Uint16 adc_table_lem[4];
Uint16 ADC_table[28]; // Ïîòîìó ÷òî +4 êàëèáð
/** @brief Фильтрованные значения всех рабочих и калибровочных каналов. */
Uint16 ADC_table[28]; // Потому что +4 калибр
/** @brief Число допустимых отсчётов прошлого окна для контроля выбросов. */
Uint16 prev_ok[28];
/** @brief Параметры временного мультиплексирования термоканалов в тиках АЦП. */
unsigned int COUNT_ONE_CANAL;
unsigned int COUNT_DISCHARGE;
unsigned int COUNT_TRANSICIA;
unsigned int FILTER_CLIP;
/** @brief Счётчик прогрева измерений и его начальная длительность. */
long WAKE, WAKE_TIME;
// Prototype statements for functions found within this file.
/** @brief ISR конца последовательности ADC SEQ1. */
interrupt void adc_isr(void);
/**
* @brief Полностью настраивает АЦП, ePWM-триггер и расписание каналов платы.
*
* @details По Desk выбирается физическая последовательность входов ADCINA/B.
* ePWM1 затем запускает SEQ1 с частотой ADC_FREQ. Для мультиплексированных
* термоканалов рассчитываются интервалы разряда, переходного процесса и окна
* накопления; WAKE подавляет использование неустановившихся фильтров при старте.
*
* @pre Desk и признаки TermoAD/TermoSW определены функцией get_Mode().
* @post ADCINT подключён к adc_isr(), SEQ1 и ePWM1 запущены.
*/
void setup_adc()
{
long CLKdiv,HSPCLKdiv,Rate;
@@ -59,21 +86,23 @@ void setup_adc()
// EINT; // Enable Global interrupt INTM
// ERTM; // Enable Global realtime interrupt DBGM
/* Исключаем использование остаточных данных до первого полного цикла АЦП. */
for(i=0;i<28;i++)
ADC_table[i]=
prev_ok[i] = 0;
/* Каждая роль платы имеет собственную разводку входов и длину sequencer. */
// Configure ADC
if(Desk==dsk_LOAD)
{
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0005; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // òåìïåðàòóðà (êîòîðîé íåò)
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // îìåãà
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x5; // íàïðóãà 1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x4; // íàïðóãà 2
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7; // òîê 1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x2; // òîê 2
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // температура (которой нет)
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // омега
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x5; // напруга 1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x4; // напруга 2
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7; // ток 1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x2; // ток 2
}
if(Desk==dsk_BKST)
@@ -87,7 +116,7 @@ void setup_adc()
if(Desk==dsk_COMM)
{
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0006; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // ñíà÷àëà òîæå áóäóò òåìïåðàòóðû
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // сначала тоже будут температуры
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x4; // Setup ADCINA2 as 2nd SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x7; // Setup ADCINA2 as 2nd SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
@@ -105,23 +134,23 @@ void setup_adc()
if(Desk==dsk_SHKF)
{
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x000F; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // 380Â Ô1
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // 380Â Ô2
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x6; // 31Â Ô1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0xC; // 31Â Ô2 ?
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xA; // 31Â UC1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0xB; // 31Â UC2
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7; // 24Â ÏÓ
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x4; // 24Â ÏÓ
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // 380В Ф1
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // 380В Ф2
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x6; // 31В Ф1
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0xC; // 31В Ф2 ?
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xA; // 31В UC1
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0xB; // 31В UC2
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7; // 24В ПУ
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x4; // 24В ПУ
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x5; // 24Â ÏÊ áûëî 5
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1; // 15Â Äð
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xE; // +24Â Äò
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0; // +24Â Äò
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x8; // -24Â Äò áûëî 8
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x5; // 24В ПК было 5
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1; // 15В Др
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xE; // +24В Дт
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0; // +24В Дт
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x8; // -24В Дт было 8
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xF;//0xF; // ÄÒ° 1
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xD;//0xD; // ÄÒ° 2
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xF;//0xF; // ДТ° 1
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xD;//0xD; // ДТ° 2
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0x9;//0x9;
}
@@ -152,6 +181,7 @@ void setup_adc()
if(EPwm1Regs.TBCTL.bit.HSPCLKDIV) HSPCLKdiv = 2*EPwm1Regs.TBCTL.bit.HSPCLKDIV;
else HSPCLKdiv = 1;
/* Период ePWM получается из реальной частоты TBCLK после обоих делителей. */
Rate = (SYSCLKOUT/(HSPCLKdiv*CLKdiv))/ADC_FREQ;
EPwm1Regs.TBPRD = Rate; // Set period for ePWM1
@@ -195,6 +225,18 @@ void setup_adc()
WAKE = WAKE_TIME;
}
/**
* @brief Забирает результаты SEQ1, фильтрует их и запускает расчёт величин.
*
* @details Сначала разрешает вложенные прерывания согласно программному
* приоритету PIE. В зависимости от аппаратной роли обрабатывает силовые каналы,
* нагрузочный аналоговый вход, шкафные каналы либо мультиплексированные
* термодатчики. Выброс принимается только при прохождении FILTER_CLIP; во время
* WAKE фильтр обучается, но наружу выдаётся непосредственный отсчёт.
*
* @note На общем выходе fin всегда сбрасывает SEQ1, подтверждает PIE и
* восстанавливает сохранённую маску PIEIER1, включая путь раннего выхода.
*/
interrupt void adc_isr(void)
{
static int cownt_one_canal=0;
@@ -214,6 +256,7 @@ interrupt void adc_isr(void)
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
EINT;
/* До READY обслуживается только обязательное завершение аппаратного цикла. */
if(WAKE) WAKE--;
if(!READY) goto fin;
@@ -246,7 +289,7 @@ interrupt void adc_isr(void)
{
if (++cownt_cans>=tpl_cans) cownt_cans=0;
// Èìåííî çäåñü íåò äûð
// Именно здесь нет дыр
// if(sens_type[cownt_cans])
{
i++;
@@ -256,6 +299,7 @@ interrupt void adc_isr(void)
else Power_count(cownt_cans);
} } }
/* Программный мультиплексор: переключение, выдержка, накопление и расчёт. */
if(TermoSW)
{
if(cownt_one_canal==COUNT_DISCHARGE)
@@ -265,11 +309,12 @@ interrupt void adc_isr(void)
if(TermoAD)
{
if(cownt_cans == TPL_CANS ) code_tpl_canal = TERMOPAIR-1;
if(cownt_cans == TPL_CANS+1) code_tpl_canal = TERMOPAIR-2; // ïîòîìó ÷òî 300 è 400 íàîáîðîò
if(cownt_cans == TPL_CANS+1) code_tpl_canal = TERMOPAIR-2; // потому что 300 и 400 наоборот
}
select_tpl_canal(code_tpl_canal);
}
/* Отсчёты до окончания переходного процесса намеренно отбрасываются. */
if(cownt_one_canal > COUNT_TRANSICIA)
for(i=0;i<TermoSW;i++)
{
@@ -277,6 +322,7 @@ interrupt void adc_isr(void)
Temper = *(&AdcRegs.ADCRESULT0 + i) >>4;
/* Ограничитель защищает рекурсивный фильтр от одиночного выброса. */
ok = abs(ADC_table[n]-Temper) < FILTER_CLIP;
if(ok) cwnt_ok[i]++;
@@ -325,6 +371,7 @@ for(i=0;i<1;i++)
fin:
/* Единая эпилоговая секция обязательна и после goto при READY == 0. */
// Reinitialize for next ADC sequence
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit