delay.c

Т.к. у нас частота встроенного тактового генератора ~16МГц то создадим константу которая отображает величину задержки равную 1мс(также необходимо учитывать то что на исполнение цикла задеркжи уходит примерно 4 такта):

/* constans */
#define DELAY_TICS 16000000 / 1000 / 4

Создадим функцию в которой будет осуществлятся программная задержка:

/* delay_ms */
void delay_ms(unsigned int timeout) {
    volatile static unsigned int counter;
    /* calculate delay */
    counter = DELAY_TICS * timeout;
    /* delay loop */
    while (counter--);
}

Внутри функции осуществляется вычисление задержки и собственно сама задержка. Переменная счетчик объявлена как volatile static unsigned int, это сделанно по причине того что компилятор в режиме оптимизации убирает все функции с нулевым телом, т.к. функция становится нулевой.