2299 views|2 replies

1w

Posts

25

Resources
The OP
 

【RPi PICO】DDS sine generator and dual PWM output [Copy link]

 

From: https://forum.micropython.org/viewtopic.php?t=9945&p=55587#p55587

The sine generator of the DDS is generated using the second core. To achieve higher resolution and higher frequency, it adds 2 PWM signals, each 6 bits.

# 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<<10)
pwmB.duty_u16(31<<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[x]= 2047+int(2047*math.sin(xr)) # 12 bit resolution
    #print(sineBuf[x])

pwmA.duty_u16(0<<10)
pwmB.duty_u16(0<<10)

ddsCtrl = uarray.array('i',[
    0x40050000 + 0x98, # 0 cc7
    sineBufLen, # 4
    1, # 8 
    int((1<<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, [r1,4]) # buffer length
        
    ldr(r4, [r1,0]) # pwm counter compare register
    ldr(r7, [r1,12]) # 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,[r0,0]) # read buffer     regPoke(0x40050000 + 0x98, ((a>>6)<<16) + (a&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,[r4,0])
    #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, [r1,12]) # reload step index repeat?
    cmp(r7,0)
    bne(nextVal)
    
    label(retu)

    


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

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

def setF(f):
    ddsCtrl[3]=int(f/1000*(1<<16))

#sineBuf[0]=1<<6
#print(dds(sineBuf, ddsCtrl))
_thread.start_new_thread(dds, (sineBuf, ddsCtrl))


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

   
"""
x=0
delta=10


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

Latest reply

I haven't played it, but I give it a thumbs up!!!   Details Published on 2021-3-3 19:41

赞赏

1

查看全部赞赏

 
 

6552

Posts

0

Resources
2
 

Sine generator for DDS

Thanks for sharing

 
 
 

1942

Posts

2

Resources
3
 

I haven't played it, but I give it a thumbs up!!!

 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list