Ну да, неблокирующие задержки это именно то, что в protothreads
делается почти без обвеса. Но требует дисциплины программирования,
поскольку не будут работать локальные переменные, их придется
заменять статическими. Или взять вариант на С++ и там можно
заменять локальные переменные переменными экземпляра объекта. Но я обычно не делаю "чистый sleep", а делаю "миницикл ожидания нескольких событий".
char Splash(uint8_t in, char out){
static uint8_t T[8];
static struct pt proc[8];
struct pt *pt = proc+in;
PT_BEGIN(pt);
PT_WAIT_WHILE(cmd_on & _BV(in));
_On(out);
Timer_RST(T+in);
while(1){
PT_YIELD(pt);
if(cmd_on & IOPort & _BV(in)){
fault &= ~_BV(in);
break;
};
if(cmd_off & ~IOPort & _BV(in)){
fault &= ~_BV(in);
break;
};
if(Timer_SECS(T[in]) > 5){
fault |= _BV(in); break;
};
};
_Off(out);
PT_END(pt);
};