Files
Balsam_167/Source/Internal/DAC.c
Andrey 31f92e89d9 Обновить сборку прошивки 166, TESTLAMP и кодировку исходников
Перенести настройки выпуска в JSON, добавить переносимый сценарий сборки и проверки BIN. Обновить конфигурации CCS, исходники в UTF-8, обработку TESTLAMP, образы прошивки и регрессионные проверки.
2026-10-17 14:36:59 +03:00

183 lines
4.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ЦАП нагрузки и аппаратная обёртка импульсов СИФУ. Load_runner
* вызывается таймером 1 кГц, расчёт ЦАП делится до DAC_FREQ.
* Формула 166 задаёт фиксированный разгон 6..16 мА. DAC_min/max
* переводят положение в код, cCalibrDac выбирает ручной код.
* WAKEpowse относится к ЦАП, не является разрешением дискрета запуска.
* Автомат СИФУ подключён в конце файла через ump_control_impl.h.
*/
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"
#include "filter_bat2.h"
#include "measure.h"
#include "RS485.h"
#include "message.h"
#include "DAC.h"
#include "package.h"
#include "tools.h"
#include "peripher.h"
#include "log_to_mem.h"
#include "ump_pulse.h"
#define dCLK_1() GpioDataRegs.GPBSET.bit.GPIO63=1
#define dCLK_0() GpioDataRegs.GPBCLEAR.bit.GPIO63=1
#define dCS_1() GpioDataRegs.GPBSET.bit.GPIO59=1
#define dCS_0() GpioDataRegs.GPBCLEAR.bit.GPIO59=1
unsigned long WAKEpowse;
volatile unsigned long IMPowse;
unsigned int period_dac, time_dac;
/* Инициализация, не обработка каждого START. 601 отсчёт при 200 Гц
* дают около 3 секунд до рабочего расчёта ЦАП после включения.
*/
void Setup_DAC_time(void)
{
WAKEpowse = 3L * DAC_FREQ +1;
period_dac = READY_FREQ / DAC_FREQ;
time_dac = LOAD_TIME * DAC_FREQ;
/* Diagnostic values for the fixed 166 ramp (0.1 mA). */
ump_dac_go10 = 60; ump_dac_stop10 = 160;
ump_dac_duration = time_dac;
}
void dOUT(int x)
{
if(x) GpioDataRegs.GPBSET.bit.GPIO60=1;
else GpioDataRegs.GPBCLEAR.bit.GPIO60=1;
}
void wast()
{
int i;
for(i=0;i<25;i++);
}
void dSEND(unsigned int word)
{
int i;
dCS_0(); DSP28x_usDelay(1L);
for(i=0;i<16;i++)
{
dCLK_1();
dOUT((word & 0x8000)?1:0); word = word<<1; DSP28x_usDelay(1L);
dCLK_0(); DSP28x_usDelay(1L);
}
dCS_1();
}
void Init_DAC(void)
{
dSEND(0x9002|0x0000); toggle_RES_OUT_1();
}
/* vrot/maxx — доля диапазона между кодами 4 и 20 мА. Маска 0xFFF
* сохраняет 12 бит, но не является насыщением. modbus[0x1C] содержит
* расчётное задание, не измеренный ток на выходных клеммах.
*/
void Anal_output(long vrot, long maxx)
{
long out;
static int x;
out = DAC_min() + vrot * DAC_max() / maxx - vrot * DAC_min() / maxx ;
x=0;// !x; тщетно бытие
if(cCalibrDac) out=DAC_cal();
out = out & 0xFFF;
if(x) dSEND(out|0x0000|0x0000);
else dSEND(out|0x8000|0x0000);
modbus[123] = out;
modbus[0x1C] = 40L + vrot * 200 / maxx - vrot * 40 / maxx ;
/*
if(!no_write)
{
Test_mem_limit(4);
Log_to_mem(modbus[0x7B]);
Log_to_mem(modbus[0x63]);
Log_to_mem(modbus[0x1C]);
Log_to_mem(modbus[0x1D]);
}
*/
}
/* После половины time_dac счётчик растёт дважды за вызов. Поэтому
* LOAD_TIME=30 даёт примерно 22.5 с до конца разгона при 200 Гц.
* Существующий профиль 166 исправление импульса СИФУ не меняет.
*/
void Load_runner()
{
static unsigned int count_dac=0, count_load=0, x=1;
float sinus=0;
int kod;
/* IMPowse обновляется UMP_pulse_tick(), а не алгоритмом ЦАП. */
if(++count_dac >= period_dac)
{
count_dac=0;
if(WAKEpowse)
{
--WAKEpowse;
if( (WAKEpowse == DAC_FREQ/2*6)||
(WAKEpowse == DAC_FREQ/2*5)||
(WAKEpowse == DAC_FREQ/2*4)||
(WAKEpowse == DAC_FREQ/2*3)||
(WAKEpowse == DAC_FREQ/2*2)||
(WAKEpowse == DAC_FREQ/2*1) )
{
Init_DAC(); x=1;
} }
else
{
if(cUMPstart)
{
if(count_load > (time_dac/2))count_load++;
if(++count_load > time_dac) count_load = time_dac;
// sinus = ((float)(DAC_stop - DAC_go) / 16.0 * count_load) + ((float)(DAC_go - 4.0) / 16.0 * time_dac);
sinus = (10.0 / 16.0 * count_load) + (2.0 / 16.0 * time_dac);
}
else
{ count_load = 0;
sinus=0;
x = (x+1)&0x3FF;
}
/* Observe the existing ramp without changing DAC control. */
ump_dac_ramp = count_load;
ump_dac_duration = time_dac;
ump_dac_position = (unsigned int)sinus;
if(!x || cInitDac)
{
Init_DAC(); x=1; cInitDac=0;
}
else
{
kod = (int)sinus;
Anal_output(kod, time_dac);
} } } }
#include "ump_control_impl.h"