Che Guevara
04.03.2012, 23:41
Hallo,
nachdem ich mein erstes Problem mit dem XMega erfolgreich gelöst habe, taucht jetzt das nächste auf:
Ich möchte mithilfe des Event-Systems und des DMAs eine PWM einlesen, sodass ich keine Interrupts benötige. Vorgestellt habe ich mir das folgendermassen:
-EventSystem Channel0 reagiert auf die PWM (fallende Flanke, momentan noch ein Taster an PortE.0)
-EventSystem Channel1 reagiert auf den TimerC0 Overflow (momentan noch 8Bit)
-DMA Channel0 wird von EventSystem Channel1 getriggert und der Timer wird wieder mit dem richtigen Start Wert vorgeladen
-DMA Channel1 wird von EventSystem Channel0 getriggert und der aktuelle Timer Wert wird in eine Variable (pwm_input) geschrieben
Mein Problem ist jetzt folgendes:
Wenn ich den Taster EINMALIG betätige wird die Interrupt Routine von DMA Channel1 unendlich oft aufgerufen (obwohl das nur 1mal passieren sollte). Diese ISR dient mir momentan nur zu debug Zwecken und wird später dann entfernt, sobald ich dieses Problem gelöst habe.
Hier mein Code:
$regfile = "xm64a3def.dat"
$crystal = 32000000
$framesize = 100
$hwstack = 100
$swstack = 100
$lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014
Config Osc = Disabled , 32mhzosc = Enabled
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
Config Com2 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM2:" For Binary As #1
Dim Timer0_reload_value As Byte
Timer0_reload_value = 100
Dim Pwm_input As Byte
Pwm_input = 0
Config Tcc0 = Normal , Prescale = 1024 , Resolution = 8
Tcc0_per = Timer0_reload_value
Config Dma = Enabled , Doublebuf = Disabled , Cpm = Ch01rr23
Config Dmach0 = Enabled , Burstlen = 1 , Chanrpt = Enabled , Tci = Lo , Eil = Lo , Singleshot = Enabled , Sar = Burst , Sam = Fixed , Dar = Burst , Dam = Fixed , Trigger = &H02 , Btc = 1 , Repeat = 0 , Sadr = Varptr(timer0_reload_value) , Dadr = Varptr(tcc0_per)
Config Dmach1 = Enabled , Burstlen = 1 , Chanrpt = Enabled , Tci = Lo , Eil = Lo , Singleshot = Enabled , Sar = Burst , Sam = Fixed , Dar = Burst , Dam = Fixed , Trigger = &H01 , Btc = 1 , Repeat = 0 , Sadr = Varptr(tcc0_per) , Dadr = Varptr(pwm_input)
On Dma_ch1 Timer_ovf_int
Config Porte.0 = Input
Porte_pin0ctrl = &B00_011_010 'enable pullup, react on falling edge
Config Event_system = Dummy , Mux0 = Porte.0 , Digflt0 = 8 Mux1 = Tcc0_ovf
'Settings:
'DMACH0: Trigger = EV_SYS_CH1 (TCC0_OVF) , timer0_reload_value --> tcc0_per
'DMACH1: Trigger = EV_SYS_CH0 (PORTE.1) , tcc0_per --> pwm_input
Enable Interrupts
Config Priority = Static , Vector = Application , Lo = Enabled
Print #1 , "START"
Print #1 ,
Do
Loop
Timer_ovf_int:
Print #1 , "Taster betätigt!"
Return
End
Weiß jemand, warum die ISR so oft aufgerufen wird und wie ich es verhindern kann, sodass PRO Tasterdruck nur EIN dma Transfer durchgeführt wird?
Vielen Dank & Gruß
Chris
nachdem ich mein erstes Problem mit dem XMega erfolgreich gelöst habe, taucht jetzt das nächste auf:
Ich möchte mithilfe des Event-Systems und des DMAs eine PWM einlesen, sodass ich keine Interrupts benötige. Vorgestellt habe ich mir das folgendermassen:
-EventSystem Channel0 reagiert auf die PWM (fallende Flanke, momentan noch ein Taster an PortE.0)
-EventSystem Channel1 reagiert auf den TimerC0 Overflow (momentan noch 8Bit)
-DMA Channel0 wird von EventSystem Channel1 getriggert und der Timer wird wieder mit dem richtigen Start Wert vorgeladen
-DMA Channel1 wird von EventSystem Channel0 getriggert und der aktuelle Timer Wert wird in eine Variable (pwm_input) geschrieben
Mein Problem ist jetzt folgendes:
Wenn ich den Taster EINMALIG betätige wird die Interrupt Routine von DMA Channel1 unendlich oft aufgerufen (obwohl das nur 1mal passieren sollte). Diese ISR dient mir momentan nur zu debug Zwecken und wird später dann entfernt, sobald ich dieses Problem gelöst habe.
Hier mein Code:
$regfile = "xm64a3def.dat"
$crystal = 32000000
$framesize = 100
$hwstack = 100
$swstack = 100
$lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014
Config Osc = Disabled , 32mhzosc = Enabled
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
Config Com2 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM2:" For Binary As #1
Dim Timer0_reload_value As Byte
Timer0_reload_value = 100
Dim Pwm_input As Byte
Pwm_input = 0
Config Tcc0 = Normal , Prescale = 1024 , Resolution = 8
Tcc0_per = Timer0_reload_value
Config Dma = Enabled , Doublebuf = Disabled , Cpm = Ch01rr23
Config Dmach0 = Enabled , Burstlen = 1 , Chanrpt = Enabled , Tci = Lo , Eil = Lo , Singleshot = Enabled , Sar = Burst , Sam = Fixed , Dar = Burst , Dam = Fixed , Trigger = &H02 , Btc = 1 , Repeat = 0 , Sadr = Varptr(timer0_reload_value) , Dadr = Varptr(tcc0_per)
Config Dmach1 = Enabled , Burstlen = 1 , Chanrpt = Enabled , Tci = Lo , Eil = Lo , Singleshot = Enabled , Sar = Burst , Sam = Fixed , Dar = Burst , Dam = Fixed , Trigger = &H01 , Btc = 1 , Repeat = 0 , Sadr = Varptr(tcc0_per) , Dadr = Varptr(pwm_input)
On Dma_ch1 Timer_ovf_int
Config Porte.0 = Input
Porte_pin0ctrl = &B00_011_010 'enable pullup, react on falling edge
Config Event_system = Dummy , Mux0 = Porte.0 , Digflt0 = 8 Mux1 = Tcc0_ovf
'Settings:
'DMACH0: Trigger = EV_SYS_CH1 (TCC0_OVF) , timer0_reload_value --> tcc0_per
'DMACH1: Trigger = EV_SYS_CH0 (PORTE.1) , tcc0_per --> pwm_input
Enable Interrupts
Config Priority = Static , Vector = Application , Lo = Enabled
Print #1 , "START"
Print #1 ,
Do
Loop
Timer_ovf_int:
Print #1 , "Taster betätigt!"
Return
End
Weiß jemand, warum die ISR so oft aufgerufen wird und wie ich es verhindern kann, sodass PRO Tasterdruck nur EIN dma Transfer durchgeführt wird?
Vielen Dank & Gruß
Chris