Работа с RS485 на микросхеме sp3485

Densl
Offline
Зарегистрирован: 28.11.2018

FoxJone пишет:
Schwarz78 пишет:

Намекну, Serial.availableForWrite(), или как-то так. Проверяем на HARDWARE_SERIAL_BUFFER - 1 (или как-то так) и понимаем, что последний байт ушёл в сдвиговый регистр. Далее, ждём длительность байта (с помощью micros()), возможно ещё 3.5 байта, если Modbus, и вуаля, можно переходить на приём.

Ну так а я про что рассказываю весь топик? Надо ждать! И именно через микрос. Единственный делай (от которого так бомбит у стмщиков) в этом топике у ТС в стартпосте.

Как раз попалась мне имплементация этого AvailibleforWrite. В библиотеке роджера кларка она всегда возвращает 1.

FoxJone
Offline
Зарегистрирован: 19.04.2019

У меня проблем с 485 нет никаких, для своих нужд я его давно понял и обкатал. Модбас еще не курил, как я писал, железки, которыми я командую, не мои, а кто их делал, тот даже слова такого не слышал. В следующем году планируется замена этого старья на мои же контроллеры, там и буду думать.
Но, опять же - если заказчик выставит условие совместимости старых контроллеров с новыми, то никаких модбасов...
Вот последние 3 дня всю голову сломал с чипом мах3232 - гонит, гад, эхо в 232 порт... Но это я, похоже, с обвязкой где то накосячил...

dosikus
Offline
Зарегистрирован: 11.03.2017

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

dosikus
Offline
Зарегистрирован: 11.03.2017

FoxJone, я уже озвучил. Вам крайне необходим сниффер.

FoxJone
Offline
Зарегистрирован: 19.04.2019

dosikus пишет:
FoxJone, я уже озвучил. Вам крайне необходим сниффер.

Мы либо по разному понимаем это слово, либо я не понимаю вообще.
Сниферов у меня штук 5 есть. На всяческие линии связи. Они прекрасно слушают и в работе мне помогают.
Как мне с помощью снифера СЛАТЬ команды по 485 вообще не представляю. А тем более в постоянном режиме прием-передача.

b707
Онлайн
Зарегистрирован: 26.05.2017

Densl пишет:

Как раз попалась мне имплементация этого AvailibleforWrite. В библиотеке роджера кларка она всегда возвращает 1.

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

dosikus
Offline
Зарегистрирован: 11.03.2017

FoxJone, здесь все зависит от вашей компетенции.
Или вы знаете протокол с которым работаете либо нет.
Озвучьте...

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Densl пишет:

FoxJone пишет:
Schwarz78 пишет:

Намекну, Serial.availableForWrite(), или как-то так. Проверяем на HARDWARE_SERIAL_BUFFER - 1 (или как-то так) и понимаем, что последний байт ушёл в сдвиговый регистр. Далее, ждём длительность байта (с помощью micros()), возможно ещё 3.5 байта, если Modbus, и вуаля, можно переходить на приём.

Ну так а я про что рассказываю весь топик? Надо ждать! И именно через микрос. Единственный делай (от которого так бомбит у стмщиков) в этом топике у ТС в стартпосте.

Как раз попалась мне имплементация этого AvailibleforWrite. В библиотеке роджера кларка она всегда возвращает 1.

Кто вам мешает раскурить эту библиотеку? Далеко не все библиотеки в ардуино годные, WIRE, например, совсем не работает. Я все библиотеки просматриваю, и правлю, если мне надо, или ищу альтернативы. И не смотрите что она возвращает, код смотрите как работает.

Densl
Offline
Зарегистрирован: 28.11.2018

В общем проверил сейчас работу ком портов на простом примере: подключил через переходник UART к ногам А9, А10 к своему ПК. В общем если использовать только ноги А9, А10, В10, В11 все нормально работает. Как только пытаюсь что нибудь послать на весящий в воздухе А2, после этого начинаются  траблы с В10, В11. 

Блин, как обидно что это не моя ошибка. Что делать ХЗ...

Schwarz78
Offline
Зарегистрирован: 19.01.2019

b707 пишет:

Densl пишет:

Как раз попалась мне имплементация этого AvailibleforWrite. В библиотеке роджера кларка она всегда возвращает 1.

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

Вот вы насколько помните, а я код смотрел, поскольку мне было нужно. Она возвращает хардвайр_сериал_буфер - 1 когда последний байт записан в UDR. Почему -1 я не знаю, но так сделано. И у меня эта проверка работает в модбасе с реальными устройствами, и позволяет не блокировать программу.

dosikus
Offline
Зарегистрирован: 11.03.2017

RS485 ни как не определяет окончание транзакции(фрейма) на уровне физики.
Все определяет протокол , к примеру модбас рту это пауза, конкретно определенная. Модбас ASCII символами.
Все эти события элементарно вылавливаются с стм32.
Теперь вопрос -накуа делаи???

Schwarz78
Offline
Зарегистрирован: 19.01.2019

dosikus пишет:
RS485 ни как не определяет окончание транзакции(фрейма) на уровне физики. Все определяет протокол , к примеру модбас рту это пауза, конкретно определенная. Модбас ASCII символами. Все эти события элементарно вылавливаются с стм32. Теперь вопрос -накуа делаи???

Беда в том, что "программист" не знает, когда последний бит ушёл из УАРТа.

dosikus
Offline
Зарегистрирован: 11.03.2017

Densl, озвучьте камень.
Если это F1 смотрите настройки пинов.

dosikus
Offline
Зарегистрирован: 11.03.2017

Schwarz78 пишет:

dosikus пишет:
RS485 ни как не определяет окончание транзакции(фрейма) на уровне физики. Все определяет протокол , к примеру модбас рту это пауза, конкретно определенная. Модбас ASCII символами. Все эти события элементарно вылавливаются с стм32. Теперь вопрос -накуа делаи???

Беда в том, что "программист" не знает, когда последний бит ушёл из УАРТа.

Бяда, вы говорите о "погромисте" с аурдуньи?
Ибо вменяемый кодер пользующий стм32 , знает как определить сие. Причем я выше объяснил все на пальцах.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Densl пишет:

В общем проверил сейчас работу ком портов на простом примере: подключил через переходник UART к ногам А9, А10 к своему ПК. В общем если использовать только ноги А9, А10, В10, В11 все нормально работает. Как только пытаюсь что нибудь послать на весящий в воздухе А2, после этого начинаются  траблы с В10, В11. 

Блин, как обидно что это не моя ошибка. Что делать ХЗ...

Ошибка ваша на 99.99% Уж поверьте.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

dosikus пишет:

 Бяда, вы говорите о "погромисте" с аурдуньи? Ибо вменяемый кодер пользующий стм32 , знает как определить сие. Причем я выше объяснил все на пальцах.

Почему вы так считаете? Я не встречал вменяемых "кодеров".

b707
Онлайн
Зарегистрирован: 26.05.2017

Densl пишет:

В общем проверил сейчас работу ком портов на простом примере: подключил через переходник UART к ногам А9, А10 к своему ПК. В общем если использовать только ноги А9, А10, В10, В11 все нормально работает. Как только пытаюсь что нибудь послать на весящий в воздухе А2, после этого начинаются  траблы с В10, В11. 

а можно по-подробнее - почему А2 висит в воздухе? Если он не используется - зачем туда что-то посылать?

 

dosikus
Offline
Зарегистрирован: 11.03.2017

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

dosikus
Offline
Зарегистрирован: 11.03.2017

Schwarz78 пишет:

dosikus пишет:

 Бяда, вы говорите о "погромисте" с аурдуньи? Ибо вменяемый кодер пользующий стм32 , знает как определить сие. Причем я выше объяснил все на пальцах.

Почему вы так считаете? Я не встречал вменяемых "кодеров".


Здесь? Я не спорю.
Но это не тот форум где можно получить знания...

b707
Онлайн
Зарегистрирован: 26.05.2017

dosikus пишет:

Но это не тот форум где можно получить знания...

"Форум, где можно получить знания" - это вообще иллюзия. Или человек учится сам, или ему и форум нобелевский лауреатов не поможет.

Мне этот форум очень много дал в плане направления для самостоятельного изучения

Кстати. дадите ссылку на "вменяемый форум" по СТМ?

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Дык я про компетенцию ни ногой. Вопрос был про микросхему 3485 и невозможность обмена. Я и назвал основную беду всех новичков. А про потрошка СТМ32 я ничего не говорил, но уверен, что УАРТ даже там работает как УАРТ.

dosikus
Offline
Зарегистрирован: 11.03.2017

b707, mcu.goodboard.ru.
Все я спать, что нужно будет - завтра

b707
Онлайн
Зарегистрирован: 26.05.2017

Schwarz78 пишет:

Вот вы насколько помните, а я код смотрел, поскольку мне было нужно. Она возвращает хардвайр_сериал_буфер - 1 когда последний байт записан в UDR. Почему -1 я не знаю, но так сделано. И у меня эта проверка работает в модбасе с реальными устройствами, и позволяет не блокировать программу.

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

Densl
Offline
Зарегистрирован: 28.11.2018

void setup() {
  Serial.begin(19200);
  Serial1.begin(19200);
  Serial2.begin(19200);
  //  Serial3.begin(9600);

}

void loop() {
  char data[99];
  int A = 0;
  while (Serial.available())
  {
    data[A] = Serial.read();
    A++;
  }
  int B = 0;
  if (A)
  {
    Serial.print("IN: ");
    Serial.println(A);
    while ((A--) != 0)
    {
 //     Serial1.print(data[B++]);
      Serial2.print(data[B++]);
    };
  }
  A = 0;
  char dt[99];
  while (Serial2.available())
  {
    dt[A] = Serial2.read();
    A++;
   }
  while (Serial1.available())
  {
    Serial.println("Serial1.available()");
//    dt[A] = Serial1.read();
    A++;
  }
  
  if (A)
  {
    for (int i = 0; i < A; i++) Serial.print(dt[i]);
    Serial.println("");
  }
  delay(2800);
}

Схема проверки такая: с компа чего нибудь посылаю в сериал, дальше он идет на Serial2 который замкнут на себя и выводится обратно в порт Serial.

Если раскоментировать Serial1 то на второй начинает идти шляпа. Через один символ приходят данные. В воздухе висит, т.к. это для эксперимента не важно.

b707
Онлайн
Зарегистрирован: 26.05.2017

dosikus пишет:
b707, mcu.goodboard.ru.

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

nik182
Offline
Зарегистрирован: 04.05.2015

dosikus пишет:
RS485 ни как не определяет окончание транзакции(фрейма) на уровне физики. Все определяет протокол , к примеру модбас рту это пауза, конкретно определенная. Модбас ASCII символами. Все эти события элементарно вылавливаются с стм32. Теперь вопрос -накуа делаи???

Ну вот. А говоришь STM знаешь. Ещё раз. Не на пальцах, а конкретно из мануала - как узнать что последний символ из сдвигового буфера UART отправлен? В момент после отправки символа в  на модуле, который использует TC, нужно переключить с передачи на приём. Это ни как не связано с протоколом модбас. В момент отправки символа в сдвиговsй регистр UART возникает прерывание буфер пуст и это единственный способ привязаться к моменту переключения на приём. Но в этот момент символ ещё не отправлен физически.  И если переключить в этот момент, без задержки, то остаток символа не уйдет в линию и пакет модбас не будет полным. Именно поэтому нужна пауза после отправки в буфер последнего символа. Если ты знаешь как это сделать без паузы, озвучь. Все твои объяснения на пальцах пока говорят только о том, что конкретно в этом вопросе не разбираешься. 

Densl
Offline
Зарегистрирован: 28.11.2018

dosikus пишет:
Densl, озвучьте камень.
Если это F1 смотрите настройки пинов.

F1c8t6. Попробую посмотреть. Вроде бы все поумолчанию настроено.

b707
Онлайн
Зарегистрирован: 26.05.2017

Densl пишет:
Если раскоментировать Serial1 то на второй начинает идти шляпа. Через один символ приходят данные.

так а что вы хотели то - если раскомментировать строчку 24, у вас инкремент B++ выполняется дважды - вот и идут данные через раз...

Densl
Offline
Зарегистрирован: 28.11.2018

А точно. Ладно спать пойду.

b707
Онлайн
Зарегистрирован: 26.05.2017

Densl пишет:
А точно.

какой типичный срач :)

80 сообщений про высокие материи, а все из-за ерунды :)

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Schwarz78 пишет:

Ошибка ваша на 99.99% Уж поверьте.

А Шварц предупреждал.

dosikus
Offline
Зарегистрирован: 11.03.2017

nik182]</p> <p>[quote=dosikus пишет:

Ну вот. А говоришь STM знаешь. Ещё раз. Не на пальцах, а конкретно из мануала - как узнать что последний символ из сдвигового буфера UART отправлен?

...

Все твои объяснения на пальцах пока говорят только о том, что конкретно в этом вопросе не разбираешься. 

 

Говори за себя , что ты знаешь а скорей ничего не знаешь.

ОК?

Окрываем RM0008 стр 792

Читаем до просветления.

 

Procedure:
1. Enable the USART by writing the UE bit in USART_CR1 register to 1.
2. Program the M bit in USART_CR1 to define the word length.
3. Program the number of stop bits in USART_CR2.
4. Select DMA enable (DMAT) in USART_CR3 if Multi buffer Communication is to take
place. Configure the DMA register as explained in multibuffer communication.
5. Select the desired baud rate using the USART_BRR register.
6. Set the TE bit in USART_CR1 to send an idle frame as first transmission.
7. Write the data to send in the USART_DR register (this clears the TXE bit). Repeat this
for each data to be transmitted in case of single buffer.
8. After writing the last data into the USART_DR register, wait until TC=1. This indicates
that the transmission of the last frame is complete. This is required for instance when
the USART is disabled or enters the Halt mode to avoid corrupting the last
transmission.

Если не понято - смотрим картинкО Figure282 .

Выше описана как и передача с дма так и "ручное" .

В случае с дма используется прерывание по TCIFx , в "ручном" прерывание по TC.

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

sadman41 пишет:
Мозгов нет у людей, а виновата, как всегда, ардуина...

поддержу, тут уже тройку лет, а узнаю всё новое и новое для себя, в том числе детские болячки в коде...
Кстати, ты бы еще озвучил, какие косяки могут быть в том коде по Энкодеру, сдаюсь надо знать )))

Densl
Offline
Зарегистрирован: 28.11.2018

Schwarz78 пишет:

Schwarz78 пишет:

Ошибка ваша на 99.99% Уж поверьте.

А Шварц предупреждал.


Поспешил скопипастить.
Просто злит, такая прошивка красивая а из-за какой-то ошибки не работает. Уже месяц назад планировал закончить с этим.

b707
Онлайн
Зарегистрирован: 26.05.2017

Densl пишет:
Поспешил скопипастить. Просто злит, такая прошивка красивая а из-за какой-то ошибки не работает. Уже месяц назад планировал закончить с этим.

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

Densl
Offline
Зарегистрирован: 28.11.2018

FoxJone пишет:

b707, точно, подбирал экспериментально как раз на 9600. Подбтрал еще на 115200, но ее не помню на память.


Можно и не экспериментально. Теоретически считается что 10 миллионов нужно разделить на скорость в бодах: 10000000/baude_rate. Результат в микросекундах.

dosikus
Offline
Зарегистрирован: 11.03.2017

Теоретически можно и хрень насчитать.

Практически считается так:

 

#define USARTCLK 72000000UL
#define BAUDRATE 115200UL
 
USART1->BRR =(USARTCLK+BAUDRATE/2)/BAUDRATE;
 
 
Где USARTCLK - тактовая USART1 тобишь APB2
BAUDRATE   скорость 
nik182
Offline
Зарегистрирован: 04.05.2015

dosikus пишет:

....

Окрываем RM0008 стр 792

Читаем до просветления.

....8. After writing the last data into the USART_DR register, wait until TC=1. This indicates

that the transmission of the last frame is complete. This is required for instance when
the USART is disabled or enters the Halt mode to avoid corrupting the last
transmission.

Если не понято - смотрим картинкО Figure282 .

Выше описана как и передача с дма так и "ручное" .

В случае с дма используется прерывание по TCIFx , в "ручном" прерывание по TC.

Я тоже читал мануал, и тоже думал что управляя по по ТС всё будет шоколадно. Но оказалось, что ТС выставляется раньше, чем последний символ физически полностью выдвинут в линию. Это поведение не соответствует мануалу, но это есть.  Это создает проблемы только при использовании RS485 c ручным переключением приёма передачи. Когда я осциллографом смотрел почему обрезается пакет, то обнаружил что переключение на приём модуля RS485 происходило через 1-2 бита после начала передачи последнего байта. Я поставил задержку на переключение и всё заработало. Потом увидел критикуемую тобой статью, в которой человек столкнулся стой же проблемой, но решил её по другому - просто добавил один символ в конец пакета, чем создал ту же задержку, но на мой взгляд лучше, так как не пришлось добавлять код задержки. Если не веришь, что поведение сигнала ТС не соответствует мануалу - попробуй сам. Всё написанное относится к stm32f103с8t6, на других не пробовал.        

FoxJone
Offline
Зарегистрирован: 19.04.2019

nik182 пишет:

 Всё написанное относится к stm32f103с8t6, на других не пробовал.        

На ЕСП и Атмеге все точно так же. Плюс, чем больше посылка, тем больше последних байт теряется. Не буду врать почему, не разбирался.

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

b707
Онлайн
Зарегистрирован: 26.05.2017

FoxJone пишет:

Поэтому я ставлю паузу. Не делай, а именно задержку по микрос.

а это не одно и то же?

FoxJone
Offline
Зарегистрирован: 19.04.2019

b707 пишет:

FoxJone пишет:

Поэтому я ставлю паузу. Не делай, а именно задержку по микрос.

а это не одно и то же?

Если у МК больше никаких дел нет, то моя пауза очень похожа на делай (как в приведенном мной примере). А если идут другие процессы, то просто через определенное время таймер щелкнет и дернет 485-й за ногу.

Так то, это азбука даже для такого ламера, как я)

И вот тут я не уверен, просто где-то слышал звон, но вроде как делай вообще тормозит МК до такой степени, что поступившая в буфер UART посылка не обрабатывается (в отличие от простого таймера). Хотя это может просто страшилки для нубов.

dosikus
Offline
Зарегистрирован: 11.03.2017

nik182 пишет:

 

Я тоже читал мануал, и тоже думал что управляя по по ТС всё будет шоколадно. Но оказалось, что ТС выставляется раньше, чем последний символ физически полностью выдвинут в линию. 

 

А теперь внимательно смотрим на картинКо.

Терзаем голубую пилюлю что есть стм32F103c8

На 7 канале посылка , на 6 канале выход на PA0 которым дергаем в прерывании.

Код ниже.

 

 void USART1_IRQHandler (void)
 {
 
   if(USART1->SR & USART_SR_TC)
   {
     //USART1->DR;
    USART1->SR=0;
GPIOA->BSRR=GPIO_BSRR_BR0;
__NOP();
__NOP();
GPIOA->BSRR=GPIO_BSRR_BS0;
 
   }
   
 }
 
Ну что скажешь?
 
nik182
Offline
Зарегистрирован: 04.05.2015

FoxJone пишет:

И вот тут я не уверен, просто где-то слышал звон, но вроде как делай вообще тормозит МК до такой степени, что поступившая в буфер UART посылка не обрабатывается (в отличие от простого таймера). Хотя это может просто страшилки для нубов.

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

nik182
Offline
Зарегистрирован: 04.05.2015

dosikus пишет:

...

Ну что скажешь?
Пока ничего. Я сейчас далеко от осциллографа. Как только доберусь, покажу что получается у меня. 
dosikus
Offline
Зарегистрирован: 11.03.2017

Да можешь и не говорить и не показывать.

Все работает как писано в мануале, если писать вменяемо а не на финтифлюшках как на хабре...

b707
Онлайн
Зарегистрирован: 26.05.2017

FoxJone пишет:

Если у МК больше никаких дел нет, то моя пауза очень похожа на делай

так что за пауза такая. можно посмотреть?

FoxJone
Offline
Зарегистрирован: 19.04.2019

b707 пишет:

FoxJone пишет:

Если у МК больше никаких дел нет, то моя пауза очень похожа на делай

так что за пауза такая. можно посмотреть?

Ну блин, элементарный же лисапед то. Я думал, у всех такая есть.

void pause(long ptime) {
  long micro = micros();
  while ((micros() - micro) < ptime) {}
}

 

dosikus
Offline
Зарегистрирован: 11.03.2017

nik182 пишет:

Потом увидел критикуемую тобой статью, в которой человек столкнулся стой же проблемой      

 

Я ее не критикую , я громко кричу - что "уникумов", подобных тому дэбилу с хабра,надо гнать ссанными тряпками.

Мало того что он "решает" несуществующие проблемы.

Так оно умудрился "портировать" модбас по старым идиотским шаблонам с таймером и это на STM32F373 

на котором есть аппаратная поддержка  модбас и RTU и ASCII...

dosikus
Offline
Зарегистрирован: 11.03.2017

И о да!

nik182, на хабре вся суть в камментах.

И что же мы видим? Вот это поворот...

Так о какой "проблеме" ты глаголил? У вас - у тебя и афтора с хабра одна проблема...

22 марта 2016 в 18:40
  •  
  •  
0
По поводу костыля. Вы обрабатываете событие TXE передатчика, поэтому линия DE деактивируется в момент начала передачи последнего байта, а не тогда, когда этот байт уже целиком «выдвинется». Поэтому либо Ваш костыль, либо после записи последнего байта нужно ждать события TC (transmission complete).
  • 22 марта 2016 в 20:45
    •  
    •  
    •  
    •  
    0
    Я не совсем понял. Я же сам управляю направлением передачи, нет?
    По поводу TC: я смотрел исходники HAL, и там TC вызывается программно. Или есть возможность получить это прерывание аппаратно?
    Но идея мне понравилась, можно перенести переключение направления передачи прямо в обработчики прерываний и посмотреть что получится.
    • 24 марта 2016 в 14:32
      •  
      •  
      •  
      •  
      0
      Бит TC в регистре статуса, прерывание от него маскируется битом TCIE в USART_CR1.
      Вызов pxMBFrameCBTransmitterEmpty() в UART_IRQ_Handler() при передаче последнего байта вызывает vMBPortSerialEnable( TRUE, FALSE ), что выключает DE в то время как этот байт только начал передаваться по линии.

 

b707
Онлайн
Зарегистрирован: 26.05.2017

FoxJone пишет:

Ну блин, элементарный же лисапед то. Я думал, у всех такая есть.

void pause(long ptime) {
  long micro = micros();
  while ((micros() - micro) < ptime) {}
}

 

мне даже как-то неудобно это говорить - но вы думаете это хоть чем-то лучше delay() ? - нисколько!

Стандартный делай точно так же использует микрос, только в нем еще yield() есть, потенциально позволяющий не полностью блокировать МК...

А ваша пауза полностью блокирующая.

Вот вам для примера исходный код delay

void delay( unsigned long ms )
{
  if (ms == 0)
  {
    return;
  }

  uint32_t start = micros();

  while (ms > 0)
  {
    yield();
    while (ms > 0 && (micros() - start) >= 1000)
    {
      ms--;
      start += 1000;
    }
  }
}