Witam
Przy pomocy Timera0 procesora ATmega168 tworzę falę PWM do sterowania silnikiem bezszczotkowym. Przerwanie od przepełnienia licznika załącza odpowiednie (w zależności od stanu czujników halla wirnika silnika) tranzystory mostka 3-fazowego a przerwanie od porównania wyłącza. Zależy mi na jak najkrótszym czasie wykonywania procedur przerwań.
W zmiennych mam już przygotowane wartości do wysłania do portu i procedury przerwań są dość banalne:
Jak podejrzałem w AVRStudio procedury są rozwijane do:
Czy to jest optymalny kod? Można jakoś zmusić kompilator żeby zrobił to lepiej czy może da się to napisać samemu w assemblerze.
Pozdrawiam
Piotr
Przy pomocy Timera0 procesora ATmega168 tworzę falę PWM do sterowania silnikiem bezszczotkowym. Przerwanie od przepełnienia licznika załącza odpowiednie (w zależności od stanu czujników halla wirnika silnika) tranzystory mostka 3-fazowego a przerwanie od porównania wyłącza. Zależy mi na jak najkrótszym czasie wykonywania procedur przerwań.
W zmiennych
volatile uint8_t pwm_on, pwm_off
ISR(TIMER0_OVF_vect) // przekroczenie timera0 - załaczenie w PWM
{
PORTD = pwm_on;
}
ISR(TIMER0_COMPA_vect) //porownanie timera0 - wylaczanie w PWM
{
PORTD = pwm_off;
}Jak podejrzałem w AVRStudio procedury są rozwijane do:
@0000015B: __vector_16
169: {
+0000015B: 921F PUSH R1 Push register on stack
+0000015C: 920F PUSH R0 Push register on stack
+0000015D: B60F IN R0,0x3F In from I/O location
+0000015E: 920F PUSH R0 Push register on stack
+0000015F: 2411 CLR R1 Clear Register
+00000160: 938F PUSH R24 Push register on stack
170: PORTD = pwm_on;
+00000161: 91800106 LDS R24,0x0106 Load direct from data space - w 0x106 jest pwm_on
+00000163: B98B OUT 0x0B,R24 Out to I/O location
171: }
+00000164: 918F POP R24 Pop register from stack
+00000165: 900F POP R0 Pop register from stack
+00000166: BE0F OUT 0x3F,R0 Out to I/O location
+00000167: 900F POP R0 Pop register from stack
+00000168: 901F POP R1 Pop register from stack
+00000169: 9518 RETI Interrupt return
@0000016A: __vector_14
174: {
+0000016A: 921F PUSH R1 Push register on stack
+0000016B: 920F PUSH R0 Push register on stack
+0000016C: B60F IN R0,0x3F In from I/O location
+0000016D: 920F PUSH R0 Push register on stack
+0000016E: 2411 CLR R1 Clear Register
+0000016F: 938F PUSH R24 Push register on stack
175: PORTD = pwm_off;
+00000170: 9180011E LDS R24,0x011E Load direct from data space - w 0x11e jest pwm_off
+00000172: B98B OUT 0x0B,R24 Out to I/O location
176: }
+00000173: 918F POP R24 Pop register from stack
+00000174: 900F POP R0 Pop register from stack
+00000175: BE0F OUT 0x3F,R0 Out to I/O location
+00000176: 900F POP R0 Pop register from stack
+00000177: 901F POP R1 Pop register from stack
+00000178: 9518 RETI Interrupt return
Czy to jest optymalny kod? Można jakoś zmusić kompilator żeby zrobił to lepiej czy może da się to napisać samemu w assemblerze.
Pozdrawiam
Piotr

![[ATMEGA168][AVRGCC] Przerwania optymalizacja szybkości [ATMEGA168][AVRGCC] Przerwania optymalizacja szybkości](https://80.48.245.227/piotr/robot/mini.jpg)