Timer gestuurde looplicht

Hallo ,ik ben bezig met een looplicht dat aan te sturen is met RS232. Alleen heb ik een probleemje met een paar stukken en ik kom er niet aan uit.
De code die ik heb werkt half , ik kan geen drukknop gebruiken samen met een RS232 command. Wanneer ik bv command 'H' stuur voert hij de instructie maar één keer uit. Ook moet ik een Timer gebruiken ipv van een delay om snelheid te regelen, dit lukt mij niet omdat ik de hele code in de ISR zet.

ATmega324PA

c code:

#define F_CPU 8000000UL /*systeemklok*/
#include <avr/io.h>
#include <util/delay.h>
#include "UART_routines.h"
uint8_t alf = 0;
uint8_t LED = 0x01;
uint8_t i = 0;


int main(void)
{
	DDRA=0x00;
	DDRB = 0xFF;
	PORTB= 0xFF;
	
	UART0_Init(9600);
	_delay_ms(100);
	while(1){
		char i=1;	
                            // drukknop om links of rechts lopend licht te krijgen over 8 leds
		if (~PINA & 0x04){	
			while (i<128){
			i=i*2;
			PORTB = ~i;
			_delay_ms(150);
			     }
			}
		else {
		 i=128;
		 while (i>0){
		  i=i/2;
		   PORTB = ~i;
		  _delay_ms(150);
			}
		}
												// met RS232 commando's geven ( S= Stop, H=Heen en weer,R=Rechts,L=Links)
		if (UART0_Receive_Ready() == 128){
			alf = UART0_Receive();
			if( alf =='H'){       
				            
				while (i<128)						// heen en weer lopen
				{
					i=i*2;
					PORTB = ~i;
					_delay_ms(150);
				}

	                while (i>0){
		                    i=i/2;
		                    PORTB = ~i;
		                    _delay_ms(150);
							}
						}
			
			if( alf =='L'){           // links lopen
				i=128;
				while (i>0)
				{
					i=i/2;
					PORTB = ~i;
					_delay_ms(150);
				}
			}
			
			if( alf =='R'){        
				               // rechts lopen
					while (i<128)
					{
						i=i*2;
						PORTB = ~i;
						_delay_ms(150);
						}
					}	
				}
				
				if( alf =='S'){   // Stop het looplicht
					PORTB = 0xFF;
				}
			}		
	     }

Tamelijk onleesbaar op deze manier. Gebruik je tabs ipv spaties?

En ik zie nergens een ISR...

Je moet die alf niet gebruiken want die is na het indrukken weer 'leeg' neem ik aan.

if alf!='' { lastalf =alf; }

Zoiets ertussen zetten.

Programmeertechnisch: je herhaalt heel vaak dezelde code:
while (i<128)
{
i=i*2;
PORTB = ~i;
_delay_ms(150);
}
}

Dat moet helderder kunnen. Want het enige verschil is dat je beweging links (*0.5) rechts (*2) of stil (*1) doet.