View previous topic :: View next topic |
Author |
Message |
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Fri Jul 20, 2018 1:03 am Post subject: Frequency generation |
|
|
I expect this code to generate a 16MHz signal at pin D4 (TCD1A) and a 16/4096MHz signal at pin D5 (TCD1B) however there is no signal at D5:
Code: | Config Portd.4 = Output
Config Portd.5 = Output
Config Tcd1 = Freq , Prescale = 1 , Comparea = Enabled , Compareb = Enabled , Resolution = 16
Tcd1_cca = 0
Tcd1_ccb = 4095
|
The following does generate the expected 16Mhz signals at both D4 and D5:
Code: | Config Tcd1 = Freq , Prescale = 1 , Comparea = Enabled , Compareb = Enabled , Resolution = 16
Tcd1_cca = 0
Tcd1_ccb = 0
|
The following does not generate anything at D5:
Code: | Config Tcd1 = Freq , Prescale = 1 , Comparea = Enabled , Compareb = Enabled , Resolution = 16
Tcd1_cca = 0
Tcd1_ccb = 1
|
The following generates a 158,4KHz signal at D4 and D5. It is correct for D4 but not for D5 which should be 16MHz
Code: | Config Tcd1 = Freq , Prescale = 1 , Comparea = Enabled , Compareb = Enabled , Resolution = 16
Tcd1_cca = 100
Tcd1_ccb = 0 |
In summary
- If Tcd1_cca > Tcd1_ccb both pins show the same signal, corresponding to Tcd1_cca
- If Tcd1_cca > Tcd1_ccb only the pin corresponding to Tcd1_cca outputs a signal
¿Shouldn't each pin show a signal according to its compare value?
Regards
(BASCOM-AVR version : 2.0.7.9 , Latest : 2.0.8.1 ) |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Jul 20, 2018 1:35 am Post subject: Re: Frequency generation |
|
|
hzz wrote: | Shouldn't each pin show a signal according to its compare value? |
Are you kidding? Knowing how hardware timers in these AVRs work, how would you expect one timer to create two different frequencies? |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Fri Jul 20, 2018 11:21 am Post subject: |
|
|
In normal mode it is possibnle to output different frequencies from a single timer using different compare values and compare interrupts. I was expecting to be able to do the same in frequency mode but without using interrupts. (The compiler does allow you to set different values to different compare registers in frequency mode) |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Jul 20, 2018 12:53 pm Post subject: |
|
|
If you use an timer interrupt, you can increase for example within three different variables each by one, compare each one with a different TOP, reset them at TOP and toggle three outputs accordingly.
This will give you three different frequencies on the toggled pins.
But with these three variables, each with different TOP-value you have actually set up three independent software counters, with a granularity of the hardware timer's interrupt period.
In your case you have only one hardware timer, some COMPAREs and one TOP.
Simply have the timer run within your mind, imagine what happens at certain moments of a compare-match or if the timer reaches TOP. And then think about how with one TOP you think to get different frequencies from this hardware. |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Fri Jul 20, 2018 2:36 pm Post subject: |
|
|
Hello MWS,
Since BASCOM allows you to set differet COMPAREs, in frequency mode, I was assuming that in this mode there is also one TOP per COMPARE.
Do you know how could i do this using the event system?
I mean, output 16MHz frequency using:
Code: | Config Tcd1 = Freq , Prescale = 1 , Comparea = Enabled , Compareb = Enabled , Resolution = 16
Tcd1_cca = 0 |
and then using the event system to output trhu another pin one pulse every 4096 tics of TCD1
Thanks
Hector |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Jul 20, 2018 4:12 pm Post subject: |
|
|
hzz wrote: | Since BASCOM allows you to set differet COMPAREs, in frequency mode, I was assuming that in this mode there is also one TOP per COMPARE. |
Even if this would be the case, there is still only one timer. TOP is the value, where the timer resets to zero.
Imagine what would happen, if there would be three TOPs, to which the timer should reset then? The lowest? What sense the other TOPs would make then?
Usually with these AVRs one Compare is configurable for TOP, if you would have read the help, Config TCXX, Table 2:
Quote: | Value_____Mode_____TOP_____UPDATE_____EVENT
1________FREQ______CCA______TOP_______TOP |
then you'd have noticed it's CCA.
Quote: | Do you know how could i do this using the event system? |
In regards of timer-events I probably do not know better than you.
As far I read from the datasheet there are some input-events and two output-events, compare and overflow.
Quote: | I mean, output 16MHz frequency using:
Code: | Config Tcd1 = Freq , Prescale = 1 , Comparea = Enabled , Compareb = Enabled , Resolution = 16
Tcd1_cca = 0 |
and then using the event system to output trhu another pin one pulse every 4096 tics of TCD1 |
It won't work directly, as the event system is no counter and your counter only counts to 0.
As there are input events, it should be possible to daisy-chain the first counters overflow event to a second counters clock-input event. This second counter then is configured for a TOP of 4095, thus its overflow-event can generate the desired action.
I'm not sure how much load this will put on the event system, as there are 16 millions events per second to handle then.
A straightforward approach could be to connect the output pin of the 16MHz timer to a second timer's external clock input pin and configure the second timer as counter.
Last edited by MWS on Fri Jul 20, 2018 4:17 pm; edited 1 time in total |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Jul 20, 2018 4:15 pm Post subject: |
|
|
Btw.: Why don't you use CLKOUT to output the peripheral clock and use a counter to divide by 4096?
Is 32MHz too much for the TLC59401?
If yes, you can set Prescalea to 2, but you loose CPU-speed then.
Last edited by MWS on Fri Jul 20, 2018 4:45 pm; edited 2 times in total |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Fri Jul 20, 2018 4:34 pm Post subject: |
|
|
I was missing the point with the TOP and the need to reset the timer, you are right.
I was doing what you say at the end, connencting the output pin to an input pin configured as a counter. I suppose there is a more elegant solution using the event system.
Thanks for your time! |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Fri Jul 20, 2018 7:58 pm Post subject: |
|
|
You could use event channel 0 as output (available as alternate pin function) and feed the channel 0 with CLK prescaled by 2. This gives you a 16MHz clock.
Then use a counter for the 4096-ticks-interval, output compare match to a second pin.
Configure the two pin as wired-AND and bound them together with a pull up. This should give you in theories a burst 0f 4096 ticks at 16 MHz.
You can then place an interrupt service routine in your counter to:
- drive the lines BLANK and XLAT (as requested in your 2nd Post)
- reset for next cycle (not really necessary - put PER to a little higher value)
To drive the two other lines as fast as possible you can declare a VPORT for these and use assembler directives SBI and CBI which are 1 cycle in xmega. (Probably bascom uses CBI and SBI automatically when using SET/RESET on a VPORT-pin) |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Fri Jul 20, 2018 9:04 pm Post subject: |
|
|
Thanks laborratte
This is what I have done:
Code: | '________________________________________________________________________________
' CONFIG SYSTEM CLOCK
Config Osc = Disabled , Extosc = Enabled , Range = 12mhz_16mhz , Startup = Xtal_16kclk , 32khzosc = Enabled , Pllosc = Enabled , Pllsource = Extclock , Pllmul = 2 ' 16x2=32MHz
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1 ' 32/1=32 MHz
$crystal = 32000000
'________________________________________________________________________________
Disable Jtag
'________________________________________________________________________________
' PORT CONFIGURATION
Led_pcb Alias Portd.0 : Config Portd.0 = Output : Config Xpin = Portd.0 , Invertio = Enabled : Led_pcb = 1 ' on board LED
Tlc_sin Alias Porta.1 : Config Porta.1 = Output ' Connected to SIN
Tlc_sclk Alias Porta.3 : Config Porta.3 = Output ' Connected to SCLK
Tlc_xlat Alias Porta.5 : Config Porta.5 = Output ' Connected to XLAT
Tlc_blank Alias Portd.5 : Config Portd.5 = Output : Tlc_blank = 1 ' SWITCH OFF ALL OUTPUTS Connected to BLANK
Tlc_mode Alias Portb.1 : Config Portb.1 = Output
Tlc_gsclk Alias Portd.4 : Config Portd.4 = Output
'________________________________________________________________________________
'A) The following event system configuration should generate an event for each 2 pulses of the system clock (16M events/s)
Config Event_system = Dummy , Mux0 = Prescaler2 , Digflt0 = 1
Portcfg_clkevout = &B0_0_10_00_00 ' Send Event Channel 0 Ouput to pin D7
' B) The following counter should count channel 0 events;
Config Tcc0 = Normal , Prescale = E0 , Event_source = E0 , Event_action = Capture , Comparea = Enabled ' Normal = no waveform generation, Event Source = Event Channel 0
' Every 4096 pulses there should be an overflow of compareA, which will cause an interrupt
Const T_c0_a = 4095
Tcc0_cca = T_c0_a
On Tcc0_cca Blank_isr Saveall
Enable Tcc0_cca , Med
Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = Enabled
Enable Interrupts
' ---------------------------------------------------------
Do
Loop
' ---------------------------------------------------------
Blank_isr:
Tlc_blank = 1
Tlc_blank = 0
Toggle Led_pcb
' Reload so that it causes an interrupt in 4096 tics
Disable Interrupts
Tcc0_cca = Tcc0_cnt + T_c0_a '
Enable Interrupts
Return
' ---------------------------------------------------------
End 'end program |
However:
A) There is nothing at pin D7 (I expected a 16MHz signal) ¿!?
B) There is an interrupt every ~4,19us (I expected an interrupt every 4096/16=256us) and it doesn't seem to come from the event channel because if I put Mux0 = Prescaler4 instead of Mux0 = Prescaler2 the interrupt is still happening every 4,19us ¿!? |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Sat Jul 21, 2018 3:42 pm Post subject: |
|
|
Thanks enniom,
I have set the counter resolution to Normal but there is no difference; I think it is normal by default. (By the way, the options showed in the editor are Normal, 8, 16 and 32) |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Sat Jul 21, 2018 5:19 pm Post subject: solved |
|
|
Now working:
There is a 16MHz signal at D7 and a pulse at D5 every 257,5ms (4118 tics of D7. It should be 256ms = 4096 tics. I don't understand why is not exact)
Code: | '________________________________________________________________________________
$regfile = "xm128a3def.dat"
$hwstack = 256
$swstack = 128
$framesize = 128
'________________________________________________________________________________
' CONFIG SYSTEM CLOCK
Config Osc = Disabled , Extosc = Enabled , Range = 12mhz_16mhz , Startup = Xtal_16kclk , 32khzosc = Enabled , Pllosc = Enabled , Pllsource = Extclock , Pllmul = 2 ' 16x2=32MHz
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1 ' 32/1=32 MHz
$crystal = 32000000
'________________________________________________________________________________
Disable Jtag
'________________________________________________________________________________
' PORT CONFIGURATION
Led_pcb Alias Portd.0 : Config Portd.0 = Output : Config Xpin = Portd.0 , Invertio = Enabled : Led_pcb = 1 ' on board LED
Tlc_sin Alias Porta.1 : Config Porta.1 = Output ' Connected to SIN
Tlc_sclk Alias Porta.3 : Config Porta.3 = Output ' Connected to SCLK
Tlc_xlat Alias Porta.5 : Config Porta.5 = Output ' Connected to XLAT
Tlc_blank Alias Portd.5 : Config Portd.5 = Output : Tlc_blank = 1 ' SWITCH OFF ALL OUTPUTS Connected to BLANK
Tlc_mode Alias Portb.1 : Config Portb.1 = Output
Tlc_gsclk Alias Portd.4 : Config Portd.4 = Output
Config Portd.7 = Output
'________________________________________________________________________________
'A) The following event system configuration should generate an event for each 2 pulses of the system clock (16M events/s)
Config Event_system = Dummy , Mux0 = Prescaler2 , Digflt0 = 1
Portcfg_clkevout = &B0_0_10_00_00 ' Send Event Channel 0 Ouput to pin D7 (OK 16MHz)
' B) The following counter should count channel 0 events;
Config Tcc0 = Normal , Prescale = E0 , Event_source = 0 , Event_action = Restart , Comparea = Enabled
' Every 4096 pulses there should be an overflow of compareA, which will cause an interrupt
Const T_c0_a = 4095
Tcc0_cca = T_c0_a
On Tcc0_cca Blank_isr
Enable Tcc0_cca , Med
Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = Enabled
Enable Interrupts
' ---------------------------------------------------------
Do
Loop
' ---------------------------------------------------------
Blank_isr:
' Blank pulse
Tlc_blank = 1
Tlc_blank = 0
Toggle Led_pcb
' Reload so that it causes an interrupt in 4096 tics
Disable Interrupts
Tcc0_cca = Tcc0_cnt + T_c0_a '
Enable Interrupts
Return
' ---------------------------------------------------------
End 'end program |
Changes:
Code: | Config Portd.7 = Output 'No wonder thre was nothing at pin D7! |
Code: | ,Event_action = Restart, |
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat Jul 21, 2018 7:49 pm Post subject: Re: solved |
|
|
hzz wrote: | It should be 256ms = 4096 tics. I don't understand why is not exact |
Guess why...
Code: | Blank_isr:
' Blank pulse
Tlc_blank = 1
Tlc_blank = 0
Toggle Led_pcb
' Reload so that it causes an interrupt in 4096 tics
Disable Interrupts
Tcc0_cca = Tcc0_cnt + T_c0_a '
Enable Interrupts
Return |
What happens a after the ISR is called?
ISR entry-code is executed, registers are saved to stack and it takes a few clocks till the reload-to-next-compare command is executed, while the counter is still counting.
Only at this later moment with then increased counter 4095 is added, which is responsible for the additional delay.
Btw., it is nonsense to disable interrupts within the ISR, as interrupts are automatically disabled there.
More even, it is dangerous to enable them before exiting, as then another pending interrupt is immediately executed, while the registers are still on the stack.
May lead to stack overflow.
Btw.II, why don't you use the 4096 ticks counter in CTC-mode? This would give exact timing without lag. |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Sun Jul 22, 2018 12:32 am Post subject: |
|
|
Quote: | It should be 256ms = 4096 tics. I don't understand why is not exact |
Sorry, I meant 256us, not ms, so your explanation clearly acounts for 1,5us extra
Quote: | Btw., it is nonsense to disable interrupts within the ISR, as interrupts are automatically disabled there.
More even, it is dangerous to enable them before exiting, as then another pending interrupt is immediately executed, while the registers are still on the stack.
May lead to stack overflow.
|
Thanks! this is an important point; it is one of those errors very dificult to find when it happens.
Quote: | Btw.II, why don't you use the 4096 ticks counter in CTC-mode? This would give exact timing without lag. |
I'm not sure I understand. There is still a lag to call and return from the ISR.
Simplifying the ISR makes the lag is smaller though.
The following works fine, with the counter in CTC mode
Code: | '________________________________________________________________________________
' TEST OF EVENT SYSTEM
' This program generates a 16MHz signal at pin D7 and a pulse at D5 every 4096 tics of D7
'________________________________________________________________________________
$regfile = "xm128a3def.dat"
$hwstack = 256
$swstack = 128
$framesize = 128
'________________________________________________________________________________
' CONFIG SYSTEM CLOCK
Config Osc = Disabled , Extosc = Enabled , Range = 12mhz_16mhz , Startup = Xtal_16kclk , 32khzosc = Enabled , Pllosc = Enabled , Pllsource = Extclock , Pllmul = 2 ' 16x2=32MHz
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1 ' 32/1=32 MHz
$crystal = 32000000
'________________________________________________________________________________
Disable Jtag
'________________________________________________________________________________
' PORT CONFIGURATION
Tlc_blank Alias Portd.5 : Config Portd.5 = Output
Config Portd.7 = Output
'________________________________________________________________________________
'A) The following event system configuration generates an event for each 2 pulses of the system clock (16M events/s)
Config Event_system = Dummy , Mux0 = Prescaler2 , Digflt0 = 1
Portcfg_clkevout = &B0_0_10_00_00 ' Send Event Channel 0 Ouput to pin D7 (OK 16MHz)
' B) The following counter counts channel 0 events;
Config Tcc0 = 3 , Prescale = E0 , Event_source = 0 , Event_action = Restart
Tcc0_per = 4096 ' When the count reaches 4096 it starts again
On Tcc0_ovf Blank_isr ' When the count reaches 4096+1 it generates an overflow interrupt
Enable Tcc0_ovf , Hi ' which calls Blank_isr
' Interrupts enable
Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled , Hi = Enabled
Enable Interrupts
' ---------------------------------------------------------
Do
Loop
' ---------------------------------------------------------
Blank_isr:
' Blank pulse
Tlc_blank = 1
Tlc_blank = 0 ' Pulse width is ~93,8ns
Return
' ---------------------------------------------------------
End 'end program |
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|