Попал мне в руки российский микроконтроллер К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)
aleks_proj
02.02.2019 12:41+2хоть и в документации сказано, что поддерживает SWD интерфейс, но как и куда что подключать упомянуть забыли
Это же Миландр. У них многое так в документации.
Видимо после перепрошивки линии порта JTAG-A переопределяются на другое функциональное назначение, хотя в программе порт B на котором находится JTAG-A даже не инициализировался. Разбираться в этом не хотелось, так как есть еще и JTAG-B.
Напоминает подход к решению проблемы классического ардуинщика.
Прерывание передатчика работает по фронту, а не по уровню сигнала. В случае, если модуль и прерывания от него разрешены до осуществления записи данных в буфер FIFO передатчика, прерывание не формируется. Прерывание возникает только при опустошении буфера FIFO.
Опустошение буфера FIFO передатчика не гарантирует передачу последнего байта наружу в линию, это же Миландр.Serge78rus
02.02.2019 15:12+10Опустошение буфера FIFO передатчика не гарантирует передачу последнего байта наружу в линию, это же Миландр.
Отнюдь не являюсь проповедником импортозамещения, но Миландр здесь ничем не отличается от других: опустошение FIFO буфера означает лишь то, что последний байт данных поступил в сдвиговый регистр трансмиттера, а вовсе не выплюнут в линию.GloooM
02.02.2019 20:09+2Плюсую, как минимум на STM32 в точности так же, сам баг ловил )
Serge78rus
02.02.2019 23:27+3У STM32, помимо прерывания TXE, есть прерывание TC, которое надо разрешать только при передаче последнего байта посылки и тогда оно как раз и будет соответствовать моменту окончания передачи данных в линию. Именно так и рекомендуется делать в официальной документации STM AN3070
GloooM
03.02.2019 15:12До того как прочитал ветку ниже в комментах был уверен что такая организация у всех, а оказывается вон как бывает что прерывания по TC не предусмотрели в принципе.
vau
03.02.2019 11:32На волне импотрозамещения портировал на сабж ChibiOS для одного выставочного проекта. Так вот UART точно такой же как у NXP. Драйвер подошел как родной.
Amomum
02.02.2019 15:09+6Прерывание передатчика работает по фронту, а не по уровню сигнала. В случае, если модуль и прерывания от него разрешены до осуществления записи данных в буфер FIFO передатчика, прерывание не формируется. Прерывание возникает только при опустошении буфера FIFO.
Ох как по больному-то месту вы прошлись сейчас!
У нас были постоянные проблемы с преобразованием UART'a в 485, потому что преобразователь нужно переключать в режим приема только после того, как на линию будет отправлен последний байт целиком.
Но в Миландре нет прерывания «передача завершена», только «буфер передатчика пуст». Для события «передача завершена» есть только флаг.
Если проверять флаг, то можно не успеть и переключиться на прием слишком поздно, когда другое устройство на шине уже начало что-то передавать — слишком позднее переключение отрезает от этой посылки кусочек бита.
ВопросВозможно, стоить пилить пост про то, как мы эту ситуацию в итоге разрулили?emmibox
02.02.2019 20:15+6Запилите пост — это достаточно серьезная проблема. Я например не выключаю приемник и принимаю собственное эхо.
Amomum
03.02.2019 15:45Да, мы в итоге так и делаем; почти случайно обнаружили, что «режим шлейфа» — это режим эха.
Тем не менее, постараюсь запилить в ближайшее время, видать, спрос есть :)
hardegor
02.02.2019 21:30Если проверять флаг, то можно не успеть и переключиться на прием слишком поздно, когда другое устройство на шине уже начало что-то передавать — слишком позднее переключение отрезает от этой посылки кусочек бита.
Я на это дело подвесил таймер(знаем размер и скорость порта) и уже в прерывании таймера проверяю флаг. Этим же таймером формирую таймауты на RS485.
ktod
02.02.2019 23:26Таймеры наше все. Особенно, когда нужна универсальная либа 485, которая без особых переделок будет работать на разных семействах.
В прерывании «фифо пуст» взводим таймерок и уже в прерывании по таймеру переключаем с передачи на прием. Приоритет для таймера можно максимальный поставить, ибо обработчик короткий. Да, костыль, но что делать. Отсутствие прерывания по концу передачи совсем не редкость.
amartology
03.02.2019 01:54Но Миландр в Зеленограде, а НИИЭТ в Воронеже)
Впрочем, это может не мешать кочевать одному и тому же UART.
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;
}
}aleks_proj
03.02.2019 19:19Самое обидное, что Миландр не собирается переделывать периферию (по большей части) и этот UART так и будет переезжать в новые процы :(
Это им не выгодно. И разработчик мог уйти в другую контору. Я так столкнулся с одним поделием Миландра. А в целом изделия Миланда — это боль. Хорошо, что UART не выпилили из МК, как в свое время они поступили с CAN-ом в одном из серии на ядре ARM.Amomum
03.02.2019 22:49+1Обидно, что они не переделывают периферию даже в своих инициативных работах (в смысле в тех, которые без заказчика).
В целом, боль, конечно, но я вынужден признать, что в России — это лучший производитель микроконтроллеров.
ittakir
02.02.2019 15:26+3Вот что меня удивляет в российской электронике
hardegor
02.02.2019 21:33Такой «вывих» встречается и в ГОСТах, например название корпуса русскими буквами, а варианты — латиницей.
AnatolPe
02.02.2019 22:33Меня удивляет то что они один и тот же кристалл упаковывают в разные корпуса, и при этом четко отказываются упаковывать данный кристалл в корпус LQFP144, тем самым кастрируют много периферии…
d_suslov
02.02.2019 17:08+5Видимо после перепрошивки линии порта JTAG-A переопределяются на другое функциональное назначение, хотя в программе порт B на котором находится JTAG-A даже не инициализировался. Разбираться в этом не хотелось, так как есть еще и JTAG-B.
В файле MDR32F9Qx_config.h выберите #define USE_JTAG_A
el_kornholio
02.02.2019 17:08+5Косяк с отвалом JTAG\SWD при «прикосновении» к его порту — просто феерическая боль, через которую обязан пройти каждый, начинающий работу с мк Миландр. Они даже как бы намекают на проблему присутствием второго порта JTAG. Стоит отметить, что библиотеки, в принципе, сносные. Если появится желание поднять USB CDC — после долгих мучений и исследований форума Миландра всплывет прикол с define-ом, который надо прописать, чтоб он работал полноценно.
Pyhesty
03.02.2019 00:42мы решали эту проблему установкой в начале программы цикла (задержка) до переопределения ног и вообще конфигурации проца, что бы была возможность остановить проц и перепрошить…
не знали про дефайн…
leon76
03.02.2019 11:55Сделали бы поддержку Arduino, был бы интерес со стороны энтузиастов. А так только для профессионального использования МК.
Serge78rus
03.02.2019 13:38+1С чего бы «энтузиаст» добровольно выбрал более дорогой и хуже документированный контроллер, если над ним, в отличие от некоторых «профессионалов», не стоит демон «импортозамещения»? И потом, разработчик-любитель («энтузиаст») — вовсе не синоним слова «чайник». Почему бы ему не воспользоваться человеческими системами разработки, а не Arduino IDE?
leon76
03.02.2019 21:24Чем больше выбор железа, тем в целом лучше для экосистемы. Что касается «импортозамещения», то энтузиаст здесь чем отличается от профи? завтра запретят ввоз Atmel и ST, и дальше что? мультивибратор на КТ315? :)
Serge78rus
03.02.2019 23:41+1завтра запретят ввоз Atmel и ST, и дальше что? мультивибратор на КТ315? :)
Если дойдет до такого маразма, то можно только догадываться, что еще запретят из областей, отличных от электроники. Боюсь, что в такой ситуации количество любителей помигать светодиодом, на чем бы это не строилось, резко поубавится, т.к. они будут заняты решением более насущных проблем. Что касается профессиональных разработчиков, то на чем прикажут, на том и будут строить мультивибраторы — может на КТ315, а может и на МП39, или даже на 6Н2П.
aleks_proj
03.02.2019 19:14+1А может стоит расти из ардуинщиков в профессионалы?
leon76
03.02.2019 21:26+1Может, но Arduino снижает порог входа в технологию, нужно начинать с чего-то простого чтобы потом расти дальше.
aleks_proj
03.02.2019 22:07+1Arduino снижает порог входа в технологию
Возможно. Но есть один важный нюанс, что большинство комьюнити ардуинщиков состоит из не профессионалов, профессионалам ардуино не интересна. И как следствие приводит к росту не грамотных. Есть живой пример и не один.
В эпоху отсутствия ардуино, как-то входили в технологию программирования микроконтроллерных и микропроцессорных встраиваемых систем.
amartology
03.02.2019 23:16Проблема ровно в том, что подавляющее большинство ардуинщиков не хочет расти дальше, а хочет клепать на Ардуино все и вся, включая вещи для автоэлектроники, промышленной техники, медицины и т.д. и т.п. И вот это надо жёстко пресекать, а то люди потом электроды от Ардуино к голове без гальванической развязки подключают и продают это задорого.
wikipro
03.02.2019 13:06Спасибо за статью… мало что то стало сейчас на хабре специалистов по железу… :(
- Есть и у кого нибудь возможность протестировать рабочий температурный диапазон у этого кристалла ?? -40/ +85 C он потянет ?? В авто электронике его использовать можно ?
- Ардуино совместимый контроллер из него сделать можно ?
Serge78rus
03.02.2019 13:33+1Есть и у кого нибудь возможность протестировать рабочий температурный диапазон у этого кристалла ?? -40/ +85 C он потянет ?
Если Вы не доверяете данным из этикетки производителя, заверенные печатью его службы контроля качества, то, наверное, следует присмотреться к продукции более надежного на Ваш взгляд производителя, а не просить «кого нибудь» проверить данный параметр. Кстати, если Вы не доверяете данным производителя, то почему только приведенному рабочему диапазону температур, а другие заявленные характеристики у Вас не вызывают сомнения?
Ардуино совместимый контроллер из него сделать можно ?
Это как то не гармонирует с Вашим же первым вопросом.
aleks_proj
03.02.2019 19:07+1мало что то стало сейчас на хабре специалистов по железу…
Специалистов хватает, просто им некогда писать статьи.amartology
03.02.2019 20:40Это очень плохо и печально. Нормального железячного коммьюнити нет, и получается, что даже те самые профессионалы, у которых нет времени писать, в итоге тоже закисают в своих местечковых болотах, не говоря уже о том, что новичкам не у кого учиться. А потом новички вырастают и проектируют чипы криво, потому что не знают, что можно было по-другому.
leon76
03.02.2019 21:28+1 поэтому порог входа должен быть низким, тогда комьюнити будет из чего расти
aleks_proj
03.02.2019 19:12+1Есть и у кого нибудь возможность протестировать рабочий температурный диапазон у этого кристалла ?? -40/ +85 C он потянет ?? В авто электронике его использовать можно ?
Кристаллы у данной серии едины, в пластик корпусируется в Китае, в золото у нас в стране. Вам остается только правильно выбрать исполнение.
Ардуино совместимый контроллер из него сделать можно ?
Можно. Только кому оно нужно?
Inanity
03.02.2019 23:38+1Cмотря какой грейд вам нужен.
AEC-Q100d_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. Хочу получить независимое подтверждение/опровержение.artshw Автор
05.02.2019 13:141. По спецификации отправитель должен быть уверен что самый большой интервал между байтами одной посылки 1,5Т, а получатель что все байты которые разделены интервалом менее или равным 1,5Т являются байтами одной посылки. Когда байты разделены более чем 3,5Т то это последний байт предыдущей посылки и следом первый байт новой.
Причина таких интервалов в том что Т отправителя может отличаться от Т получателя, но 1.5Т отправителя всегда будут меньше 3,5Т получателя. Это можно трактовать как: «Будьте либеральны к тому что принимаете, и консервативны к тому что отправляете».
На практике интервал 1,5Т не используют, так многие слейв устройства из-за неправильно расставленных приоритетов прерываний, (обычно modbus имеет самый низкий приоритет) могут прерывать передачу и на большие интервалы, и не контролируют этот параметр. Собственно это не имеет смысла так как новая посылка должна начаться с интервала в 3,5Т, и если интервал превышает 3,5Т то предыдущая и следующая посылка будут отброшены по проверке контрольной суммы.
Думаю для большей поддержки разнообразных устройств все и отступают от контроля этого интервала.
aleks_proj
Вы, судя по высказыванию, никогда не заказывали микроконтроллеры не на AliExpress.
konchok
Такая упоротая упаковка говорит скорее о хлипкости контроллера. Тот же Маузер шлёт через полмира практически в такой же упаковке как и на Алиэкспрессе и всё замечательно работает.
GloooM
Ну китайцы-китайцу рознь, некоторые могут и просто LQFP россыпью в зиплок насыпать ))
А так вроде на фотках можно сказать практически стандартная упаковка для всех кто занимается электроникой, штатная подложка от производителя, пакетик силикагеля, индикатор влажности и все это в вакуумный антистатический пакет, а поролон сверху уже по вкусу )
rstepanov
Могу показать партию из Маузера с загнутыми ногами. Штук 20 контроллеров испоганили. Деньги вернули…
konchok
От хождения ногами десять слоёв фольги не помогли бы в любом случае
Inanity
Именно. Тут нужен жёсткий матричный поддон (Waffle Tray).