www.kn34pc.com

Форум на силистренските радиолюбители
Дата и час: 17 Юни 2026, 15:37

Часовете са според зоната UTC + 2 часа




Напиши нова тема Отговори на тема  [ 1 мнение ] 
Автор Съобщение
МнениеПубликувано на: 10 Май 2026, 11:34 
Offline
Аватар

Регистриран на: 07 Дек 2006, 17:24
Мнения: 1666
Местоположение: Силистра
просто засъснение:
Код за потвърждение:
for (volatile int i = 0; i < 1000; i++);

Без volatile оптимизаторът (почти) винаги просто игнорира реда (и закъснението).
Зависи от тактовата честота, от натовареността, от времето на Луната ... много неща :smt048 .
Ниска прецизност. Същия ред в друга част на програмата може да доведе до друго забаяне.
---
За фиксация на точността на времето на забавне добре би било да използваме таймерX, SysTick, DWT ...

Полезен линк:
How to use Systick to achieve microsecond (μs) level delay in STM32?
---
Случай от днешния ден: пренасям програмен код за DS18B20 от G030 към F411. Clock от кварц с PLL: от 64 MHz -> на 100 MHz.
DS18 не ще, и не ще, и не ще ... За анализ на времето използвах 8 входов логически анализатор. Първо: не се изпращаха коректно командите по време към DS18. С малка корекция на времето (80 за G030 -> 100 за F411) това стана ОК - командите започнаха да се декодират от датчика и той започна да връща отговор.
Код за потвърждение:
void delay_us(uint32_t us) {
  volatile uint32_t i = 90 * us;
  i /= 10;
  while (i--);
}

Следваше: четене на върнатите данни. И грешки от четенето, и грешки, и грешки, и грешки ...
Прекочих CRC анлиза: температурата самопроизволно скчаше, през 4-10 s за кратко: показваше истинска температура, ново скачане ... до безкрайност.

Първо заподозряно: неточни времена в 1-wire проткокола. От първия път замяната на "простите закъсненията" на "закъснения от DWT" моментално поправи реакцията (без последваща корекция на методите на писане и четене).

Следва като собствен извод: никога повече "просто закъснение" за прецизни дейности. (в псевдо-код: "нищонеправене" -> изпълнявай n-пъти) :crazy

delay в μs с DWT:
Код за потвърждение:
void dwt_init(void) {
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  DWT->CYCCNT = 0;
  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}

void delay_us(uint32_t us) {
  uint32_t cycles = (SystemCoreClock / 1000000) * us;
  uint32_t start = DWT->CYCCNT;
  while ((DWT->CYCCNT - start) < cycles);
}


код:
Код за потвърждение:
delay_us(64);

и резултат с лог. анализатор:


Прикачени файлове:
dwt_64us.jpg
dwt_64us.jpg [ 93.38 KiB | Прегледано 882 пъти ]
Върнете се в началото
 Профил  
 
Покажи мненията от миналия:  Сортирай по  
Напиши нова тема Отговори на тема  [ 1 мнение ] 

Часовете са според зоната UTC + 2 часа


Кой е на линия

Потребители, разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Форумът се задвижва от phpBB® Forum Software © phpBB Group
Преведено от yarnaudov.com