dcexpert 发表于 2021-3-2 10:37

【RPi PICO】DDS正弦发生器和双路PWM输出

<p>来自:https://forum.micropython.org/viewtopic.php?t=9945&amp;p=55587#p55587</p>

<p>&nbsp;</p>

<p>DDS 的正弦发生器,使用第二个内核生成。为了实现更高的分辨率和更高的频率,它增加了2个PWM信号,每个6位。&nbsp;</p>

<p>&nbsp;</p>

<pre>
<code class="language-python"># DDS Sine Generator in second core by CWE
# Example using Double PWM
# http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/index.html 100k and 1.5k + 4.7nF

import time, _thread, sys
from machine import Pin, PWM
import math
import uarray

# Construct PWM object, with LED on Pin(25).
pwmA = PWM(Pin(15, Pin.OUT)) # upper 6 bits
pwmB = PWM(Pin(14, Pin.OUT)) # low 6 bits


# Set the PWM frequency.
pwmFreq= int(125_000_000/64) # 6 bit
pwmA.freq(pwmFreq)
pwmB.freq(pwmFreq)
pwmA.duty_u16(31&lt;&lt;10)
pwmB.duty_u16(31&lt;&lt;10)

sineBufLen= 6249 #1kHz: 6249
sineBuf=uarray.array("H",range(0,sineBufLen))
for x in range(0,sineBufLen):
    xr= x/sineBufLen*2*math.pi
    sineBuf= 2047+int(2047*math.sin(xr)) # 12 bit resolution
    #print(sineBuf)

pwmA.duty_u16(0&lt;&lt;10)
pwmB.duty_u16(0&lt;&lt;10)

ddsCtrl = uarray.array('i',[
    0x40050000 + 0x98, # 0 cc7
    sineBufLen, # 4
    1, # 8
    int((1&lt;&lt;16)*1.0) # 12 1=run, step in half
    ])

@micropython.asm_thumb
def dds(r0, r1): # Buffer, ctrl-array

    mov(r2,r0) # Buffer Start Address
    ldr(r5, ) # buffer length
      
    ldr(r4, ) # pwm counter compare register
    ldr(r7, ) # step index fine
   
    mov(r3,0) # Buffer Index fine
   
    label(nextVal)
   
    lsr(r0,r3,16) # index coarse
    lsl(r0,r0,1) # index coarse half words
    add(r0,r0,r2)
    ldrh(r0,) # read buffer   regPoke(0x40050000 + 0x98, ((a&gt;&gt;6)&lt;&lt;16) + (a&amp;63))
    lsl(r6,r0,26) # get the lowest 6 bit
    lsr(r0,r0,6) # shift bits right (upper)
    lsl(r0,r0,16)
   
    lsr(r6,r6,26) # lower 6 bits
    add(r0,r0,r6)
   
    str(r0,)
    #b(retu)
   
    add(r3,r3,r7) # next buffer index fine
    lsr(r0,r3,16)
   
    cmp(r5,r0) # end not yet reached
    bhi(nextVal)
   
    lsl(r0,r5,16)
    sub(r3,r3,r0)   
    mov(r0,r3)
   
    ldr(r7, ) # reload step index repeat?
    cmp(r7,0)
    bne(nextVal)
   
    label(retu)

   


@micropython.asm_thumb
def regPeek(r0): # Address
    mov(r1,r0)
    ldr(r0,)

@micropython.asm_thumb
def regPoke(r0, r1): # Address, Data
    str(r1,)
    mov(r0,r1)
   
def regSet(adress, mask):
    regPoke(adress, regPeek(adress) | mask)

def setF(f):
    ddsCtrl=int(f/1000*(1&lt;&lt;16))

#sineBuf=1&lt;&lt;6
#print(dds(sineBuf, ddsCtrl))
_thread.start_new_thread(dds, (sineBuf, ddsCtrl))


try:
    while True:
      f=10
      while f&lt;25_000:
            setF(f)
            time.sleep(.2)
            print(f, end=" ")
            f=f*1.5849 #math.sqrt(10)
      
except KeyboardInterrupt:
    ddsCtrl=0
    sys.exit()

   
"""
x=0
delta=10


while True:
    x+= delta
    if x&gt;(sineBufLen-1):
      x-=sineBufLen
    a= sineBuf
    #pwmA.duty_u16( (a&lt;&lt;4) &amp; (255&lt;&lt;8)) # upper 6 bit
    #pwmB.duty_u16( (a&lt;&lt;10) &amp; (255&lt;&lt;8)) # lower 6 bit
    regPoke(0x40050000 + 0x98, ((a&gt;&gt;6)&lt;&lt;16) + (a&amp;63))
    #regPoke(0x40050000 + 0x98, ((a&gt;&gt;6)&lt;&lt;16))
"""
</code></pre>

<p>&nbsp;</p>

Jacktang 发表于 2021-3-2 14:01

<p>DDS 的正弦发生器</p>

<p>谢谢分享</p>

w494143467 发表于 2021-3-3 19:41

<p>没玩,不过点个赞!!!</p>
页: [1]
查看完整版本: 【RPi PICO】DDS正弦发生器和双路PWM输出