Как стать автором
Обновить
43
0

Инженер-электронщик

Отправить сообщение

Объяснение очень простое. Программисты PLC не утруждают себя обработкой исключений установки, сбитых концевиков, заклинивших моторов итд.

Поиск такой неисправности осуществляется анализом в отладчике. И тут язык LD подходит идеально.

inline float absF(float a) { return (*(((unsigned long*)(&a))))&0x7FFFFFF;} // :)

Может и тепличные, но я думаю что всякая офисная техника с импульсными БП, лампы с электронными баластами создают помех не меньше, чем коллекторный движок.

Ну выбьет искра один модбасовский пакет, ну перезапросит мастер еще раз, для моей задачи не критично.

Я уже решил. Буду ставить на объект.

Ну... например, система управления уличным освещением

На каждом столбе стоит коробочка Modbus-PLC, модуль дискретного выхода Модбас и реле.

Другая коробочка стоит в начале линии, там где обычно рубильник.

Коробочка подключена к одноплатнику, который подключен к интернету. Шлюз TCP RS485.

В офисе на писишке (или на смартфоне) стоит скада, из которой мы можем управлять отдельно каждой лампой. Только не спрашивайте зачем!

Обновил проект!
Переписал функцию вычисления CRC по таблице, время выполнения функции сократилось на 32%
Итоговое быстродействие Modbus RTU для наилучшего случая (вариант 8):
AVR среднее-105; минимальное-99; максимальное-1924;
STM32 среднее-86; минимальное-59; максимальное-1293;
Снижение максимального времени выполнения
STM32 — 1417-1293=124 такта
AVR — 2026-1924=102 такта
Имеется в ввиду минимальное и максимальное время выполнения.
Минимальное время выполнения соответствует ветке кода — «вошли, проверили таймер, таймер не дотикал и вышли» или «вошли проверили прием, принятых данных нет и вышли „
Максимальное время — завершение приема пакета запроса и формирование пакета ответа.

Согласен!
Я перебрал 48 вариантов, мне уже лень…
Попробуйте сами — github.com/IBAH-II/modbus-M48/archive/main.zip
1) Для АВР, и для СТМ, компилировался один и тот же код
2) В модуле как-бы две библиотеки, RTU и ASCII
3) Каждая содержит модбас функции 1,2,3,4,5,6,15,16,22
4) Код модуля Модбас полностью отвязан от аппаратуры, и использует 3 функции для связи с системой ModBusSysTimer, ModBusPUT(), ModBusGET()
5) в СТМ ModBusGET() работает через ПДП

Для примера — кольцевой буфер для передачи в UART
#define FifoTxBuf (256)
static unsigned char TxFifo[FifoTxBuf];//буфер для передачи данных 
static unsigned short TxHead=0;//голова, байт для передачи кладем на голову
static volatile unsigned short TxTail=0;//хвост, с хвоста в UART
void AES_RNG_LPUART1_IRQHandler(void)
  {//обработчик прерывания "передача закончена" 
  if(LPUART1->ISR & USART_ISR_TC)  
    {
    if(TxHead==TxTail)//проверяем наличие байт в буфере
      {//Данных нет, сбрасываем флаг прерывания
      LPUART1->ICR=USART_ICR_TCCF;
      }
    else
      {//данные есть, передаем, FIFO->UART
      LPUART1->TDR=TxFifo[TxTail];
      TxTail=(TxTail+1)&(FifoTxBuf-1);
      }
    }
  }

void PutUart0(unsigned char data)
  {
  //если в TX буфере пусто и регистр передачи пуст 
  if(
     (TxHead==TxTail)
     &&
     (((LPUART1->ISR)&USART_ISR_TXE)!=0)
    )
    {//сразу запускаем передачу
    LPUART1->TDR=data;
    return;
    }
  //если в буфере не пусто кладем в Tx буфер
  TxFifo[TxHead]=data;
  TxHead=(TxHead+1)&(FifoTxBuf-1);
 
Я тоже пятого размера не видел, но не могу сказать, что в этом нет смысла.
Использование потокового ввода-вывода (stream), позволяет полностью абстрагироваться от способа приема-передачи данных.
Зачем писать на ассемблере
потому что могу
Плате лет 12-13. Ноуту 16. Раньше на совесть делали :)
Тот анализатор которым я пользуюсь, выдает именно такие предупреждения…
Не разу он мне не выдал такого предупреждения, которое мне удалось исправить.
Хочется понять его логику. Может дело во мне.
Давно хочу спросить… Объясните логику анализатора (не вашего)
Неопределенный порядок выполнения

#pragma pack(push,1) 
typedef union
  {
  struct eeprom_tag
    {                                                                          
    signed short D0;
    signed short D1;
    unsigned char  CRC; 
    };
  unsigned char EepromAlignment[((sizeof(struct eeprom_tag)+2)/4)*4]; 
  }                                                                            
  eeprom_t;  
#pragma pack(pop)    
...
eeprom_t Ep;
...
Ep.CRC=GetCRC((unsigned char*)&Ep, sizeof(struct eeprom_tag)-sizeof(Ep.CRC) );   


Откуда предупреждение? В аргументах функции побочных эффектов нет, а sizeof вообще вычисляется на этапе компиляции.
Как писать чтобы предупреждения не было?
Не целесообразно. К Сименсу не протолкнешься, а для для решения насущных проблем хватает Модбас.
дык это оно и есть.

там еще выше защита для коротких пакетов
if(UkPaket<8) continue;

В натуре! сейчас проверил на Kepware,
задал мастеру блок чтения дискретных входов 16, а в слейву 8

что возвращаешь слайвом ILLEGAL_DATA_ADDRESS, что ILLEGAL_DATA_VALUE
Kepware пишет
Date Time Level User Name Source Event
05.11.2020 19:39:58 2 Default User Modbus Serial Bad address in block [000002 to 000012] on device 'c1.d1'
Вспомнил почему я не делал обработку ошибок!
Все дело в неоднозначности трактовок функций ошибок 2 (ILLEGAL_DATA_ADDRESS) и 3 (ILLEGAL_DATA_VALUE).
Каждый трактует их как хочет.

Информация

В рейтинге
Не участвует
Откуда
Россия
Зарегистрирован
Активность