/* Последовательный вывод данных канала индикации. Русские пояснения сохранены в UTF-8. */ /* Подключает "DSP2833x_Device.h": поставляемое TI описание Device для семейства C2833x. */ #include "DSP2833x_Device.h" // DSP281x Headerfile Include File /* Подключает "DSP2833x_SWPrioritizedIsrLevels.h": поставляемое TI описание SWPrioritizedIsrLevels для семейства C2833x. */ #include "DSP2833x_SWPrioritizedIsrLevels.h" /* Подключает "filter_bat2.h": накопительный фильтр измерительных каналов. */ #include "filter_bat2.h" /* Подключает "measure.h": обработка датчиков, вычисление величин и миллисекундный такт системы. */ #include "measure.h" /* Подключает "RS485.h": приём и передача SCI-A/SCI-B, упаковка команд и FIFO первого порта. */ #include "RS485.h" /* Подключает "message.h": обработка Modbus, заводские параметры и сохранение настроек. */ #include "message.h" /* Подключает "kanal.h": последовательный вывод данных канала индикации. */ #include "kanal.h" /* Подключает "pulto.h": обмен и индикация пульта. */ #include "pulto.h" /* Подключает "package.h": адреса устройств, типы плат и псевдонимы технологических регистров. */ #include "package.h" /* Подключает "tools.h": настройка внешней памяти и служебные задержки. */ #include "tools.h" /* Подключает "peripher.h": перемычки режима платы, дискретные входы и выходы. */ #include "peripher.h" /* Объявляет digits — данные digits. Начальное значение задаётся справа от знака равенства. */ int digits[16] = {63,6,91,79,102,109,125,7,127,111,64,0,0,0,121,0}; /* Объявляет readr — данные readr. Начальное значение задаётся справа от знака равенства. */ int readr[5] = {0x08,0x0C,0x10,0x00,0x04}; /* Ограничивает настройки таймингов компилятором TI C2000; модель на ПК не использует эти директивы. */ #if defined(__TI_COMPILER_VERSION__) /* Сохраняет отдельный вызов переключения CLOCK: встраивание при -O3 сокращало удержание DATA после фронта. */ #pragma FUNC_CANNOT_INLINE(DCLK) /* Возвращает генерацию DCLK как в образе от 06.10.2026: уровень 1 и приоритет скорости 3 сохраняют прежнюю последовательность инструкций GPIO. */ #pragma FUNCTION_OPTIONS(DCLK, "--opt_level=1 --opt_for_speed=3") /* Сохраняет отдельный вызов переключения DATA, чтобы длительность импульсов не зависела от встраивания в передатчик. */ #pragma FUNC_CANNOT_INLINE(DOUT) /* Возвращает генерацию DOUT с прежними параметрами -O1 и --opt_for_speed=3; значения взяты из старой конфигурации CCS. */ #pragma FUNCTION_OPTIONS(DOUT, "--opt_level=1 --opt_for_speed=3") /* Не позволяет встроить разделитель пакетов в цикл передачи и изменить интервалы между переключениями линий. */ #pragma FUNC_CANNOT_INLINE(RESET) /* Сохраняет прежнюю последовательность вызовов GPIO и задержек разделителя, используя настройки старого образа. */ #pragma FUNCTION_OPTIONS(RESET, "--opt_level=1 --opt_for_speed=3") /* Сохраняет отдельный вызов передачи бита; протокол использует порядок и интервалы фронтов CLOCK и DATA. */ #pragma FUNC_CANNOT_INLINE(SENDBIT) /* Возвращает передаче бита настройки старого образа -O1 и --opt_for_speed=3, оставляя остальной проект на -O3. */ #pragma FUNCTION_OPTIONS(SENDBIT, "--opt_level=1 --opt_for_speed=3") /* Завершает блок настроек TI, не изменяя формат пакетов и существующие счётчики задержек. */ #endif /* Начинает функцию DCLK; назначение модуля — последовательный вывод данных канала индикации. */ void DCLK(int x) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Проверяет if(x) GpioDataRegs.GPASET.bit.GPIO6=1; последующий оператор выполняется только при истинном условии. */ if(x) GpioDataRegs.GPASET.bit.GPIO6=1; /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else GpioDataRegs.GPACLEAR.bit.GPIO6=1; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Начинает функцию DOUT; назначение модуля — последовательный вывод данных канала индикации. */ void DOUT(int x) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Проверяет if(x) GpioDataRegs.GPASET.bit.GPIO8=1; последующий оператор выполняется только при истинном условии. */ if(x) GpioDataRegs.GPASET.bit.GPIO8=1; /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else GpioDataRegs.GPACLEAR.bit.GPIO8=1; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Условие компиляции CLKMULT==1: выбранный блок включается в текущий вариант прошивки. */ #if CLKMULT==1 /* Задаёт POWS0 = 0L; данные POWS0. */ #define POWS0 0L /* Задаёт POWS1 = 10L; данные POWS1. */ #define POWS1 10L /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Условие компиляции CLKMULT==2: выбранный блок включается в текущий вариант прошивки. */ #if CLKMULT==2 /* Задаёт POWS0 = 0L; данные POWS0. */ #define POWS0 0L /* Задаёт POWS1 = 30L; данные POWS1. */ #define POWS1 30L /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Условие компиляции CLKMULT==3: выбранный блок включается в текущий вариант прошивки. */ #if CLKMULT==3 /* Задаёт POWS0 = 1L; данные POWS0. */ #define POWS0 1L /* Задаёт POWS1 = 50L; данные POWS1. */ #define POWS1 50L /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Условие компиляции CLKMULT==4: выбранный блок включается в текущий вариант прошивки. */ #if CLKMULT==4 /* Задаёт POWS0 = 2L; данные POWS0. */ #define POWS0 2L /* Задаёт POWS1 = 60L; данные POWS1. */ #define POWS1 60L /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Условие компиляции CLKMULT==5: выбранный блок включается в текущий вариант прошивки. */ #if CLKMULT==5 /* Задаёт POWS0 = 4L; данные POWS0. */ #define POWS0 4L /* Задаёт POWS1 = 80L; данные POWS1. */ #define POWS1 80L /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Начинает функцию RESET; назначение модуля — последовательный вывод данных канала индикации. */ void RESET() /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Вызывает DCLK с аргументами (0) в текущей последовательности операций. */ DCLK(0); /* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ #if POWS1>0 /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ DSP28x_usDelay(POWS1); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Вызывает DOUT с аргументами (1) в текущей последовательности операций. */ DOUT(1); /* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ #if POWS1>0 /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ DSP28x_usDelay(POWS1); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Вызывает DOUT с аргументами (0) в текущей последовательности операций. */ DOUT(0); /* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ #if POWS1>0 /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ DSP28x_usDelay(POWS1); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Начинает функцию SENDBIT; назначение модуля — последовательный вывод данных канала индикации. */ void SENDBIT(int x) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Вызывает DOUT с аргументами (x); DCLK(1) в текущей последовательности операций. */ DOUT(x); DCLK(1); /* Условие компиляции POWS0>0: выбранный блок включается в текущий вариант прошивки. */ #if POWS0>0 /* Вызывает DSP28x_usDelay с аргументами (POWS0) в текущей последовательности операций. */ DSP28x_usDelay(POWS0); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Вызывает DOUT с аргументами (0) в текущей последовательности операций. */ DOUT(0); /* Вызывает DSP28x_usDelay с аргументами (POWS0+1) в текущей последовательности операций. */ DSP28x_usDelay(POWS0+1); /* Вызывает DCLK с аргументами (0) в текущей последовательности операций. */ DCLK(0); /* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ #if POWS1>0 /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ DSP28x_usDelay(POWS1); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Начинает функцию kanal_Send; назначение модуля — последовательный вывод данных канала индикации. */ void kanal_Send(int adr, long dat, int dot) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Объявляет Word — слово; data — данные; aliq_part — данные aliq_part; dg — данные dg. */ long Word,data,aliq_part,dg[4]; /* Объявляет i — данные i; j — данные j; bit — представление регистра отдельными битовыми полями; byt — данные byt; addr — данные addr. Начальное значение задаётся справа от знака равенства. */ int i,j,bit,byt,addr,sgn=0,punkt=0,aliq_len=0,full_len, isdot=0; /* Проверяет if(adr>1); последующий оператор выполняется только при истинном условии. */ if(adr>1) // Лампочки /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Записывает Word значением dat; слово. */ Word =dat; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Проверяет if(dat<0) sgn=1; последующий оператор выполняется только при истинном условии. */ if(dat<0) sgn=1; /* Записывает data значением labs(dat); данные. */ data = labs(dat); /* Проверяет if(dot>=0 и dot<4) isdot = 1; последующий оператор выполняется только при истинном условии. */ if(dot>=0 && dot<4) isdot = 1; /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else dot=0; /* Записывает aliq_part значением data; данные aliq_part. */ aliq_part = data; /* Цикл for(i=0;i0). */ while(dat>0) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Делит dat значением 10; данные dat. */ aliq_len++; dat/=10; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Записывает dat значением data; данные dat. */ dat = data; /* Записывает full_len значением aliq_len+sgn; данные full_len. */ full_len = aliq_len+sgn; /* Проверяет if(full_len==0) full_len=1; последующий оператор выполняется только при истинном условии. */ if(full_len==0) full_len=1; /* Увеличивает full_len значением dot; данные full_len. */ full_len += dot; /* Цикл for(i=0; i<(full_len-4);i++); задаёт начальное значение, условие продолжения и шаг перебора. */ for(i=0; i<(full_len-4);i++) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Начинает цикл с проверкой условия после тела: первый проход выполняется всегда. */ dot--; dat/=10; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Проверяет if(dot<0) dot=0; последующий оператор выполняется только при истинном условии. */ if(dot<0) dot=0; /* Записывает punkt значением 1<0;i--); задаёт начальное значение, условие продолжения и шаг перебора. */ for(i=3;i>0;i--) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Проверяет if((dg[i]==0) и (i!=dot)); последующий оператор выполняется только при истинном условии. */ if((dg[i]==0)&&(i!=dot)) /* Записывает dg[i] значением 0xF; данные dg. */ dg[i]=0xF; // Это значит пусто /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else break; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Проверяет if(sgn); последующий оператор выполняется только при истинном условии. */ if(sgn) /* Цикл for(i=1;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ for(i=1;i<4;i++) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Проверяет if( (dg[i]==0xF) или (i==3)); последующий оператор выполняется только при истинном условии. */ if( (dg[i]==0xF)||(i==3)) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Записывает dg[i] значением 0xA; данные dg. */ dg[i]=0xA; // Это значит минус /* Прерывает ближайший цикл или ветвь switch и продолжает после него. */ break; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } } /* Цикл for(i=0;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ for(i=0;i<4;i++) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Записывает dg[i] значением digits[dg[i]]; данные dg. */ dg[i] = digits[dg[i]]; /* Проверяет if((punkt>>i)&1) dg[i]+= 128; последующий оператор выполняется только при истинном условии. */ if((punkt>>i)&1) dg[i]+= 128; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Записывает Word значением ((dg[0] ) & 0x000000FF) | ((dg[1]<<8 ) & 0x0000FF00) |; слово. */ Word = ((dg[0] ) & 0x000000FF) | ((dg[1]<<8 ) & 0x0000FF00) | /* Продолжает список аргументов, полей или выражение ((dg[2]<<16) & 0x00FF0000) | ((dg[3]<<24) & 0xFF000000);; порядок элементов сохраняется. */ ((dg[2]<<16) & 0x00FF0000) | ((dg[3]<<24) & 0xFF000000); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Записывает addr значением readr[adr]; данные addr. */ addr = readr[adr]; /* Цикл for (i=0;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ for (i=0;i<4;i++) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Проверяет if(addr>0x10) break; последующий оператор выполняется только при истинном условии. */ if(addr>0x10) break; /* Цикл for (j=0;j<8;j++); задаёт начальное значение, условие продолжения и шаг перебора. */ for (j=0;j<8;j++) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Записывает bit значением Word & 1; Word >>= 1; представление регистра отдельными битовыми полями. */ bit = Word & 1; Word >>= 1; /* Вызывает SENDBIT с аргументами (bit) в текущей последовательности операций. */ SENDBIT(bit); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Записывает byt значением addr; данные byt. */ byt = addr; /* Цикл for (j=0;j<6;j++); задаёт начальное значение, условие продолжения и шаг перебора. */ for (j=0;j<6;j++) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { /* Записывает bit значением byt & 1; byt >>= 1; представление регистра отдельными битовыми полями. */ bit = byt & 1; byt >>= 1; /* Вызывает SENDBIT с аргументами (bit) в текущей последовательности операций. */ SENDBIT(bit); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Изменяет счётчик в выражении addr++; на один для следующего шага. */ addr++; /* Вызывает RESET с аргументами () в текущей последовательности операций. */ RESET(); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ }