View previous topic :: View next topic |
Author |
Message |
JamesAus
Joined: 08 Aug 2007 Posts: 50 Location: Australia
|
Posted: Tue Oct 12, 2021 11:38 pm Post subject: ATMEGA4809 TCA0 Split mode PWM 100% duty? |
|
|
Hi All,
I've been playing around with the TCA0 on the 4809 in split mode for generating >3 PWM outputs, which in itself has been a bit of a learning curve. I would like to output from 0 - 100% duty, but this is not possible, with the maximum duty being 1 cycle less than 100%. Has anyone done the same and come up with an elegant solution?
Thanks
James
(BASCOM-AVR version : 2.0.8.4 ) |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Wed Oct 13, 2021 11:47 am Post subject: |
|
|
it is always a good idea to show some code.
you mean you get 0-99 ? instead of 0-100 ? _________________ Mark |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Wed Oct 13, 2021 1:20 pm Post subject: |
|
|
As I understand the datasheet you should get a 100% on time if you set the periodic (LPER and HPER) registers to &HFE and compare registers (LCMP0 ... HCMP2) to &HFF.
sorry, no possiblities to verify this in real hardware. |
|
Back to top |
|
|
JamesAus
Joined: 08 Aug 2007 Posts: 50 Location: Australia
|
Posted: Fri Oct 15, 2021 6:08 am Post subject: |
|
|
My understanding is that in split mode the high and low become completely separate 8 bit timers sharing only the clock, with period and duty able to be set independently. In the little bit of code below ramping up and down works perfectly for TCA0_CMP2H = 0 resulting in the output being off, as it should. However in the case of TCA0_CMP2H = 200 ( top count as set by TCA0_PERH ) the output is high with the exception of one clock cycle where the output goes low. This is covered in the datasheet, however I was hoping there was a simple trick to get around it.
Laborratte if CMPxH exceeds the PERH by 1 you get a constant low output, regardless of whether it's set at &HFF, &HFE or any arbitrary value below that.
I did see a post elsewhere about this suggesting to set the DDRx to set the pin as an input at / for 100% duty and use a pullup (Or internal pullup). This is not really ideal though.
Code: |
'Demonstration of Split mode PWM on WO5 Alt pin using ATMEGA4809-XPRO eval board
'WO5 Alternative pin (PB.5) is used for visual assesment - This is the LED
$regfile = "mx4809.dat"
$crystal = 4000000
$hwstack = 16
$swstack = 16
$framesize = 24
Config Sysclock = 16_20mhz , Prescale = 4 , Clockout = Disabled '16MHz / 4 = 4MHz
DIM Brightness As Byte
Config Port_mux = Overwrite , TCA0 = ALT1_PB0PB5 'WO5 on alternate pin
Config Portb.5 = Output 'WO5 output
Config TCA0 = PWM , Prescale = 1 , Resolution = Byte , Compare2H = Enabled , Run = On
TCA0_PERH = 200 'PWM frequency (counts to OVF) (Clock freq / this value = fequency: 4MHz / 200 Counts = ~20kHz)
Do
While Brightness < 200 'PWM Duty Ramps from low to high
Incr Brightness
TCA0_CMP2H = Brightness
Waitms 5
Wend
WAIT 10 'Hold PWM Duty at max for 2 seconds
While Brightness > 0 'PWM Duty ramps from high to low
Decr Brightness
TCA0_CMP2H = Brightness
Waitms 5
Wend
WAIT 10 'Hold PWM Duty at 0 for 2 seconds.
Loop
End
|
|
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Fri Oct 15, 2021 10:34 am Post subject: |
|
|
Yes, sorry, you are right. I misssed the "Down Count Only" behaviour of split mode. And it makes sense: if the counter reaches zero output is set to low, if CMP > PER it will never set back to high.
So I don't see an automatic way as in normal upcounting single slope mode. I'm afraid you have to catch the 100% state manually and set the pin directly, either by setting the coresspondending CMP-Enable-Bit in CTRLB register of the timer - assuming the OUT register of your pin is set to high - or by inverting the pin in its control register.
I would implement a small sub for that, something like
Code: | 'catching 100% value and setting pin override
sub setpwmvalue(value as byte)
if value >= 200 then
TCA0_CTRLB.HCMP2EN = 0
else
TCA0_CMP2H = value
TCA0_CTRLB.HCMP2EN = 1
end if
end sub
|
|
|
Back to top |
|
|
|