zum PWM: genau, entweder es reicht, wenn man das Flackern läßt , oder man legt wirklich einen Tiefpaß dazwischen.
Zum ICE-Bahnhof: Der Mega88 kann eher mehr. Unter Assembler ist einiges zu beachten: Da er jetzt wegen der zusätzlichen Hardware eh nicht mehr mit 64 I/O-Registern auskommt (Zugriff geht bis dahin unter Assembler mit in/out), müßten einige Register darüber angeordnet werden (Zugriff mit LDS/STS (erfordert mehr Takte). Dabei wurden die Alten Register auch etwas aufgeräumt (beim Mega8 verwenden UCSRC und UBRRH dasselbe Register als 7-bit-Register. Dabei entscheidet das MSB des zu schreibenden Bytes, ob man das UBRRH oder das UCSRC meint. Beim lesen wird erst das UBRRH gelesen, liest man im Takt direkt danach (eventuelle Interrupts ausschließen!) nochmal das Register, erscheint jetzt der Wert des UCSRC.
Ist auch gerade nicht einfach...
Aber wie schon gesagt - Du verwendest eine Hochsprache, die sich um derlei Details zu kümmern hat.
Unterschiede zwischen Mega8 und Mega88
Edit: Du mußt Dich entscheiden - entweder Blinken lassen (quasi PWM mit sichtbaren Frequenzen), oder Dimmen (PWM mit Frequenzen, wo das Blinken verwischt - wobei je nach geforderter "Glätte" gefiltert werden muß (Tiefpaß)
Noch ein Wagon an Deinem Zug: Derzeit wird im Compare-Match eine ISR ausgeführt, in der Du ein Flag umsetzt, welches Du im Hauptprogramm abfragst, und dementsprechend alle Pins von PortB setzt.
Das könntest Du genauso bereits in der ISR machen (statt dem Flag). Wenn nur ein Pin reicht, kannst Du diesen auch durch die Hardware selbständig umsetzen lassen, ohne daß dazu das Hauptprogramm überhaupt unterbrochen wird. Such mal nach Compare Output Mode im Datenblatt...
(Hier bietet der 88 zB mehr als der 8 )