Фронты START/STOP обрабатываются при принятии командного слова CAN/RS, а окончание импульса обслуживается таймером. STOP имеет приоритет, перекрытие выходов исключено, сохранена защита от самопуска при включении. Загрузка параметров больше не подменяет живые команды нагрузки. Добавлены подробные русские комментарии во все собственные C-модули и основные заголовки, описание поведения и host-тест автомата. Обновлены файлы прошивки. Полная сборка TI 22.6.1.LTS и тесты пройдены; проверка на физической плате не выполнялась.
264 lines
8.1 KiB
C
264 lines
8.1 KiB
C
/* Íàñòðîéêà ÀÖÏ è îáðàáîòêà àíàëîãîâûõ âûáîðîê. adc_isr îáíîâëÿåò
|
|
* adc_table_lem[0..3] èç ADCRESULT2..5 >> 4 è âûçûâàåò ðàñ÷¸ò èçìåðåíèé.
|
|
* READY â 166 ÿâëÿåòñÿ ñ÷¸ò÷èêîì äî íóëÿ, íå ôëàãîì ãîòîâíîñòè.
|
|
* WAKE çàäà¸ò îòäåëüíîå âðåìÿ óñòàíîâëåíèÿ èçìåðèòåëüíûõ öåïåé.
|
|
* Íå äîáàâëÿòü îæèäàíèÿ EEPROM/UART â îáðàáîò÷èê âûáîðîê.
|
|
*/
|
|
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
|
|
#include "DSP2833x_Examples.h" // DSP281x Examples Include File
|
|
#include "DSP2833x_SWPrioritizedIsrLevels.h"
|
|
|
|
#include "ADC.h"
|
|
|
|
#include "log_to_mem.h"
|
|
#include "RS485.h"
|
|
#include "filter_bat2.h"
|
|
|
|
#include "measure.h"
|
|
#include "message.h"
|
|
#include "package.h"
|
|
|
|
#include "peripher.h"
|
|
|
|
Uint16 adc_table_lem[4];
|
|
Uint16 adc_table_tpl[28]; // Ïîòîìó ÷òî +4 êàëèáð
|
|
|
|
unsigned long COUNT_WAIT_ONE_CANAL;
|
|
|
|
// Prototype statements for functions found within this file.
|
|
interrupt void adc_isr(void);
|
|
|
|
void setup_adc()
|
|
{
|
|
long CLKdiv,HSPCLKdiv,Rate;
|
|
|
|
#if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT
|
|
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
|
|
#endif
|
|
#if (CPU_FRQ_100MHZ)
|
|
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
|
|
#endif
|
|
|
|
// Specific clock setting for this example:
|
|
// EALLOW;
|
|
// SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
|
|
// EDIS;
|
|
|
|
// Interrupts that are used in this example are re-mapped to
|
|
// ISR functions found within this file.
|
|
EALLOW; // This is needed to write to EALLOW protected register
|
|
PieVectTable.ADCINT = &adc_isr;
|
|
EDIS; // This is needed to disable write to EALLOW protected registers
|
|
|
|
InitAdc(); // For this example, init the ADC
|
|
|
|
// Enable ADCINT in PIE
|
|
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
|
|
IER |= M_INT1; // Enable CPU Interrupt 1
|
|
// EINT; // Enable Global interrupt INTM
|
|
// ERTM; // Enable Global realtime interrupt DBGM
|
|
|
|
// 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
|
|
}
|
|
|
|
if(Desk==dsk_BKST)
|
|
{
|
|
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0002; // Setup 2 conv's on SEQ1
|
|
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //0x5;//0x7; // Setup ADCINA3 as 1st SEQ1 conv.
|
|
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; //0x4;// Setup ADCINA2 as 2nd SEQ1 conv.
|
|
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; //0x4;// Setup ADCINA2 as 2nd SEQ1 conv.
|
|
}
|
|
|
|
if(Desk==dsk_COMM)
|
|
{
|
|
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0006; // Setup 2 conv's on SEQ1
|
|
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.
|
|
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x3; // Setup ADCINA2 as 2nd SEQ1 conv.
|
|
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x6; // Setup ADCINA2 as 2nd SEQ1 conv.
|
|
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x1; // Setup ADCINA2 as 2nd SEQ1 conv.
|
|
}
|
|
|
|
if(Desk==dsk_BKSD)
|
|
{
|
|
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0000; // Setup 2 conv's on SEQ1
|
|
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA3 as 1st SEQ1 conv.
|
|
}
|
|
|
|
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.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.CONV15 = 0x9;//0x9;
|
|
}
|
|
|
|
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
|
|
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)
|
|
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
|
|
|
|
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded mode
|
|
|
|
AdcRegs.ADCTRL1.bit.CONT_RUN=0;
|
|
AdcRegs.ADCTRL1.bit.ACQ_PS = 15;
|
|
|
|
//AdcRegs.ADCTRL1.bit.CPS=1;
|
|
|
|
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
|
|
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
|
|
|
|
// Assumes ePWM1 clock is already enabled in InitSysCtrl();
|
|
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
|
|
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount
|
|
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
|
|
EPwm1Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
|
|
|
|
EPwm1Regs.TBCTL.bit.HSPCLKDIV = CLKMULT;
|
|
EPwm1Regs.TBCTL.bit.CLKDIV=2;
|
|
|
|
CLKdiv = 1<<EPwm1Regs.TBCTL.bit.CLKDIV;
|
|
if(EPwm1Regs.TBCTL.bit.HSPCLKDIV) HSPCLKdiv = 2*EPwm1Regs.TBCTL.bit.HSPCLKDIV;
|
|
else HSPCLKdiv = 1;
|
|
|
|
Rate = (SYSCLKOUT/(HSPCLKdiv*CLKdiv))/ADC_FREQ;
|
|
|
|
EPwm1Regs.TBPRD = Rate; // Set period for ePWM1
|
|
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start
|
|
|
|
if(Desk==dsk_BKSD) COUNT_WAIT_ONE_CANAL = (ADC_FREQ/100);
|
|
else COUNT_WAIT_ONE_CANAL = (ADC_FREQ/20);
|
|
}
|
|
|
|
interrupt void adc_isr(void)
|
|
{
|
|
static int count_run_one_canal=0;
|
|
static int cownt_cans=0;
|
|
int code_tpl_canal=0;
|
|
float Temper;
|
|
int i;
|
|
|
|
// Set interrupt priority:
|
|
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER1.all;
|
|
|
|
IER |= M_INT1;
|
|
IER &= MINT1; // Set "global" priority
|
|
PieCtrlRegs.PIEIER1.all &= MG11;//16; // Set "group" priority
|
|
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
|
|
EINT;
|
|
|
|
if(WAKE) WAKE--;
|
|
if(READY) READY--;
|
|
else
|
|
{
|
|
if(Caliber_time)
|
|
{
|
|
if(!--Caliber_time)
|
|
{
|
|
cTermoCal = 0;
|
|
cSaveParam = 1;
|
|
} }
|
|
|
|
if(Kurrent)
|
|
{
|
|
for(i=0;i<4;i++)
|
|
{
|
|
adc_table_lem[i] = *((&AdcRegs.ADCRESULT0)+i+2) >>4; Current_count(i);
|
|
} }
|
|
|
|
if(Desk==dsk_LOAD)
|
|
{
|
|
Temper = AdcRegs.ADCRESULT1 >> 4;
|
|
modbus[0x63] = Temper;
|
|
Temper = filterbat(&adc_filter[0],Temper);
|
|
modbus[0x1D] = (Temper-DAC_04)/(DAC_20-DAC_04)*(200-40)+40;
|
|
}
|
|
|
|
if(Desk==dsk_SHKF)
|
|
{
|
|
for(i=0;i<CLKMULT*3;)
|
|
{
|
|
if (++cownt_cans>=tpl_cans) cownt_cans=0;
|
|
|
|
// Èìåííî çäåñü íåò äûð
|
|
// if(sens_type[cownt_cans])
|
|
{
|
|
i++;
|
|
Temper= *(&AdcRegs.ADCRESULT0 + cownt_cans) >>4;
|
|
adc_table_tpl[cownt_cans]=filterbat(&adc_filter[cownt_cans],Temper);
|
|
if(sens_type[cownt_cans]==TERMO_AD) Temper_count(cownt_cans);
|
|
else Power_count(cownt_cans);
|
|
} } }
|
|
|
|
if(TermoSW)
|
|
{
|
|
if (count_run_one_canal>COUNT_WAIT_ONE_CANAL/2)
|
|
{
|
|
for(i=0;i<TermoSW;i++)
|
|
{
|
|
Temper = *(&AdcRegs.ADCRESULT0 + i) >>4;
|
|
Temper = filterbat(&adc_filter[TermoSW*cownt_cans+i],Temper);
|
|
adc_table_tpl[TermoSW*cownt_cans+i]=(int)Temper;
|
|
} }
|
|
|
|
if (count_run_one_canal++ >= COUNT_WAIT_ONE_CANAL)
|
|
{
|
|
count_run_one_canal=0;
|
|
|
|
for(i=0;i<TermoSW;i++)
|
|
Temper_count(TermoSW*cownt_cans+i);
|
|
|
|
if (++cownt_cans >= TPL_CANS+2)
|
|
{
|
|
cownt_cans=0;
|
|
}
|
|
|
|
code_tpl_canal = cownt_cans;
|
|
|
|
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 íàîáîðîò
|
|
}
|
|
|
|
select_tpl_canal(code_tpl_canal);
|
|
} } }
|
|
|
|
// Reinitialize for next ADC sequence
|
|
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
|
|
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
|
|
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
|
|
|
|
// Restore registers saved:
|
|
DINT;
|
|
PieCtrlRegs.PIEIER1.all = TempPIEIER;
|
|
|
|
return;
|
|
}
|