Лeoнид Ивaнoвич (29.09.2011 12:29, просмотров: 179) ответил mazur на Про прибавлять значение уже думал. Допустимо использовать один из OCxx выходов. Что-то не получилось выставить при помощи Force Output Compare. Как там можно принудительно выставить ногу в нужное значение? Может я опять что-то не так ляпнул. В
Как пример, реализация DDS с I2S-ЦАПом. Там используется force. DDS: ldi XL,(1<<COM1A0)
out TCCR1A,XL ;OC1A toggle
ldi XL,(1<<COM1A0) | (1<<FOC1A)
out TCCR1A,XL ;set SCK (OC1A force toggle)
Port_I2SWS_0 ;clear WS
out TCCR1A,XL ;clear SCK (OC1A force toggle)
out SPDR,SinH ;---> load DAC high byte
in tsreg,SREG ;save status register
clr r1
add PhaseK,FreqK ;Phase(0..33) = Phase(0..33) + Freq(0..31)
adc PhaseL,FreqL
adc PhaseM,FreqM
adc PhaseN,FreqN
adc PhaseP,r1 ;r1 = 0
mov XL,PhaseN ;XL = wa (word address)
mov r0,PhaseM ;r0 = dx
sbrc PhaseP,0 ;if(Phase.32 == 0)
com XL ;wa = !wa
sbrc PhaseP,0 ;if(Phase.32 == 0)
com r0 ;dx = !dx
ldi XH,high(LUT) ;XH = table base (low(LUT) = 0)
add XL,XL ;offset * 2 (word offset)
adc XH,r1 ;r1 = 0
nop
out SPDR,SinL ;---> load DAC low byte
ld SinL,X+ ;SinL = lo sin[x]
ld SinH,X+ ;SinH = hi sin[x]
ld r1,X ;r1 = lo sin[x + 1]
sub r1,SinL ;r1 = dA
mul r1,r0 ;r1,r0 = dA * dx
rol r0 ;C = 1 if r0.7 == 1
clr r0
adc SinL,r1 ;SinH:SinL = sin[x] + round(r1:r0 / 256)
adc SinH,r0 ;SinH:SinL = A
sbrs PhaseP,1
rjmp ph_cd ;jump if Phase.33 == 0
ph_ab: com SinL ;SIN > 0, data line has NOT gate,
com SinH ;SinH:SinL = !SinH:SinL
rjmp ph_all
ph_cd: sec
sbc SinL,r0 ;SIN < 0, data line has NOT gate,
sbc SinH,r0 ;SinH:SinL = SinH:SinL - 1
ph_all: ldi XL,(1<<COM1A0) | (1<<FOC1A)
out TCCR1A,XL ;OC1A force toggle
out SPDR,r0 ;zero data for another DAC channel
Port_I2SWS_1 ;set WS
ldi XL,(1<<COM1A1)
out TCCR1A,XL ;OC1A clear on compare
out SREG,tsreg ;restore status register
reti