Добавлен регистратор запуска и отключения УМП для стендовой проверки
Реализованы кольцевая запись CAN-команд, дискретных сигналов, уставок и состояния ЦАП, а также отдельный архив отключения с секундой постинтервала. Добавлено расширение Modbus для онлайн-графиков и чтения архива через SetGUI. Сохранены управляющая логика и существующая область технологических регистров. Добавлены русские комментарии, описание протокола и тест регистратора. Проверка алгоритма и синтаксиса C пройдена; сборка TI/CCS и испытания на плате ещё требуются.
This commit is contained in:
@@ -138,6 +138,10 @@ void Load_runner()
|
||||
if(dac_go>5) dac_go=5;
|
||||
if(dac_stop>16) dac_go=16;
|
||||
if(dac_stop<=dac_go) dac_stop=dac_go+1;
|
||||
/* Для лога сохраняем реальные ограниченные уставки:
|
||||
* внутренние dac_go/stop отсчитываются от 4 мА. */
|
||||
ump_dac_go10 = (unsigned int)((dac_go + 4.0) * 10.0);
|
||||
ump_dac_stop10 = (unsigned int)((dac_stop + 4.0) * 10.0);
|
||||
}
|
||||
|
||||
if(count_load > (time_dac/2))count_load++;
|
||||
@@ -154,6 +158,11 @@ void Load_runner()
|
||||
x = (x+1)&0x3FF;
|
||||
}
|
||||
|
||||
/* Снимок стадии разгона для сопоставления команды CAN,
|
||||
* ожидаемого тока и кода, действительно отправленного ЦАП. */
|
||||
ump_dac_ramp = count_load;
|
||||
ump_dac_duration = time_dac;
|
||||
ump_dac_position = (unsigned int)sinus;
|
||||
preStart = cUMPstart;
|
||||
|
||||
if(!x || cInitDac)
|
||||
|
||||
@@ -3,5 +3,6 @@ void Anal_output(long vrot, long maxx);
|
||||
void Init_DAC(void);
|
||||
void Setup_DAC_time(void);
|
||||
|
||||
extern unsigned long IMPowse;
|
||||
/* Счётчик пускового импульса и выдержки инициализации доступны логгеру. */
|
||||
extern unsigned long IMPowse, WAKEpowse;
|
||||
extern unsigned int period_dac, time_dac;
|
||||
|
||||
@@ -42,6 +42,22 @@ extern LOG Log;
|
||||
/* Очистка памати (обнуление) */
|
||||
void clear_mem();
|
||||
|
||||
/* Ëîããåð ÓÌÏ: îòäåëüíîå àäðåñíîå ïðîñòðàíñòâî Modbus, áåç èçìåíåíèÿ
|
||||
* 128 òåõíîëîãè÷åñêèõ ðåãèñòðîâ. Äâà áàíêà ïî 800 çàïèñåé:
|
||||
* òåêóùèé êîëüöåâîé æóðíàë è çàôèêñèðîâàííûé ôðàãìåíò îòêëþ÷åíèÿ. */
|
||||
#define UMP_LOG_BASE 0x1000U
|
||||
#define UMP_LOG_DATA 0x1010U
|
||||
#define UMP_LOG_WORDS 40U
|
||||
#define UMP_LOG_CAPACITY 800U
|
||||
#define UMP_LOG_LIVE 0x1100U
|
||||
extern unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
|
||||
void ump_log_tick(void);
|
||||
void ump_log_io(void);
|
||||
void ump_log_can(unsigned int header, unsigned int a, unsigned int b, unsigned int c);
|
||||
void ump_log_rs(void);
|
||||
unsigned int ump_log_read(unsigned int address);
|
||||
int ump_log_write(unsigned int address, unsigned int value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "RS485.h"
|
||||
#include "message.h"
|
||||
#include "peripher.h"
|
||||
#include "log_to_mem.h"
|
||||
|
||||
|
||||
// Prototype statements for functions found within this file.
|
||||
@@ -212,6 +213,8 @@ void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
|
||||
if(bit[1]) if(adr < ANSWER_LEN) modbus[adr] = Data[1]; adr++;
|
||||
if(bit[2]) if(adr < ANSWER_LEN) modbus[adr] = Data[2];
|
||||
|
||||
/* Ôèêñèðóåì ïðèìåí¸ííóþ êîìàíäó äî âûõîäà èç îáðàáîò÷èêà CAN. */
|
||||
ump_log_can((unsigned int)(hiword >> 16), Data[0], Data[1], Data[2]);
|
||||
led2_toggle();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
* Çàïèñü ëîãîâ â ïàìyòü *
|
||||
****************************************************************/
|
||||
|
||||
#include "DSP2833x_Device.h"
|
||||
#include "filter_bat2.h"
|
||||
#include "measure.h"
|
||||
#include "package.h"
|
||||
#include "RS485.h"
|
||||
#include "message.h"
|
||||
#include "peripher.h"
|
||||
#include "DAC.h"
|
||||
#include "ADC.h"
|
||||
#include "log_to_mem.h"
|
||||
|
||||
int no_write = 0,
|
||||
@@ -32,3 +41,235 @@ void clear_mem()
|
||||
for (i=Log.Start; i<Log.Finis; i++)
|
||||
*(volatile int *)i = 0;
|
||||
}
|
||||
/* Äâà áàíêà èñïîëüçóþò óæå âûäåëåííóþ âíåøíþþ RAM .logg (64000 ñëîâ).
|
||||
* Àêòèâíûé áàíê êîëüöåâîé. ×åðåç 1000 ìñ ïîñëå êîìàíäû îòêëþ÷åíèÿ îí
|
||||
* ñòàíîâèòñÿ àðõèâîì, à çàïèñü ïðîäîëæàåòñÿ âî âòîðîì áàíêå. Ïåðåêëþ÷åíèå
|
||||
* çàíèìàåò ïîñòîÿííîå âðåìÿ: êîïèðîâàíèÿ 30 òûñÿ÷ ñëîâ ïîä çàïðåòîì IRQ íåò.
|
||||
* Àðõèâ ïåðåæèâàåò ðàçðûâ RS-ñâÿçè, íî ÍÅ èñ÷åçíîâåíèå ïèòàíèÿ ïëàòû. */
|
||||
static volatile unsigned int ump_state, ump_count, ump_cursor, ump_next;
|
||||
static volatile unsigned int ump_period = 20, ump_divider;
|
||||
static volatile unsigned long ump_time, ump_sequence;
|
||||
static unsigned int ump_bank, ump_archive_bank = 1;
|
||||
static unsigned int ump_archive_count, ump_archive_next, ump_generation;
|
||||
static unsigned int ump_source, ump_post, ump_post_dropped;
|
||||
static unsigned int ump_can_header, ump_can_data[3], ump_can_count;
|
||||
static unsigned int ump_prev_commands, ump_prev_inputs, ump_prev_outputs;
|
||||
extern int CanTimeOutErrorTR;
|
||||
/* Äèàãíîñòèêà âíóòðåííèõ ïåðåìåííûõ ðàçãîíà. Îáíîâëÿåòñÿ ñàìèì Load_runner,
|
||||
* íå ïåðåñ÷èòûâàåò è íå èçìåíÿåò óïðàâëÿþùèé àëãîðèòì. */
|
||||
unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
|
||||
|
||||
/* Ëîãè÷åñêèå óðîâíè âõîäîâ ïëàòû íàãðóçêè: ôèçè÷åñêèé íîëü îçíà÷àåò 1.
|
||||
* ×òåíèå GPIO íåïîñðåäñòâåííî çäåñü ïîçâîëÿåò çàïèñàòü âõîä äî ñëåäóþùåãî
|
||||
* îáíîâëåíèÿ ðåãèñòðà Inputs â îñíîâíîì öèêëå. */
|
||||
static unsigned int ump_inputs(void)
|
||||
{
|
||||
return (!GpioDataRegs.GPADAT.bit.GPIO6) |
|
||||
((!GpioDataRegs.GPADAT.bit.GPIO8) << 1) |
|
||||
((!GpioDataRegs.GPADAT.bit.GPIO11) << 2);
|
||||
}
|
||||
|
||||
/* START/STOP àêòèâíû åäèíèöåé; RES_OUT_2 àêòèâåí ôèçè÷åñêèì íóë¸ì. */
|
||||
static unsigned int ump_outputs(void)
|
||||
{
|
||||
return GpioDataRegs.GPBDAT.bit.GPIO62 |
|
||||
(GpioDataRegs.GPBDAT.bit.GPIO58 << 1) |
|
||||
((!GpioDataRegs.GPADAT.bit.GPIO3) << 2);
|
||||
}
|
||||
|
||||
/* Âûçûâàåòñÿ òîëüêî âíóòðè êîðîòêîé êðèòè÷åñêîé ñåêöèè. Âñå òðè èñòî÷íèêà
|
||||
* çàïèñåé (main, CAN ISR, timer ISR) èñïîëüçóþò îäíó áëîêèðîâêó IRQ ñ
|
||||
* âîññòàíîâëåíèåì ïðåæíåãî ñîñòîÿíèÿ, âêëþ÷àÿ âûçîâû èç ïðåðûâàíèÿ. */
|
||||
static void ump_capture(unsigned int reason)
|
||||
{
|
||||
volatile unsigned int *p;
|
||||
unsigned int i, commands;
|
||||
if (ump_state != 1 || Desk != dsk_LOAD || !READY) return;
|
||||
if (no_write || never_write) { ump_state = 3; return; }
|
||||
commands = Commands;
|
||||
/* Îòêëþ÷åíèå: ôðîíò cUMPreset (áèò 6) ëèáî ñïàä cUMPstart (áèò 7).
|
||||
* Ïîâòîðíûå êîìàíäû íå ñäâèãàþò êîíåö óæå íà÷àòîãî ïîñòèíòåðâàëà. */
|
||||
if (!ump_post && (((commands & 0x40) && !(ump_prev_commands & 0x40)) ||
|
||||
(!(commands & 0x80) && (ump_prev_commands & 0x80)))) {
|
||||
/* Ïîëîâèíó áàíêà ðåçåðâèðóåì ïîä ïîñòèíòåðâàë. Äàæå ïðè ïåðèîäå
|
||||
* 1 ìñ èëè øêâàëå CAN ñîáûòèå îòêëþ÷åíèÿ íå âûòåñíÿåòñÿ êîëüöîì. */
|
||||
if (ump_count >= UMP_LOG_CAPACITY/2) ump_count = UMP_LOG_CAPACITY/2-1;
|
||||
ump_post_dropped = 0;
|
||||
ump_post = 1000;
|
||||
reason |= 0x100;
|
||||
}
|
||||
/* Ïîñëåäíåå ìåñòî îñòàâëÿåì äëÿ ñíèìêà êîíöà ïîñòèíòåðâàëà. Ïðè
|
||||
* ïåðåïîëíåíèè ÷åñòíî îòìå÷àåì óñå÷åíèå áèòîì 0x200 â êîíå÷íîé çàïèñè. */
|
||||
if (ump_post && ump_count >= UMP_LOG_CAPACITY-1) {
|
||||
ump_post_dropped = 1;
|
||||
return;
|
||||
}
|
||||
if (reason == 5 && ump_post_dropped) reason |= 0x200;
|
||||
p = logs_block + ((unsigned long)ump_bank * UMP_LOG_CAPACITY + ump_next) * UMP_LOG_WORDS;
|
||||
p[0] = (unsigned int)ump_time; p[1] = (unsigned int)(ump_time >> 16);
|
||||
p[2] = reason; p[3] = commands;
|
||||
p[4] = ump_inputs(); p[5] = ump_outputs();
|
||||
p[6] = (unsigned int)IMPowse; p[7] = (unsigned int)WAKEpowse;
|
||||
p[8] = modbus[0x7B]; p[9] = modbus[0x1C];
|
||||
for (i = 0; i < 4; i++) { p[10+i] = sens_data[i]; p[14+i] = modbus[i]; }
|
||||
p[18] = ump_can_header;
|
||||
p[19] = ump_can_data[0]; p[20] = ump_can_data[1]; p[21] = ump_can_data[2];
|
||||
p[22] = ump_can_count; p[23] = CanTimeOutErrorTR;
|
||||
/* Èñõîäíûå óñòàâêè — ìÀ; ýôôåêòèâíûå óñòàâêè ïîñëå îãðàíè÷åíèé — 0.1 ìÀ.
|
||||
* p[8] — îòïðàâëåííûé êîä, à p[9] — ðàñ÷¸òíîå çàäàíèå, ÍÅ èçìåðåíèå òîêà. */
|
||||
p[24] = DAC_go; p[25] = DAC_stop;
|
||||
p[26] = DAC_min(); p[27] = DAC_max(); p[28] = DAC_cal();
|
||||
p[29] = DAC_04; p[30] = DAC_20;
|
||||
p[31] = ump_dac_ramp; p[32] = ump_dac_duration;
|
||||
p[33] = ump_dac_go10; p[34] = ump_dac_stop10; p[35] = ump_dac_position;
|
||||
for (i = 0; i < 4; i++) p[36+i] = ADC_table[i];
|
||||
ump_prev_commands = commands; ump_prev_inputs = p[4]; ump_prev_outputs = p[5];
|
||||
ump_next++;
|
||||
if (ump_next == UMP_LOG_CAPACITY) ump_next = 0;
|
||||
if (ump_count < UMP_LOG_CAPACITY) ump_count++;
|
||||
ump_sequence++;
|
||||
}
|
||||
|
||||
/* Çàâåðø¸ííûé áàíê áîëüøå íå èçìåíÿåòñÿ äî ñëåäóþùåãî îòêëþ÷åíèÿ.
|
||||
* Íîìåð ïîêîëåíèÿ ïîçâîëÿåò GUI îáíàðóæèòü çàìåíó àðõèâà âî âðåìÿ ÷òåíèÿ. */
|
||||
static void ump_freeze(void)
|
||||
{
|
||||
ump_archive_bank = ump_bank;
|
||||
ump_archive_count = ump_count; ump_archive_next = ump_next;
|
||||
ump_generation++;
|
||||
ump_bank ^= 1;
|
||||
ump_count = 0; ump_next = 0; ump_post = 0;
|
||||
}
|
||||
|
||||
void ump_log_tick(void)
|
||||
{
|
||||
unsigned int saved = __disable_interrupts();
|
||||
if (ump_state == 1) {
|
||||
ump_time++;
|
||||
if (++ump_divider >= ump_period) { ump_divider = 0; ump_capture(1); }
|
||||
if (ump_post && --ump_post == 0) {
|
||||
ump_capture(5);
|
||||
ump_freeze();
|
||||
}
|
||||
}
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
/* Äîïîëíèòåëüíûé ñíèìîê òîëüêî ïðè èçìåíåíèè êîìàíä, âõîäîâ èëè âûõîäîâ.
|
||||
* Ýòî íå çàìåíÿåò ïåðèîäè÷åñêóþ çàïèñü àíàëîãîâûõ âåëè÷èí â òàéìåðå. */
|
||||
void ump_log_io(void)
|
||||
{
|
||||
unsigned int saved;
|
||||
if (ump_state != 1 || Desk != dsk_LOAD) return;
|
||||
saved = __disable_interrupts();
|
||||
if (Commands != ump_prev_commands || ump_inputs() != ump_prev_inputs ||
|
||||
ump_outputs() != ump_prev_outputs) ump_capture(3);
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
/* Âûçûâàåòñÿ ïîñëå ïðèìåíåíèÿ ñëîâ ïðèíÿòîãî CAN-êàäðà: ñíèìîê ñîäåðæèò
|
||||
* íîâûå êîìàíäû, à òàêæå èñõîäíûé àäðåñ/ìàñêó è âñå òðè ñëîâà êàäðà. */
|
||||
void ump_log_can(unsigned int header, unsigned int a, unsigned int b, unsigned int c)
|
||||
{
|
||||
unsigned int saved;
|
||||
if (ump_state != 1 || Desk != dsk_LOAD) return;
|
||||
saved = __disable_interrupts();
|
||||
ump_can_header = header;
|
||||
ump_can_data[0] = a; ump_can_data[1] = b; ump_can_data[2] = c;
|
||||
ump_can_count++;
|
||||
ump_capture(2);
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
void ump_log_rs(void)
|
||||
{
|
||||
unsigned int saved = __disable_interrupts();
|
||||
ump_capture(4);
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
/* Óïðàâëåíèå æóðíàëîì îòäåëåíî îò òåõíîëîãè÷åñêèõ êîìàíä: íà÷àëî çàïèñè
|
||||
* ÍÅ çàïóñêàåò ÓÌÏ. Âûáîð àðõèâà íå îñòàíàâëèâàåò òåêóùóþ çàïèñü. */
|
||||
int ump_log_write(unsigned int address, unsigned int value)
|
||||
{
|
||||
unsigned int saved, valid = 1;
|
||||
saved = __disable_interrupts();
|
||||
if (address == UMP_LOG_BASE && value == 0) {
|
||||
ump_state = 3; ump_post = 0;
|
||||
} else if (address == UMP_LOG_BASE && value == 1 && Desk == dsk_LOAD && READY && ump_state != 1) {
|
||||
ump_count = 0; ump_next = 0; ump_cursor = 0; ump_divider = 0; ump_post = 0;
|
||||
ump_source = 0;
|
||||
ump_prev_commands = Commands;
|
||||
no_write = 0; never_write = 0;
|
||||
ump_state = 1;
|
||||
ump_capture(1);
|
||||
}
|
||||
else if (address == UMP_LOG_BASE+1 && ump_state != 1 && value >= 1 && value <= 1000)
|
||||
ump_period = value;
|
||||
else if (address == UMP_LOG_BASE+2 && value < UMP_LOG_CAPACITY)
|
||||
ump_cursor = value;
|
||||
else if (address == UMP_LOG_BASE+3 && value <= 1) ump_source = value;
|
||||
else valid = 0;
|
||||
__restore_interrupts(saved);
|
||||
return valid;
|
||||
}
|
||||
|
||||
/* Ïðåîáðàçîâàíèå õðîíîëîãè÷åñêîãî èíäåêñà â ôèçè÷åñêóþ ïîçèöèþ êîëüöà.
|
||||
* Äëÿ àðõèâà ñîõðàíåíû ñîáñòâåííûå count/next, íåçàâèñèìûå îò æèâîãî áàíêà. */
|
||||
static unsigned int ump_word(unsigned int archived, unsigned int record, unsigned int word)
|
||||
{
|
||||
unsigned int count = archived ? ump_archive_count : ump_count;
|
||||
unsigned int next = archived ? ump_archive_next : ump_next;
|
||||
unsigned int bank = archived ? ump_archive_bank : ump_bank;
|
||||
unsigned int slot;
|
||||
if (record >= count) return 0;
|
||||
slot = next + UMP_LOG_CAPACITY - count + record;
|
||||
while (slot >= UMP_LOG_CAPACITY) slot -= UMP_LOG_CAPACITY;
|
||||
return logs_block[((unsigned long)bank * UMP_LOG_CAPACITY + slot) * UMP_LOG_WORDS + word];
|
||||
}
|
||||
|
||||
/* Âåñü Modbus-áëîê ÷èòàåòñÿ âûçûâàþùèì êîäîì ïîä îäíîé áëîêèðîâêîé IRQ.
|
||||
* Ïîýòîìó timestamp/äàííûå è çàãîëîâîê îíëàéí-áëîêà îòíîñÿòñÿ ê îäíîìó
|
||||
* ñîñòîÿíèþ êîëüöà, äàæå åñëè â ýòîò ìîìåíò ïðèõîäèò íîâàÿ CAN-êîìàíäà. */
|
||||
unsigned int ump_log_read(unsigned int address)
|
||||
{
|
||||
unsigned int offset, count;
|
||||
unsigned long first;
|
||||
switch (address) {
|
||||
case UMP_LOG_BASE: return 0x554D;
|
||||
case UMP_LOG_BASE+1: return 2;
|
||||
case UMP_LOG_BASE+2: return ump_source ? 3 : ump_state;
|
||||
case UMP_LOG_BASE+3: return ump_source ? ump_archive_count : ump_count;
|
||||
case UMP_LOG_BASE+4: return UMP_LOG_WORDS;
|
||||
case UMP_LOG_BASE+5: return UMP_LOG_CAPACITY;
|
||||
case UMP_LOG_BASE+6: return ump_period;
|
||||
case UMP_LOG_BASE+7: return (unsigned int)ump_time;
|
||||
case UMP_LOG_BASE+8: return (unsigned int)(ump_time >> 16);
|
||||
case UMP_LOG_BASE+9: return Desk;
|
||||
case UMP_LOG_BASE+10: return Mode;
|
||||
case UMP_LOG_BASE+11: return (unsigned int)READY_FREQ;
|
||||
case UMP_LOG_BASE+12: return ump_generation;
|
||||
case UMP_LOG_BASE+13: return ump_archive_count;
|
||||
case UMP_LOG_BASE+14: return ump_post;
|
||||
case UMP_LOG_BASE+15: return ump_state;
|
||||
}
|
||||
if (address >= UMP_LOG_DATA && address < UMP_LOG_DATA+120 && (ump_source || ump_state != 1)) {
|
||||
offset = address - UMP_LOG_DATA;
|
||||
return ump_word(ump_source, ump_cursor + offset / UMP_LOG_WORDS, offset % UMP_LOG_WORDS);
|
||||
}
|
||||
/* Ïîñëåäíèå òðè çàïèñè äëÿ îíëàéí-ãðàôèêà, áåç îñòàíîâêè è áåç
|
||||
* èçìåíåíèÿ êóðñîðà àðõèâíîãî ÷òåíèÿ. Ïåðâûå äâà ñëîâà — èõ íîìåð. */
|
||||
if (address >= UMP_LOG_LIVE && address < UMP_LOG_LIVE+124) {
|
||||
count = ump_count < 3 ? ump_count : 3;
|
||||
first = ump_sequence - count;
|
||||
offset = address - UMP_LOG_LIVE;
|
||||
if (offset == 0) return (unsigned int)first;
|
||||
if (offset == 1) return (unsigned int)(first >> 16);
|
||||
if (offset == 2) return count;
|
||||
if (offset == 3) return ump_generation;
|
||||
offset -= 4;
|
||||
if (offset / UMP_LOG_WORDS < count)
|
||||
return ump_word(0, ump_count - count + offset / UMP_LOG_WORDS, offset % UMP_LOG_WORDS);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -197,6 +197,9 @@ void main()
|
||||
if(!IMPowse) { clear_START_DPTB(); clear_STOP_DPTB(); }
|
||||
}
|
||||
|
||||
/* Снимок после обновления входов и формирования пусковых выходов. */
|
||||
ump_log_io();
|
||||
|
||||
for(i=0;i<2;i++)
|
||||
{
|
||||
if(i) rs = &rs_a;
|
||||
|
||||
@@ -151,6 +151,8 @@ interrupt void cpu_timer1_isr_SENS(void)
|
||||
if(Desk==dsk_LOAD)
|
||||
{
|
||||
Load_runner();
|
||||
/* База времени 1 мс; снимок содержит результат текущего шага ЦАП. */
|
||||
ump_log_tick();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "spise2p.h"
|
||||
|
||||
#include "caliber.h"
|
||||
#include "log_to_mem.h"
|
||||
|
||||
int modbus[ANSWER_LEN+1];
|
||||
unsigned int param[ANSWER_LEN+1];
|
||||
@@ -182,15 +183,36 @@ void Save_params()
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
|
||||
static void modbus_exception(RS_DATA *rs_arr, unsigned int function, unsigned int error)
|
||||
{
|
||||
unsigned int crc;
|
||||
rs_arr->buffer[0] = CNTRL_ADDR;
|
||||
rs_arr->buffer[1] = function | 0x80;
|
||||
rs_arr->buffer[2] = error;
|
||||
crc = get_crc_16(0xFFFF, rs_arr->buffer, 3);
|
||||
rs_arr->buffer[3] = LOBYTE(crc); rs_arr->buffer[4] = HIBYTE(crc);
|
||||
rs_arr->flag_TIMEOUT_to_Send = true;
|
||||
RS_Send(rs_arr, rs_arr->buffer, 5);
|
||||
}
|
||||
|
||||
void ReceiveCommandModbus3(RS_DATA *rs_arr)
|
||||
{
|
||||
unsigned int crc, Address_MB, Length_MB, i;
|
||||
unsigned int crc, Address_MB, Length_MB, i, value, saved = 0;
|
||||
|
||||
// ïîëó÷èëè íà÷àëüíûé àäðåñ ÷òåíèà
|
||||
Address_MB =/*(rs_arr->RS_Header[2] << 8) |*/ rs_arr->RS_Header[3];
|
||||
Address_MB = (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3];
|
||||
|
||||
// ïîëó÷èëè êîëè÷åñòâî ñëîâ äàííûõ
|
||||
Length_MB = (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5];
|
||||
if (!Length_MB || Length_MB > 125 ||
|
||||
!((Address_MB < ANSWER_LEN && Length_MB <= ANSWER_LEN-Address_MB) ||
|
||||
(Address_MB >= UMP_LOG_BASE && Address_MB <= UMP_LOG_BASE+15 &&
|
||||
Length_MB <= UMP_LOG_BASE+16-Address_MB) ||
|
||||
(Address_MB >= UMP_LOG_DATA && Address_MB < UMP_LOG_DATA+120 &&
|
||||
Length_MB <= UMP_LOG_DATA+120-Address_MB) ||
|
||||
(Address_MB == UMP_LOG_LIVE && Length_MB == 124))) {
|
||||
modbus_exception(rs_arr, CMD_MODBUS_3, 2); return;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Îòñûëêà
|
||||
@@ -200,12 +222,17 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
|
||||
rs_arr->buffer[1] = CMD_MODBUS_3;
|
||||
rs_arr->buffer[2] = Length_MB*2;
|
||||
|
||||
/* Çàùèùàåì öåëîñòíîñòü îäíîãî ñíèìêà/áëîêà; ïåðåäà÷à UART èä¸ò óæå
|
||||
* ñ ðàçðåø¸ííûìè ïðåðûâàíèÿìè è íå çàäåðæèâàåò èçìåðåíèå/óïðàâëåíèå. */
|
||||
if (Address_MB >= UMP_LOG_BASE) saved = __disable_interrupts();
|
||||
for (i=0;i<Length_MB;i++)
|
||||
{
|
||||
rs_arr->buffer[3+i*2 ]=(Modbus[Address_MB+i].byt.byte_hi);
|
||||
rs_arr->buffer[3+i*2+1]=(Modbus[Address_MB+i].byt.byte_lo);
|
||||
value = Address_MB >= UMP_LOG_BASE ? ump_log_read(Address_MB+i) : modbus[Address_MB+i];
|
||||
rs_arr->buffer[3+i*2] = (value >> 8) & 0xFF;
|
||||
rs_arr->buffer[3+i*2+1] = value & 0xFF;
|
||||
}
|
||||
|
||||
if (Address_MB >= UMP_LOG_BASE) __restore_interrupts(saved);
|
||||
crc = 0xffff;
|
||||
crc = get_crc_16(crc, rs_arr->buffer, Length_MB*2+3);
|
||||
|
||||
@@ -218,7 +245,10 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
|
||||
rs_arr->buffer[Length_MB*2+8] = 0;
|
||||
|
||||
rs_arr->flag_TIMEOUT_to_Send=true;
|
||||
RS_Send(rs_arr, rs_arr->buffer, Length_MB*2+8);
|
||||
/* Ðàñøèðåíèå ëîããåðà îòâå÷àåò òî÷íûì êàäðîì Modbus áåç õâîñòîâûõ
|
||||
* íóëåé: îíè èíà÷å ïîïàëè áû â íà÷àëî îòâåòà ñëåäóþùåãî áëîêà GUI.
|
||||
* Èñòîðè÷åñêèé ôîðìàò òåõíîëîãè÷åñêèõ ðåãèñòðîâ îñòàâëåí ïðåæíèì. */
|
||||
RS_Send(rs_arr, rs_arr->buffer, Length_MB*2+(Address_MB >= UMP_LOG_BASE ? 5 : 8));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -236,15 +266,22 @@ void ReceiveCommandModbus6(RS_DATA *rs_arr)
|
||||
|
||||
|
||||
// ïîëó÷èëè íà÷àëüíûé àäðåñ çàïèñè
|
||||
Address_MB = (/*(rs_arr->RS_Header[2] << 8) | */rs_arr->RS_Header[3]);
|
||||
Address_MB = (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3];
|
||||
|
||||
// ïîëó÷èëè ñëîâî äàííûõ
|
||||
Data_MB = (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5];
|
||||
|
||||
Modbus[Address_MB].all = Data_MB;
|
||||
if (Address_MB >= UMP_LOG_BASE) {
|
||||
if (!ump_log_write(Address_MB, Data_MB)) {
|
||||
modbus_exception(rs_arr, CMD_MODBUS_6, 3); return;
|
||||
}
|
||||
} else if (Address_MB < ANSWER_LEN) {
|
||||
Modbus[Address_MB].all = Data_MB;
|
||||
if (Address_MB == 127) ump_log_rs();
|
||||
} else { modbus_exception(rs_arr, CMD_MODBUS_6, 2); return; }
|
||||
|
||||
rs_arr->flag_TIMEOUT_to_Send=true;
|
||||
RS_Send(rs_arr, rs_arr->buffer, 10);
|
||||
RS_Send(rs_arr, rs_arr->buffer, Address_MB >= UMP_LOG_BASE ? 8 : 10);
|
||||
}
|
||||
|
||||
void SendCommandModbus4(RS_DATA *rs_arr)
|
||||
|
||||
Reference in New Issue
Block a user