Ами функцията delay се осланя на системният такт.
Ти като компилираш сетваш един глобален define, с който казваш, че clock-a с който захранваш системата е 16MHz (ако не си го сетнал default-a е 1MHz).
Това обаче е нещо, което ти просто обещаваш на компилатора и той ти вярва. А истинската стойност, която е нагласена хардуерно в микроконтролера се настройва с fuses.
Ако погледнеш в секцията
Fuse Bits на ATmega328/P datasheet ще видиш
1) CKSEL бит-овете са настроени по default за 8MHz
2) CKDIV8 ти е сетнат пак по default. Това значи, че клок-а ти се дели на 8, което ти дава ефективен такт от 1MHz
Другото голямо проблем, е че тези функции са мислени само за кратки чакалъци (примерно switch debouncing)
В документацията на хедъра
delay.h четем, че максималната стойност на чакалнята е
The maximal possible delay is 262.14 ms / F_CPU in MHz.
Което значи при такт от:
1MHz -> 262.14 ms
8MHz -> 32.8 ms
16MHz -> 16.4 ms
При по-големи зададени стойности от максималните, функциите започват да разтягат локуми и не са точни.
Ето ти един
fuse-калкулатор скойто можеш да си пресметнеш стойностите за 3-те байта.
Много внимавай кои bits ще сетнеш, защото може да си направиш микроконтролера неизползваем.
Бих те посъветвал RSTDISBL, SPIEN и DWEN да не ги бараш. Т.е. не да не ги сетваш, а да ги остваиш така както са си!
Командата за четене на актуалните стойности с avrdude ще ти изглежда нещо такова
avrdude -c avrisp2 -P /dev/ttyUSB0 -p m328p -n -v
Порта естествено трябва да си го нагласиш. Също така и не разбрах atmega328 или atmega328
p имаш. Съответно махаш от командата 'p'-то ако трябва.