assembly - How to make PWM pulse with 20% duty cycle in AVR? -
i want generate pwm wave in pwm mode of timer0 in atmega8 figure below:

it has 20% duty cycle can't implemented pwm mode alone. have tried using fast pwm mode in reversed mode , tried check tcnt0 until gets 64h can clear oc0 pin when reaches it.
i wondering if method works correctly when clearing oc0 manually?
and here code:
.def = r16 ;general purpose accumulator .org $0000 on_reset: sbi ddrb,3 ;set portb3(oc0) output ldi a,0b01011011 ;set fast pwm mode out tccr0,a ;set prescaler/divider /32 ldi a,32 ;different value out ocr0,a ;for compare main_loop: ploop: in a,tcnt0 ;compare tcnt0 andi a,0x64h ;compare tcnt0 64 make 0 brneq ploop cbi pinb,3 rjmp main_loop;a check timer loop
pwm cycles in avr start timer overflow (except phase correct , phase/frequency correct pwm) ... in other words have control on duty cycle not on start. in example - whatever reasons - want control start of pwm cycle (at 32h timer overflow) duty cycle (ca. 20% ... 32h of ffh).
so may want consider
- to use free running timer generating interrupt every 1/ffh
- use single 8 bit register increment during each call interrupt (it overflow after ff ... that's ok)
- if register reads 32h or 64h, invert output pin (or set / reset below)
- initialize program setting output pin 0 before sei
i hijacked 1 of pwm led things on at90usbkey2 - using at90usb1287 processor - , modified acc. above (sorry code bit lengthy :-o ... see below)
edit:
strictly speaking makes sense if have point of synchronisation ... if @ 20% waveform in isolation cannot determine if starts @ timeslot 0x00 or 0x32 ... oscilloscope sync @ rising (or falling) edge of pulse. need provide reference start of pwm frame output of pulse on different pin @ overflow of pwm_sublevel. using pulse other pin sync source oscilloscope start see move of phase start changing pwm_on.
/* * asmfile1.asm * * created: 19.05.2015 22:01:49 * author: miked */ .nolist .include <usb1287def.inc> .list .def tmp1 = r16 .def tmp2 = r17 .def pwm_sublevel = r18 .def pwm_on = r19 .def pwm_off = r20 .cseg .org 0x0000 jmp v_reset ; 1 $0000 reset external pin, power-on reset, brown-out reset, watchdog reset, , jtag avr reset jmp v_noint ; 2 $0002 int0 external interrupt request 0 jmp v_noint ; 3 $0004 int1 external interrupt request 1 jmp v_noint ; 4 $0006 int2 external interrupt request 2 jmp v_noint ; 5 $0008 int3 external interrupt request 3 jmp v_noint ; 6 $000a int4 external interrupt request 4 jmp v_noint ; 7 $000c int5 external interrupt request 5 jmp v_noint ; 8 $000e int6 external interrupt request 6 jmp v_noint ; 9 $0010 int7 external interrupt request 7 jmp v_noint ; 10 $0012 pcint0 pin change interrupt request 0 jmp v_noint ; 11 $0014 usb general usb general interrupt request jmp v_noint ; 12 $0016 usb endpoint/pipe usb endpoint/pipe interrupt request jmp v_noint ; 13 $0018 wdt watchdog time-out interrupt jmp v_noint ; 14 $001a timer2 compa timer/counter2 compare match jmp v_noint ; 15 $001c timer2 compb timer/counter2 compare match b jmp v_t2ovf ; 16 $001e timer2 ovf timer/counter2 overflow jmp v_noint ; 17 $0020 timer1 capt timer/counter1 capture event jmp v_noint ; 18 $0022 timer1 compa timer/counter1 compare match jmp v_noint ; 19 $0024 timer1 compb timer/counter1 compare match b jmp v_noint ; 20 $0026 timer1 compc timer/counter1 compare match c jmp v_noint ; 21 $0028 timer1 ovf timer/counter1 overflow jmp v_noint ; 22 $002a timer0 compa timer/counter0 compare match jmp v_noint ; 23 $002c timer0 compb timer/counter0 compare match b jmp v_noint ; 24 $002e timer0 ovf timer/counter0 overflow jmp v_noint ; 25 $0030 spi, stc spi serial transfer complete jmp v_noint ; 26 $0032 usart1 rx usart1 rx complete jmp v_noint ; 27 $0034 usart1 udre usart1 data register empty jmp v_noint ; 28 $0036 usart1tx usart1 tx complete jmp v_noint ; 29 $0038 analog comp analog comparator jmp v_noint ; 30 $003a adc adc conversion complete jmp v_noint ; 31 $003c ee ready eeprom ready jmp v_noint ; 32 $003e timer3 capt timer/counter3 capture event jmp v_noint ; 33 $0040 timer3 compa timer/counter3 compare match jmp v_noint ; 34 $0042 timer3 compb timer/counter3 compare match b jmp v_noint ; 35 $0044 timer3 compc timer/counter3 compare match c jmp v_noint ; 36 $0046 timer3 ovf timer/counter3 overflow jmp v_noint ; 37 $0048 twi 2-wire serial interface jmp v_noint ; 38 $004a spm ready store program memory ready v_reset: ; prepare stack ... special write procedure ldi tmp1, low(ramend) ldi tmp2, high(ramend) out spl, tmp1 out sph, tmp2 ; increase clkio 1 8mhz ... special write procedure ldi tmp1, 0b1000_0000 ldi tmp2, 0b0000_0000 sts clkpr, tmp1 sts clkpr, tmp2 ; initialize variables clr pwm_sublevel ldi pwm_on, 0x32 ldi pwm_off, 0x64 ; prepare led ports ; d2-rd on portd4 ; d2-gn on portd5 ; d5-rd on portd7 ; d5-gn on portd6 ldi tmp1, 0b1111_0000 out ddrd, tmp1 ; timer2 (8bit) without prescaler in normal mode ; generates interrupt every 256 cpu clock cycles (32 us) pwm sublevel ; use pwm timer2 has highest priority amongst timers clr tmp1 sts tccr2a, tmp1 ; normal mode, port pins disabled ldi tmp1, (1 << cs20) sts tccr2b, tmp1 ; internal clock, no prescaler ldi tmp1, (1 << toie2) sts timsk2, tmp1 ; overflow interrupt enable sei ; set general interupt enable flag main: rjmp main v_t2ovf: ; fires every 32 inc pwm_sublevel ; overflows every 8.192 ms, f=122.07... hz cp pwm_sublevel, pwm_on breq go_hi cp pwm_sublevel, pwm_off breq go_lo reti go_hi: sbi portd, portd4 reti go_lo: cbi portd, portd4 reti v_noint: ; fire error led ... if here wrong sbi pind, pind7 ; invert output writing 1 input bit in output mode reti
Comments
Post a Comment