树莓派4与AD9833 SPI通信Python实现的频率输出异常求助
AD9833 DDS模块600Hz输出异常问题分析
核心问题排查
发送函数的变量拼写错误
代码中send_data函数里的spi.xfer([tx_msb,txlsb])存在笔误:txlsb应为tx_lsb。这个错误会导致发送无效的LSB字节,直接破坏频率寄存器的写入数据。对于600Hz对应的频率字,该错误会让LSB完全偏离预期值,最终输出频率不符。复位指令未解除
AD9833的0x2000是复位控制字(RESET位置1),此时芯片处于复位状态,内部频率累加器停止工作,输出固定电平。仅发送复位指令而不发送解除复位的控制字(如0x0000,RESET位置0),芯片无法正常生成波形。之前部分频率看似正常,是复位前的寄存器数据未被完全清除的偶发现象,600Hz的写入刚好触发了复位状态下的异常。频率计算精度验证
600Hz对应的频率字计算逻辑无问题:freq_word = int(round(float(600 * 268435456) / 25000000))计算结果为
6442,代入AD9833频率公式:
[
F_{out} = \frac{25MHz \times 6442}{2^{28}} \approx 599.95Hz
]
该结果与目标600Hz的误差属于正常精度范围,计算逻辑本身无问题。
修正后的代码片段
import time import spidev spi = spidev.SpiDev() spi.open(0,1) spi.max_speed_hz = 976000 freq_out = 600 Two28 = 268435456 phase = 0 def send_data(input): tx_msb = input >> 8 tx_lsb = input & 0xFF spi.xfer([tx_msb, tx_lsb]) # 修正变量名拼写错误 print(hex(input)) freq_word = int(round(float(freq_out * Two28) / 25000000)) MSB = (freq_word & 0xFFC000) >> 14 LSB = (freq_word & 0x3FFF) LSB |= 0x4000 MSB |= 0x4000 phase |= 0xC000 # 正确操作顺序:复位→写入频率→写入相位→解除复位 send_data(0x2000) # 复位芯片 send_data(LSB) # 写入频率寄存器LSB send_data(MSB) # 写入频率寄存器MSB send_data(phase) # 写入相位寄存器 send_data(0x0000) # 解除复位,启用输出
额外注意事项
- AD9833要求SPI数据以16位为单位高位先传,修正后的
send_data函数确保了这一通信规范。 - 若仍存在频率偏差,可检查SPI总线的电平匹配(如添加上拉电阻)、AD9833的电源稳定性,或更换更高精度的时钟源(若需更严格的频率精度)。
内容的提问来源于stack exchange,提问作者Prayander Sahatma Siahaan
相关产品推荐
相关产品推荐

