La gestione di motori stepping è un argomento ampiamente trattato nel forum (Topic, topic), la tua idea di utilizzare gli I/O standard per generare frequenze di uscita dell’ordine di 400 Hz ha un problema. Le uscite digitali statiche hanno tempi di On/Off compatibili con i 400 Hz ma è la loro gestione il tallone d’Achille.
Se ipotizzi di utilizzare l’interrupt fast a 1 mS per invertire lo stato di una uscita digitale tu avrai una frequenza in uscita di 500 Hz. Ho fatto delle prove ed è possibile anche scendere con l’interrupt a 500nS con frequenza massima di 1KHz. Ora se tu utilizzi una sola uscita puoi variare il tempo di interrupt (Funzione SysSetTaskLpTime) per avere tutte le frequenze nel range fino ad 1KHz. Ma se le uscite sono più di una è ovvio che variando il tempo di interrupt tutte le uscite cambiano di frequenza.
Per variare la frequenza di ogni uscita puoi solo attendere una o più esecuzioni dell’interrupt per invertire l’uscita ma in tal caso le frequenze sono sottomultipli esatti della frequenza base (Esempio 1KHz, 500Hz, 250Hz, 125Hz…) e non credo vada bene.
Sul mercato esistono drivers economici per motori stepping che si possono gestire via I2C (Vedi questo), in alternativa esistono degli integrati per generare uscite PWM pilotabili da bus I2C (Esempio il PCA9685, 16-channel, 12-bit PWM Fm+ I2C-bus LED controller della NXP).