Попал мне в руки российский микроконтроллер К1986ВЕ92QI производства АО "ПКК Миландр" с 32-битным RISC ядром ARM Cortex-M3 128кБ Flash и 32кБ ОЗУ, сразу же захотелось изучить и опробовать его в действии.


Микроконтроллер поставляется в упаковке, которой позавидуют китайцы с AliExpress. Микросхема лежит в кассете из толстой алюминиевой фольги, которая обернута фольгированной бумагой, проложено поролоном, и весь этот "бутерброд" в картонной коробке с внутренними стенками покрытыми фольгой. Вообщем защита от статического электричества на высоте.




К микроконтроллеру идет этикетка и протокол отбора продукции, что очень даже приятно.



Для начала нужно было разработать принципиальную схему отладочной платы и определится с компонентами. Остановился на минимуме компонентов: стабилизатор на 3.3в для питания от USB порта, кварцевый резонатор на 8МГц, разъем miniUSB, кнопка сброса, подтягивающие резисторы и sip разъемы. Думаю для начальных опытов с микроконтроллером хватит. Также установил smd переключатель для выбора режима встроенного загрузчика. Микроконтроллер позволяет выбирать метод загрузки программы по одному из двух последовательных интерфейсов UART или JTAG/SWD, при этом JTAG позволяет производить отладку программы в микроконтроллере. Выбор метода загрузки программы определяется логическими уровнями на выходах PF4, PF5, PF6. Все возможные варианты представлены в таблице:



Микроконтроллер представляет из себя микросхему выполненную в пластиковом корпусе LQFP64 с выводами шириной 0.3мм и с расстоянием между ними 0.2мм, что навело на мысль о невозможности создать печатную плату приемлемого качества по технологии ЛУТ, но опыт подтвердил обратное. За пару часов был сделан чертеж печатной платы в Sprint Layout, распечатан на бумаге повышенной плотности Lamond и перенесен на стеклотекстолит. Травление происходило в растворе перекиси и лимонной кислоты на глазок и заняло около часа, на удивление качество проводников оказалось приемлемым с первого раза, что порадовало.



И так плата создана, все компоненты распаяны, остается запрограммировать. Будем использовать среду для разработки от Keil — MDK ARM uVision 5.0, к ней производителем микроконтроллера распространяется библиотека Standard Peripherals Library + software pack. По UART программировать не хотелось, поэтому решил использовать внутрисхемный программатор/отладчик ST-Link v2, а точнее его клон от неизвестного китайского производителя. Keil его поддерживает “из коробки”, а вот микроконтроллер, хоть и в документации сказано, что поддерживает SWD интерфейс, но как и куда что подключать упомянуть забыли. После поисков в интернете по запросу: “JTAG — SWD переходник” было выяснено, что линия SWDIO подключается к JTAG-TMS, а SWCLK к JTAG-TCK и “О чудо!” все заработало, в микроконтроллер прошилась тестовая программа.



На этом радость закончилась, так как после прошивки микроконтроллер хоть и работал, но отладчиком видится перестал. Видимо после перепрошивки линии порта JTAG-A переопределяются на другое функциональное назначение, хотя в программе порт B на котором находится JTAG-A даже не инициализировался. Разбираться в этом не хотелось, так как есть еще и JTAG-B. При подключении к альтернативному JTAG интерфейсу, все заработало как часы. В дальнейшем его и будем использовать для программирования и отладки.


Первой же поставленной себе задачей, было подключить контроллер к SCADA системе используя протокол Modbus. Дабы не изобретать велосипед возьмем кроссплатформенную свободно распространяемую библиотеку Freemodbus, и портируем ее для нашего микроконтроллера.


Для создания проектов в Keil на микроконтроллере от Миландр нужно для начала установить software pack. Делается это простым двойным кликом мыши по файлу. Далее Keil все сделает сама.


И так создаём новый проект. Выбираем наш микроконтроллер и компоненты библиотеки которые нам понадобятся:



В дереве проекта создаем группу Modbus Slave и добавляем туда следующие файлы из библиотеки Freemodbus:



И не забываем в опциях проекта указать компилятору следующие пути к каталогам библиотеки.



Теперь можно приступить конкретно к портированию библиотеки Freemodbus под наш микроконтроллер с использованием Standard Peripherals Library. Для этого нужно в файле portserial.c прописать функцию инициализации порта UART xMBPortSerialInit


BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{

        // Включение тактирования порта F
        RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTF, ENABLE); 
        // Объявление структуры для инициализации порта
        PORT_InitTypeDef uart2_port_set;  
        // Инициализация порта F для функции UART
        // Настройка порта по умолчанию
        PORT_StructInit(&uart2_port_set);  
        // Переопределение функции порта
        uart2_port_set.PORT_FUNC = PORT_FUNC_OVERRID;  
        // Установка короткого фронта
        uart2_port_set.PORT_SPEED = PORT_SPEED_MAXFAST;  
        // Цифровой режим работы вывода
        uart2_port_set.PORT_MODE = PORT_MODE_DIGITAL;  
        // Инициализация вывода PF1 как UART_TX (передача)
        uart2_port_set.PORT_Pin = PORT_Pin_1;
        uart2_port_set.PORT_OE = PORT_OE_OUT;
        PORT_Init(MDR_PORTF, &uart2_port_set);
        // Инициализация вывода PF0 как UART_RX (прием)
        uart2_port_set.PORT_Pin = PORT_Pin_0;
        uart2_port_set.PORT_OE = PORT_OE_IN;

        // Процедура инициализации контроллера UART
        // Включение тактирования UART2
        RST_CLK_PCLKcmd(RST_CLK_PCLK_UART2, ENABLE);
        // Объявление структуры для инициализации контроллера UART
        UART_InitTypeDef UART_InitStructure;
        // Делитель тактовой частоты UART = 1
        UART_BRGInit(MDR_UART2,UART_HCLKdiv1);
        // Конфигурация UART
        // Скорость передачи данных – 115200 бод
        UART_InitStructure.UART_BaudRate = ulBaudRate;
        // Количество бит в посылке – 8
        UART_InitStructure.UART_WordLength = UART_WordLength8b;
        // Один стоп-бит
        UART_InitStructure.UART_StopBits = UART_StopBits1;
        // Без проверки четности
        UART_InitStructure.UART_Parity = UART_Parity_No;
        // Выключить работу буфера FIFO приемника и передатчика,
        // т.е. передача осуществляется по одному байту
        UART_InitStructure.UART_FIFOMode = UART_FIFO_OFF;
        // Разрешить прием и передачу данных
        UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_RXE | UART_HardwareFlowControl_TXE;
        // Инициализация UART2 с заданными параметрами
        UART_Init(MDR_UART2, &UART_InitStructure);
        // Включить сконфигурированный UART
        UART_Cmd(MDR_UART2, ENABLE);

    return TRUE;
}

функцию записи и чтения:


BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
        //Отправляем байт
            UART_SendData(MDR_UART2,ucByte);

    return TRUE;
}

BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
            //Читаем байт
    *pucByte = (uint8_t) UART_ReceiveData(MDR_UART2);
    return TRUE;
}

обработчик прерываний UART


    void USART2_IRQHandler(void)
{

  /* Событие при приеме байта ---------------------------------------------------*/
  if((UART_GetITStatus(MDR_UART2,UART_IT_RX)) != RESET)
  { 
         prvvUARTRxISR(  ); 
  }

  /* Событие при передаче байта ------------------------------------------------*/
  if((UART_GetITStatus(MDR_UART2,UART_IT_TX)) !=RESET)
  {
    prvvUARTTxReadyISR(  );
  } 
}

Следом за этим правим файл portimer.c в котором настраивается таймер который формирует временные отчеты для отслеживания конца пакета протокола modbus.


BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{
        MDR_RST_CLK->PER_CLOCK |= (1<<14); // Включение тактирования TIM1
        MDR_RST_CLK->TIM_CLOCK = 0x0;
        MDR_RST_CLK->TIM_CLOCK |= (1<<24); // TIM1_CLK_EN
        MDR_RST_CLK->TIM_CLOCK |= 0x07; // HCLK/8 выбор частоты

        MDR_TIMER1->CNTRL = 0x00000002; //Запись регистра управления
        MDR_TIMER1->CNT = 0x00000000; //Обнуление регистра
        MDR_TIMER1->PSG = 0x2; //f/1 выбор предделителя
        while((MDR_TIMER1->CNTRL & 0x004) != 0) {__NOP();} //ожидание конца записи делителя

        MDR_TIMER1->ARR = usTim1Timerout50us; // установка базы основного счетчика
        while((MDR_TIMER1->CNTRL & 0x004) != 0) {__NOP();} //ожидание записи базы основного счетчика

        MDR_TIMER1->IE = 0x00000002; //(CNT==ARR)->IE выбор действия для срабатывания прерывания
        NVIC->ISER[0] = (1<<14); // Global EN for IRQ14 разрешаем прерывание
        MDR_TIMER1->CNTRL |= (1<<0); //Timer1 ON включаем таймер
    return TRUE;

}

inline void
vMBPortTimersEnable(  )
{
    /* Разрешаем работу таймера */
        MDR_TIMER1->CNTRL |= (1<<0); //Timer1 ON
}

inline void
vMBPortTimersDisable(  )
{
    /* Запрещаем работу таймера */
        MDR_TIMER1->CNTRL &= ~(1<<0); //Timer1 OFF
}

static void prvvTIMERExpiredISR( void )
{
    ( void )pxMBPortCBTimerExpired(  );
}

void Timer1_IRQHandler(void)
{
    //Обработчик прерывания таймера
        MDR_TIMER1->STATUS &= ~0x002; //IE FLAG=0
     prvvTIMERExpiredISR( );
}

В main.c добавим функции обработки регистров modbus, неиспользуемые регистры заглушим заглушками


/* ----------------------- Defines ------------------------------------------*/
#define REG_INPUT_START 1000
#define REG_INPUT_NREGS 4

/* ----------------------- Static variables ---------------------------------*/
static USHORT   usRegInputStart = REG_INPUT_START;
static USHORT   usRegInputBuf[REG_INPUT_NREGS];

eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;

    if( ( usAddress >= REG_INPUT_START )
        && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInputStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}

eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,
                 eMBRegisterMode eMode )
{
    return MB_ENOREG;
}

eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
               eMBRegisterMode eMode )
{
    return MB_ENOREG;
}

eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    return MB_ENOREG;
}

На этом портирование закончено, осталось только в функции int main(void) инициализировать библиотеку и в цикле вызывать eMBPoll( );


int main (void) 
{

     eMBErrorCode    eStatus;
//Настройки UART не поддерживаются кроме скорости, необходимо в portserial.c в xMBPortSerialInit описать выбор режимов

    eStatus = eMBInit( MB_RTU, 0x0A, 0, 19200, MB_PAR_NONE ); 

        /* Enable the Modbus Protocol Stack. */
    eStatus = eMBEnable(  );

    while(1)
    {
    eStatus = eMBPoll(  );
        //обработчик ошибок
        if (eStatus!= MB_ENOREG){};

        /* Here we simply count the number of poll cycles. */
        usRegInputBuf[0]++;
    }

}

Компилируем все без ошибок, но ничего не работает. В режиме отладки узнаем, что пакеты принимаются обрабатываются и программа зависает на инициализации передачи. При включении прерывания от передатчика UART, прерывание не вызывается, и программа уходит в бесконечный цикл. После штудирования раздела “Описание работы UART” спецификации на микроконтроллер наткнулся на Примечание:


Прерывание передатчика работает по фронту, а не по уровню сигнала. В случае, если модуль и прерывания от него разрешены до осуществления записи данных в буфер FIFO передатчика, прерывание не формируется. Прерывание возникает только при опустошении буфера FIFO.

Ну что же не беда, ищем где происходит начало передачи, в файле mbrtu.c находим строчки кода


/* Activate the transmitter. */
        eSndState = STATE_TX_XMIT;
        vMBPortSerialEnable( FALSE, TRUE );

и принудительно отправляем байт в передатчик UART, для этого добавляем строку: "xMBRTUTransmitFSM();" и все прекрасно начинает работать, пакеты бегают, регистры читаются, а дальше дело техники.

Комментарии (49)


  1. aleks_proj
    02.02.2019 12:22
    +1

    Микроконтроллер поставляется в упаковке, которой позавидуют китайцы с AliExpress.


    Вы, судя по высказыванию, никогда не заказывали микроконтроллеры не на AliExpress.


    1. konchok
      02.02.2019 19:59

      Такая упоротая упаковка говорит скорее о хлипкости контроллера. Тот же Маузер шлёт через полмира практически в такой же упаковке как и на Алиэкспрессе и всё замечательно работает.


      1. GloooM
        02.02.2019 20:05
        +3

        Ну китайцы-китайцу рознь, некоторые могут и просто LQFP россыпью в зиплок насыпать ))
        А так вроде на фотках можно сказать практически стандартная упаковка для всех кто занимается электроникой, штатная подложка от производителя, пакетик силикагеля, индикатор влажности и все это в вакуумный антистатический пакет, а поролон сверху уже по вкусу )


      1. rstepanov
        02.02.2019 20:08

        Могу показать партию из Маузера с загнутыми ногами. Штук 20 контроллеров испоганили. Деньги вернули…


        1. konchok
          02.02.2019 22:14
          +1

          От хождения ногами десять слоёв фольги не помогли бы в любом случае


          1. Inanity
            03.02.2019 04:37

            Именно. Тут нужен жёсткий матричный поддон (Waffle Tray).


  1. aleks_proj
    02.02.2019 12:41
    +2

    хоть и в документации сказано, что поддерживает SWD интерфейс, но как и куда что подключать упомянуть забыли

    Это же Миландр. У них многое так в документации.

    Видимо после перепрошивки линии порта JTAG-A переопределяются на другое функциональное назначение, хотя в программе порт B на котором находится JTAG-A даже не инициализировался. Разбираться в этом не хотелось, так как есть еще и JTAG-B.

    Напоминает подход к решению проблемы классического ардуинщика.

    Прерывание передатчика работает по фронту, а не по уровню сигнала. В случае, если модуль и прерывания от него разрешены до осуществления записи данных в буфер FIFO передатчика, прерывание не формируется. Прерывание возникает только при опустошении буфера FIFO.

    Опустошение буфера FIFO передатчика не гарантирует передачу последнего байта наружу в линию, это же Миландр.


    1. Serge78rus
      02.02.2019 15:12
      +10

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


      1. GloooM
        02.02.2019 20:09
        +2

        Плюсую, как минимум на STM32 в точности так же, сам баг ловил )


        1. Serge78rus
          02.02.2019 23:27
          +3

          У STM32, помимо прерывания TXE, есть прерывание TC, которое надо разрешать только при передаче последнего байта посылки и тогда оно как раз и будет соответствовать моменту окончания передачи данных в линию. Именно так и рекомендуется делать в официальной документации STM AN3070


          1. GloooM
            03.02.2019 15:12

            До того как прочитал ветку ниже в комментах был уверен что такая организация у всех, а оказывается вон как бывает что прерывания по TC не предусмотрели в принципе.


      1. vau
        03.02.2019 11:32

        На волне импотрозамещения портировал на сабж ChibiOS для одного выставочного проекта. Так вот UART точно такой же как у NXP. Драйвер подошел как родной.


  1. Amomum
    02.02.2019 15:09
    +6

    Прерывание передатчика работает по фронту, а не по уровню сигнала. В случае, если модуль и прерывания от него разрешены до осуществления записи данных в буфер FIFO передатчика, прерывание не формируется. Прерывание возникает только при опустошении буфера FIFO.

    Ох как по больному-то месту вы прошлись сейчас!
    У нас были постоянные проблемы с преобразованием UART'a в 485, потому что преобразователь нужно переключать в режим приема только после того, как на линию будет отправлен последний байт целиком.
    Но в Миландре нет прерывания «передача завершена», только «буфер передатчика пуст». Для события «передача завершена» есть только флаг.

    Если проверять флаг, то можно не успеть и переключиться на прием слишком поздно, когда другое устройство на шине уже начало что-то передавать — слишком позднее переключение отрезает от этой посылки кусочек бита.
    Вопрос
    Возможно, стоить пилить пост про то, как мы эту ситуацию в итоге разрулили?


    1. emmibox
      02.02.2019 20:15
      +6

      Запилите пост — это достаточно серьезная проблема. Я например не выключаю приемник и принимаю собственное эхо.


      1. Amomum
        03.02.2019 15:45

        Да, мы в итоге так и делаем; почти случайно обнаружили, что «режим шлейфа» — это режим эха.
        Тем не менее, постараюсь запилить в ближайшее время, видать, спрос есть :)


    1. hardegor
      02.02.2019 21:30

      Если проверять флаг, то можно не успеть и переключиться на прием слишком поздно, когда другое устройство на шине уже начало что-то передавать — слишком позднее переключение отрезает от этой посылки кусочек бита.

      Я на это дело подвесил таймер(знаем размер и скорость порта) и уже в прерывании таймера проверяю флаг. Этим же таймером формирую таймауты на RS485.


    1. ktod
      02.02.2019 23:26

      Таймеры наше все. Особенно, когда нужна универсальная либа 485, которая без особых переделок будет работать на разных семействах.
      В прерывании «фифо пуст» взводим таймерок и уже в прерывании по таймеру переключаем с передачи на прием. Приоритет для таймера можно максимальный поставить, ибо обработчик короткий. Да, костыль, но что делать. Отсутствие прерывания по концу передачи совсем не редкость.


    1. amartology
      03.02.2019 01:54

      Но Миландр в Зеленограде, а НИИЭТ в Воронеже)
      Впрочем, это может не мешать кочевать одному и тому же UART.


    1. vau
      03.02.2019 11:51

      Все уже придумано за нас
      if (isr & UART_MIS_TXMIS)
      {
      if (u->FR & UART_FR_TXFE)
      {
      osalSysLockFromISR();
      msg_t b = sdRequestDataI(sdp);
      osalSysUnlockFromISR();
      if (b >= Q_OK) {
      u->DR = b;
      }
      }
      /* Physical transmission end.*/
      if ((u->FR & UART_FR_BUSY) != UART_FR_BUSY)
      {
      osalSysLockFromISR();
      if (oqIsEmptyI(&sdp->oqueue))
      chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
      osalSysUnlockFromISR();
      u->IMSC &= ~UART_IMSC_TXIM;
      }
      }


    1. aleks_proj
      03.02.2019 19:19

      Самое обидное, что Миландр не собирается переделывать периферию (по большей части) и этот UART так и будет переезжать в новые процы :(

      Это им не выгодно. И разработчик мог уйти в другую контору. Я так столкнулся с одним поделием Миландра. А в целом изделия Миланда — это боль. Хорошо, что UART не выпилили из МК, как в свое время они поступили с CAN-ом в одном из серии на ядре ARM.


      1. Amomum
        03.02.2019 22:49
        +1

        Обидно, что они не переделывают периферию даже в своих инициативных работах (в смысле в тех, которые без заказчика).
        В целом, боль, конечно, но я вынужден признать, что в России — это лучший производитель микроконтроллеров.


  1. ittakir
    02.02.2019 15:26
    +3

    Вот что меня удивляет в российской электронике
    image


    1. semen-pro
      02.02.2019 18:48

      Так ведь это тип корпуса, корпус «импортный» — буква тоже «импортная». Всё логично.


      1. ittakir
        02.02.2019 19:16
        +3

        А другие буквы в названии тоже импортные? А в других корпусах буквы все отечественные?


    1. hardegor
      02.02.2019 21:33

      Такой «вывих» встречается и в ГОСТах, например название корпуса русскими буквами, а варианты — латиницей.


    1. AnatolPe
      02.02.2019 22:33

      Меня удивляет то что они один и тот же кристалл упаковывают в разные корпуса, и при этом четко отказываются упаковывать данный кристалл в корпус LQFP144, тем самым кастрируют много периферии…


  1. d_suslov
    02.02.2019 17:08
    +5

    Видимо после перепрошивки линии порта JTAG-A переопределяются на другое функциональное назначение, хотя в программе порт B на котором находится JTAG-A даже не инициализировался. Разбираться в этом не хотелось, так как есть еще и JTAG-B.


    В файле MDR32F9Qx_config.h выберите #define USE_JTAG_A


  1. el_kornholio
    02.02.2019 17:08
    +5

    Косяк с отвалом JTAG\SWD при «прикосновении» к его порту — просто феерическая боль, через которую обязан пройти каждый, начинающий работу с мк Миландр. Они даже как бы намекают на проблему присутствием второго порта JTAG. Стоит отметить, что библиотеки, в принципе, сносные. Если появится желание поднять USB CDC — после долгих мучений и исследований форума Миландра всплывет прикол с define-ом, который надо прописать, чтоб он работал полноценно.


    1. Pyhesty
      03.02.2019 00:42

      мы решали эту проблему установкой в начале программы цикла (задержка) до переопределения ног и вообще конфигурации проца, что бы была возможность остановить проц и перепрошить…
      не знали про дефайн…


  1. leon76
    03.02.2019 11:55

    Сделали бы поддержку Arduino, был бы интерес со стороны энтузиастов. А так только для профессионального использования МК.


    1. Serge78rus
      03.02.2019 13:38
      +1

      С чего бы «энтузиаст» добровольно выбрал более дорогой и хуже документированный контроллер, если над ним, в отличие от некоторых «профессионалов», не стоит демон «импортозамещения»? И потом, разработчик-любитель («энтузиаст») — вовсе не синоним слова «чайник». Почему бы ему не воспользоваться человеческими системами разработки, а не Arduino IDE?


      1. leon76
        03.02.2019 21:24

        Чем больше выбор железа, тем в целом лучше для экосистемы. Что касается «импортозамещения», то энтузиаст здесь чем отличается от профи? завтра запретят ввоз Atmel и ST, и дальше что? мультивибратор на КТ315? :)


        1. Serge78rus
          03.02.2019 23:41
          +1

          завтра запретят ввоз Atmel и ST, и дальше что? мультивибратор на КТ315? :)
          Если дойдет до такого маразма, то можно только догадываться, что еще запретят из областей, отличных от электроники. Боюсь, что в такой ситуации количество любителей помигать светодиодом, на чем бы это не строилось, резко поубавится, т.к. они будут заняты решением более насущных проблем. Что касается профессиональных разработчиков, то на чем прикажут, на том и будут строить мультивибраторы — может на КТ315, а может и на МП39, или даже на 6Н2П.


    1. aleks_proj
      03.02.2019 19:14
      +1

      А может стоит расти из ардуинщиков в профессионалы?


      1. leon76
        03.02.2019 21:26
        +1

        Может, но Arduino снижает порог входа в технологию, нужно начинать с чего-то простого чтобы потом расти дальше.


        1. aleks_proj
          03.02.2019 22:07
          +1

          Arduino снижает порог входа в технологию

          Возможно. Но есть один важный нюанс, что большинство комьюнити ардуинщиков состоит из не профессионалов, профессионалам ардуино не интересна. И как следствие приводит к росту не грамотных. Есть живой пример и не один.

          В эпоху отсутствия ардуино, как-то входили в технологию программирования микроконтроллерных и микропроцессорных встраиваемых систем.


        1. amartology
          03.02.2019 23:16

          Проблема ровно в том, что подавляющее большинство ардуинщиков не хочет расти дальше, а хочет клепать на Ардуино все и вся, включая вещи для автоэлектроники, промышленной техники, медицины и т.д. и т.п. И вот это надо жёстко пресекать, а то люди потом электроды от Ардуино к голове без гальванической развязки подключают и продают это задорого.


  1. wikipro
    03.02.2019 13:06

    Спасибо за статью… мало что то стало сейчас на хабре специалистов по железу… :(


    1. Есть и у кого нибудь возможность протестировать рабочий температурный диапазон у этого кристалла ?? -40/ +85 C он потянет ?? В авто электронике его использовать можно ?
    2. Ардуино совместимый контроллер из него сделать можно ?


    1. Serge78rus
      03.02.2019 13:33
      +1

      Есть и у кого нибудь возможность протестировать рабочий температурный диапазон у этого кристалла ?? -40/ +85 C он потянет ?
      Если Вы не доверяете данным из этикетки производителя, заверенные печатью его службы контроля качества, то, наверное, следует присмотреться к продукции более надежного на Ваш взгляд производителя, а не просить «кого нибудь» проверить данный параметр. Кстати, если Вы не доверяете данным производителя, то почему только приведенному рабочему диапазону температур, а другие заявленные характеристики у Вас не вызывают сомнения?
      Ардуино совместимый контроллер из него сделать можно ?
      Это как то не гармонирует с Вашим же первым вопросом.


    1. parilov
      03.02.2019 15:09

      1886ВЕ3У при минус 60 °С работает.


    1. aleks_proj
      03.02.2019 19:07
      +1

      мало что то стало сейчас на хабре специалистов по железу…

      Специалистов хватает, просто им некогда писать статьи.


      1. amartology
        03.02.2019 20:40

        Это очень плохо и печально. Нормального железячного коммьюнити нет, и получается, что даже те самые профессионалы, у которых нет времени писать, в итоге тоже закисают в своих местечковых болотах, не говоря уже о том, что новичкам не у кого учиться. А потом новички вырастают и проектируют чипы криво, потому что не знают, что можно было по-другому.


        1. leon76
          03.02.2019 21:28

          +1 поэтому порог входа должен быть низким, тогда комьюнити будет из чего расти


    1. aleks_proj
      03.02.2019 19:12
      +1

      Есть и у кого нибудь возможность протестировать рабочий температурный диапазон у этого кристалла ?? -40/ +85 C он потянет ?? В авто электронике его использовать можно ?

      Кристаллы у данной серии едины, в пластик корпусируется в Китае, в золото у нас в стране. Вам остается только правильно выбрать исполнение.
      Ардуино совместимый контроллер из него сделать можно ?

      Можно. Только кому оно нужно?


    1. Inanity
      03.02.2019 23:38
      +1

      Cмотря какой грейд вам нужен.

      AEC-Q100
      image


  1. amartology
    03.02.2019 20:40

    Del, ошибся веткой из-за глюка мобильной версии (


  1. Colorbit
    04.02.2019 21:30

    Поделитесь пожалуйста проектом с разводкой платы под МК.


  1. d_ilyich
    05.02.2019 10:28

    Кто-нибудь,

    1. Проясните, пожалуйста, про интервалы. В документации с сайта modbus.org сказано:

    In RTU mode, message frames are separated by a silent interval of at least 3.5 character times.

    If a silent interval of more than 1.5 character times occurs between two characters, the message frame is declared incomplete and should be discarded by the receiver.

    Насколько я понимаю, в FreeModbus используется только t3.5, соответственно, в основанных на нём портах — тоже. Во всяком случае, в виденных мной. Но почему? Ведь теоретически может получиться, что межсимвольный интервал будет, скажем, t1.6, и тогда придётся «браковать» фреймы, хотя данные в них корректны.

    2. Проверьте, пожалуйста, работу с Coils на «правильном» железе, т.е которому доверяете на ~100%. Насколько я помню и понимаю, в FreeModbus 1.5 (1.6, вроде, не отличается) она некорректно реализована, т.е. не соответствует документации с сайта modbus.org. Хочу получить независимое подтверждение/опровержение.


    1. artshw Автор
      05.02.2019 13:14

      1. По спецификации отправитель должен быть уверен что самый большой интервал между байтами одной посылки 1,5Т, а получатель что все байты которые разделены интервалом менее или равным 1,5Т являются байтами одной посылки. Когда байты разделены более чем 3,5Т то это последний байт предыдущей посылки и следом первый байт новой.

      Причина таких интервалов в том что Т отправителя может отличаться от Т получателя, но 1.5Т отправителя всегда будут меньше 3,5Т получателя. Это можно трактовать как: «Будьте либеральны к тому что принимаете, и консервативны к тому что отправляете».

      На практике интервал 1,5Т не используют, так многие слейв устройства из-за неправильно расставленных приоритетов прерываний, (обычно modbus имеет самый низкий приоритет) могут прерывать передачу и на большие интервалы, и не контролируют этот параметр. Собственно это не имеет смысла так как новая посылка должна начаться с интервала в 3,5Т, и если интервал превышает 3,5Т то предыдущая и следующая посылка будут отброшены по проверке контрольной суммы.

      Думаю для большей поддержки разнообразных устройств все и отступают от контроля этого интервала.