Shop OBEX P1 Docs P2 Docs Learn Events
sine-wave — Parallax Forums

sine-wave

caskazcaskaz Posts: 957
edited 2010-03-09 05:23 in Propeller 1
Hi,.

I try to make sine-wave.
But wave is DC 1.66V to check by oscillooscop.
Connected RC-cuicuit at P0. R=1kohm C=103

CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
OBJ
  sin : " sine_wave"
PUB
  sin.start(0,1)




sin_wave.spin
VAR
  long  dira_, ctra_, cnt_

PUB start(pin, freq) : cog
  dira_ := |< pin
  ctra_ := %00110 << 26 + pin   'DUTY single-end
  cnt_ := clkfreq/(8192 * freq)
  cog := cognew(@entry, @dira_)
  
DAT
entry       org
              mov       t1,par
              rdlong    dira,t1                 ' dira_ 
              add       t1,#4  
              rdlong    ctra,t1                 ' ctra_
              add       t1,#4    
              rdlong    period, t1              ' cnt_
              mov       degree,#0
:loop        test      degree,sin_90  wc       ' get sine quadrant 2|4 int  c        
              test      degree,sin_180 wz       ' get sine quadrant 3|4 into nz 
              negc      degree,degree           ' if sine quadrant 2|4, negate table offset 
              or        degree,sin_table        ' insert sine table base address >> 1 
              shl       degree,#1               ' shift left to get final word address 
              rdword    t1,degree               ' read sine word from table 
              negnz     t1,t1                   ' if quadrnt 3|4, negate word
              shl       t1,#15
              add       t1,level
              mov       frqa,t1
              add       degree,#1
              mov       time, cnt
              waitcnt   time,period
              jmp       #:loop

sin_table     long      $0000E000 >> 1
sin_180       long      $00001000
sin_90        long      $00000800
level         long      $7fffffff

degree        res       1
t1            res       1
period        res       1
time          res       1




I think to not get value of sine_table.
But I can't find out where is incorrect code.

Please teach me advice.

Post Edited (caskaz) : 3/9/2010 5:43:11 AM GMT

Comments

  • pullmollpullmoll Posts: 817
    edited 2010-03-08 07:03
    caskaz said...
    Hi,.

    or degree,sin_table ' insert sine table base address >> 1
    shl degree,#1 ' shift left to get final word address

    But I can't find out where is incorrect code.

    I think it's these two lines, because degree can be negative, i.e. $ffff in the upper 16 bits. Using OR to add the base address of the sin table does not work as expected in this case. You'd have to use:
             ...
             shl   degree, #1
     if_c   add degree, sin_table_end
     if_nc add  degree, sin_table
             ...
    sin_table long $e000
    sin_table_end long $f001
    
    


    So in the case of carry set, the negative value is used to index the sin_table down from its end.

    Edit: you also have to use another loop variable instead of 'degree', because degree is modified inside the loop. Just copy this loop variable to degree at the :loop label.

    HTH,
    Juergen

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    He died at the console of hunger and thirst.
    Next day he was buried. Face down, nine edge first.

    Post Edited (pullmoll) : 3/8/2010 8:39:12 AM GMT
  • caskazcaskaz Posts: 957
    edited 2010-03-09 05:23
    Hi, pullmoll.
    Thank you foy your advise.

    It fine works.

    DAT
    entry       org
                  mov       t1,par
                  rdlong    dira,t1                 ' dira_ 
                  add       t1,#4  
                  rdlong    ctra,t1                 ' ctra_
                  add       t1,#4    
                  rdlong    period, t1              ' cnt_
                  mov       time, cnt
                  add       time,period
                  mov       degree,#0
    :loop        test      degree,sin_90  wc               
                  test      degree,sin_180 wz     
                  mov      t2,degree
                  and       t2,mask
                  negc      t2,t2                  
                  shl        t2,#1             
    if_c         add       t2,sin_table_end
    if_nc       add        t2,sin_table
                  rdword    t1,t2
                  negnz     t1,t1              
                  shl       t1,#15
                  add       t1,level
                  mov       frqa,t1
                  add       degree,#1
                  
                  waitcnt   time,period
                  jmp       #:loop
    
    sin_table          long      $0000E000
    sin_table_end    long      $0000F001
    sin_180           long      $00001000
    sin_90             long      $00000800
    level                long      $7fffffff
    mask               long      $000007ff
    degree             res       1
    t1                  res       1
    t2                  res       1
    period             res       1
    time               res       1
    
    

    Post Edited (caskaz) : 3/9/2010 9:14:52 AM GMT
Sign In or Register to comment.