ШИМ-циклов в AVR обычно начинаются с переполнением таймера (за исключением фазы правильной и фазы/частоты правильно ШИМ) ... Другими словами, у вас есть контроль на но не с самого начала. В вашем примере - по каким-либо причинам - вы хотите контролировать начало цикла PWM (в 32 часа от переполнения таймера), а также рабочий цикл (около 20% ... 32h от FFh).
Таким образом, вы можете рассмотреть
- использовать бесплатный запуск таймера генерации прерывания каждые 1/FFh
- использовать один 8-битный регистр, который вы приращение при каждом вызове прерывания (он будет переполнение после FF ... это OK)
- , если этот регистр считывает 32h или 64h, инвертировать выходной контакт (или установки/сброса, как показано ниже)
- инициализировать программу, установив выходной контакт 0 до SEI
Я быстро угнали один из моих PWM LED вещи на моем AT90USBKEY2 - используя AT90USB1287 процессор - и модифицировали его в соотв. вышеупомянутому (извините код немного длинный: -o ... смотри ниже)
Edit:
Строго говоря, все это имеет смысл только если у вас есть точка синхронизации ... если вы смотрите на 20% -ную форму сигнала в изоляции, которую вы не можете определить, если она начинается с временного интервала 0x00
или 0x32
... осциллограф всегда будет синхронизироваться на восходящем (или падающем) фронте импульса. Таким образом, вам нужно будет предоставить ссылку на начало кадра ШИМ путем вывода импульса на другом выводе при переполнении PWM_SUBLEVEL
. Используя этот импульс от другого вывода в качестве источника синхронизации для осциллографа, вы начинаете видеть переход фазы при начале изменения 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, and 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 A
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 A
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 A
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 A
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 from 1 to 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) for PWM sublevel
; we use this for PWM as Timer2 has the 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 us
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 we get here something is wrong
sbi PIND, PIND7 ; invert output by writing 1 to input bit in output mode
reti
Вам нужен только один импульс или что-то еще? Похоже, PWM должен уметь отлично справляться с этим. – tangrs
Нет, я вообще не хочу полной волны. Примерно за один импульс я думаю, что это работает. На самом деле я хочу знать, что изменение вручную OC0 будет влиять на внутренние функции PWM или нет? –
Я до сих пор не знаю, зачем вам это нужно. Сигнал PWM будет периодическим, так что неважно, где вы начинаете? – tangrs