Ускорить обратную связь R0–R3 задатчика для ПМ67

Перенести регистры индикации VPU в быстрый поток CAN, чтобы R3 не ожидал медленного обхода параметров. Сохранить управление светодиодами и настройки периодов EEPROM.

Добавить проверку настоящих масок и планировщика: интервал R3 составляет 120 мс при быстром делителе 2 и 600 мс при делителе 10. Сохранить изменённый исходник в UTF-8.
This commit is contained in:
2026-10-16 16:46:15 +03:00
parent 9ddea2d99a
commit ee79c7a376
2 changed files with 139 additions and 56 deletions
+56 -56
View File
@@ -1,8 +1,8 @@
/* Измерения, диагностика и периодическое обслуживание. ADC ISR
* поставляет выборки; таймер 1 обслуживает индикацию и телеметрию.
* Для dsk_LOAD он сначала завершает импульс СИФУ, затем вызывает
* расчёт ЦАП и снимок логгера. Частоты находятся в measure.h;
* при их изменении требуется пересчитать зависимые интервалы.
/* Измерения, диагностика и периодическое обслуживание. ADC ISR
* поставляет выборки; таймер 1 обслуживает индикацию и телеметрию.
* Для dsk_LOAD он сначала завершает импульс СИФУ, затем вызывает
* расчёт ЦАП и снимок логгера. Частоты находятся в measure.h;
* при их изменении требуется пересчитать зависимые интервалы.
*/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"
@@ -20,13 +20,13 @@
#include "message.h"
#include "log_to_mem.h"
#include <math.h> // Это чтобы мерить амплитуду! sqrt без этого будет крив!!!
#include <math.h> // Это чтобы мерить амплитуду! sqrt без этого будет крив!!!
unsigned int CanPowse=CANPOWSE,CanGO=0;
unsigned int Maska[2][8];
int TPL_CANS=0; // Количество температурных каналов
int TPL_CANS=0; // Количество температурных каналов
int tpl_cans=0;
int cal_addr=0;
@@ -53,23 +53,23 @@ int Curr_Edge;
float powK[] =
{
0.127, // питание 380В
0.127, // питание 380В
0.127, // питание 380В
0.127, // питание 380В
1.000, // ток
1.000, // напражение
1.000, // ток
1.000, // напражение
0.0076, // питание 31В
0.0076, // питание 24В
0.0076, // питание 24В
0.0076, // питание 15В
1.0000, // термодатчик мелкосхема
0.0076, // питание 31В
0.0076, // питание 24В
0.0076, // питание 24В
0.0076, // питание 15В
1.0000, // термодатчик мелкосхема
};
FILTERBAT def_FILTERBAT = DEF_FILTERBAT;
FILTERBAT adc_filter[20+4]; // макс.TPL*2 + 4 калибр
FILTERBAT out_filter[20+4]; // макс.TPL*2 + 4 напраж
FILTERBAT zer_filter[4]; // 4 напраж
FILTERBAT adc_filter[20+4]; // макс.TPL*2 + 4 калибр
FILTERBAT out_filter[20+4]; // макс.TPL*2 + 4 напраж
FILTERBAT zer_filter[4]; // 4 напраж
long sens_count[24+4];
@@ -79,7 +79,7 @@ float K_T1,K_T2;
interrupt void cpu_timer1_isr_SENS(void);
/********************************************************************/
/* Расчет модула тока из показаний двух фаз */
/* Расчет модула тока из показаний двух фаз */
/********************************************************************/
float im_calc(float ia,float ib)
{
@@ -115,8 +115,8 @@ interrupt void cpu_timer1_isr_SENS(void)
int TST;
#define err_lamp work_lamp // это дла шкапа,
#define alm_lamp heat_lamp // чтоб было понатнее
#define err_lamp work_lamp // это дла шкапа,
#define alm_lamp heat_lamp // чтоб было понатнее
EALLOW;
CpuTimer1.InterruptCount++;
@@ -140,10 +140,10 @@ interrupt void cpu_timer1_isr_SENS(void)
if(Desk==dsk_LOAD)
{
/* Снять истёкший импульс до расчёта ЦАП, независимо от main. */
/* Снять истёкший импульс до расчёта ЦАП, независимо от main. */
UMP_pulse_tick();
Load_runner();
/* База времени 1 мс; снимок содержит результат текущего шага ЦАП. */
/* База времени 1 мс; снимок содержит результат текущего шага ЦАП. */
ump_log_tick();
return;
}
@@ -156,9 +156,9 @@ interrupt void cpu_timer1_isr_SENS(void)
((Desk==dsk_COMM) && heat_lamp) ) set_RES_OUT_1();
else clear_RES_OUT_1();
if(work_lamp) set_LED_OUT_1(); // Она же err_lamp дла шкапа
if(work_lamp) set_LED_OUT_1(); // Она же err_lamp дла шкапа
else clear_LED_OUT_1();
if(heat_lamp) set_LED_OUT_2(); // Она же alm_lamp дла шкапа
if(heat_lamp) set_LED_OUT_2(); // Она же alm_lamp дла шкапа
else clear_LED_OUT_2();
}
@@ -360,37 +360,37 @@ void Init_packMask()
switch(Desk)
{
case dsk_EPLT:
Maska[m_SLOW][0]|= 0x000F; // Полученное
Maska[m_SLOW][6]|= 0x01FC; // Яркость ламп и одиночество
Maska[m_FAST][0]|= 0x000F; // Возвращает R0–R3 задатчика в быстром потоке: маска 0x000F выбирает четыре младших регистра, чтобы подтверждение R3 для ПМ67 не ожидало медленного обхода параметров.
Maska[m_SLOW][6]|= 0x01FC; // Яркость ламп и одиночество
break;
default:
for(i=0;i<can;i++)
{
Maska[m_FAST][ i /16]|=(1<<( i %16)); // Диагностика
Maska[m_FAST][(i+24)/16]|=(1<<((i+24)%16)); // Показаниа
Maska[m_FAST][ i /16]|=(1<<( i %16)); // Диагностика
Maska[m_FAST][(i+24)/16]|=(1<<((i+24)%16)); // Показаниа
}
for(i=0;i<3; i++)
Maska[m_SLOW][i+3] = Maska[m_FAST][i]; // Уставки
Maska[m_SLOW][i+3] = Maska[m_FAST][i]; // Уставки
if(Desk==dsk_BKSD) Maska[m_SLOW][7]|= 0x0300; // Калибровка термодатчиков
if(Desk==dsk_BKSD) Maska[m_SLOW][7]|= 0x0300; // Калибровка термодатчиков
else
Maska[m_SLOW][7]|= 0x0F00; // Калибровка термодатчиков
Maska[m_SLOW][7]|= 0x0F00; // Калибровка термодатчиков
if(Kurrent)
{ Maska[m_SLOW][7]|= 0x000F; // Ноль датчиков напражениа
Maska[m_SLOW][7]|= 0x00F0; // Калибровка датчиков напражениа
Maska[m_FAST][6]|= 0x3F00; // Фазные значениа
{ Maska[m_SLOW][7]|= 0x000F; // Ноль датчиков напражениа
Maska[m_SLOW][7]|= 0x00F0; // Калибровка датчиков напражениа
Maska[m_FAST][6]|= 0x3F00; // Фазные значениа
}
if(Desk==dsk_LOAD)
{ Maska[m_SLOW][7]|= 0x0030; // Калибровка ЦАП
Maska[m_FAST][7]|= 0xE000; // Дублировать команды
Maska[m_FAST][1]|= 0x3000; // Управлающий ток СИФУ
{ Maska[m_SLOW][7]|= 0x0030; // Калибровка ЦАП
Maska[m_FAST][7]|= 0xE000; // Дублировать команды
Maska[m_FAST][1]|= 0x3000; // Управлающий ток СИФУ
} }
Maska[m_FAST][1]|= 0x0001; // Дискретные входы
Maska[m_SLOW][6]|= 0x0007; // Яркость ламп и периоды посылок
Maska[m_SLOW][7]|= 0xE000; // Адрес, команды, и чтоб не вылазило
Maska[m_FAST][1]|= 0x0001; // Дискретные входы
Maska[m_SLOW][6]|= 0x0007; // Яркость ламп и периоды посылок
Maska[m_SLOW][7]|= 0xE000; // Адрес, команды, и чтоб не вылазило
}
int er_anal(int term, long * count, long edge, int pre)
@@ -449,26 +449,26 @@ void Current_count(int chan)
modbus[0x64+chan] = Numb;
// Средний (он же нулевой) уровень показаний АЦП
// Средний (он же нулевой) уровень показаний АЦП
zer_count[chan] += (Numb-zer_count[chan])/(5.0 * ADC_FREQ);
Zero_lev[chan] = (int)(filterbat(&zer_filter[chan],zer_count[chan]));
// Мгновенное значение фазы
// Мгновенное значение фазы
Current = (Numb - Zero_lev[chan]) * powK[chan];
// Действующее (среднеквадратичное) значение фазы
// Действующее (среднеквадратичное) значение фазы
lev_quadr[chan] += ((Current*Current)-lev_quadr[chan])/(1.0 * ADC_FREQ);
lev_count[chan] = sqrt(lev_quadr[chan]);
// Запомним
// Запомним
if(ist)
{
if(Desk==dsk_COMM) aCurrent =-Current;
else aCurrent = Current; // Запомнили мгновенное значение - дла амплитуды
else aCurrent = Current; // Запомнили мгновенное значение - дла амплитуды
}
else
{
// Вычисление амплитуды
// Вычисление амплитуды
Amplitude = filterbat(&out_filter[sens], im_calc(Current,aCurrent));
if(sens_type[chan]==VOLTAGE)
@@ -485,7 +485,7 @@ modbus[0x64+chan] = Numb;
sens_data[sens-1] = Level;
}
// Действующее (среднеквадратичное) значение третьей фазы
// Действующее (среднеквадратичное) значение третьей фазы
Numb =-Current-aCurrent;
lev_quadr[thrd] += (Numb*Numb-lev_quadr[thrd])/(1.0 * ADC_FREQ);
lev_count[thrd] = sqrt(lev_quadr[thrd]);
@@ -511,12 +511,12 @@ modbus[0x68+fazz+1] = lev_count[chan];
modbus[0x68+fazz+2] = lev_count[thrd];
}
// Это максимальное
// Это максимальное
Numb = lev_count[chan];
if(Numb<lev_count[pair]) Numb = lev_count[pair];
if(Numb<lev_count[thrd]) Numb = lev_count[thrd];
// Зашиты!
// Зашиты!
error.all = 0;
no_ignor = !sens_error[chan].bit.Ignor;
@@ -659,7 +659,7 @@ void Temper_count(int chan)
if(chan>tpl_cans) return;
// Kun именно чтоб скомпенсировать нечетность
// Kun именно чтоб скомпенсировать нечетность
if(kun&1) Numb = (Numb-K300_2)*K_T2+ZERO;
else Numb = (Numb-K300_1)*K_T1+ZERO;
}
@@ -706,7 +706,7 @@ sens_data[chan+8] = adc_table_tpl[chan];
error.all = 0;
no_ignor = !sens_error[chan].bit.Ignor;
// Обрыв или неисправность
// Обрыв или неисправность
if(Temper==-20 || Temper==200)
{
error.bit.Tear = 1;
@@ -714,7 +714,7 @@ sens_data[chan+8] = adc_table_tpl[chan];
}
else
// Перегрев
// Перегрев
if(((Temper>sens_hi_edge[chan]-Cooling) && (sens_error[chan].bit.Hyper)) ||
(Temper>sens_hi_edge[chan]) )
{
@@ -724,7 +724,7 @@ sens_data[chan+8] = adc_table_tpl[chan];
}
else
// Предупреждение по температуре
// Предупреждение по температуре
if(Temper>sens_lo_edge[chan])
{
error.bit.Over = 1;
@@ -796,7 +796,7 @@ void Power_count(int chan)
error.bit.Stop = 1;
} }
/* Повышенное напражение
/* Повышенное напражение
if(Power > sens_hi_edge[chan])
{
error.bit.Hyper = 1;