你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32 dds

[复制链接]
gujiamao 发布时间:2015-5-3 10:39
本帖最后由 gujiamao 于 2015-5-3 10:41 编辑


最近要用到正弦波,就用STM32内部的DAC产生。
思路主要有以下三个:
1.用matlab或者excel产生一个N长度的正弦码表,如果要产生频率为f的正弦波,则每隔fclk / (N * f)个定时器中断给DAC的数据寄存器赋值一次(fclk是定时器中断频率);
2.根据定时器频率fclk和信号频率f计算出一个周期内点的个数N = fclk / f,动态生成正弦码表,则每个定时器中断给DAC的数据寄存器赋值一次;
先总结下,思路1和思路2的方法差不多,在频率的范围上,f = fclk / (N * M)(M是多少个中断赋值DAC),思路2的M为1,频率范围应该更大些;
                                                       在波形的美观上,思路1更好些,因为频率大的时候,2中的点数会少,导致波形中高频能量比较大;
但是,都是时钟的分频,比如说fclk / 8, fclk / 16,两者之间的频率是肯定产生不了的。
以上的方法都不尽如人意。
想到在学校里参加电子设计比赛时,用过AD9850产生过正弦波,为何不用DDS的原理实现呢?
1.高速dac; 2.正弦码表;3.相位累加器;4.低通滤波器,STM32都有,试一试呗。

3.DDS的方法:以下是个人的理解,不知道对不对。sin(ΔΦ) = sin(w*t) = sin(2*pi*f*Ts),其中f是要得的信号频率,Ts = 1 / fclk, fclk是定时器中断频率,相位Φ就是ΔΦ的不断累积。
程序里是这么做的,当串口输入f时,计算出delta_phase_temp = 2.0 * f / fclk,显然这是一个浮点数,总不能在中断内部计算浮点数吧,听同事说有一个Q15的数据格式,将浮点数
转化成short类型的方法,网上查了下,发现STM32的DSP库里有这样的东西,能够快速计算出某相位的正弦值(下面会介绍),接下来把delta_phase_temp 转换成Q15格式,
delta_phase = float_to_Q15(delta_phase_temp),这样基本工作就OK了,接下来打开定时器中断,写中断服务程序,主要就是相位累加和计算出给DAC赋值的数字量,
phase +=  delta_phase,相位累加够简单吧,给DAC赋值的数字量就是此相位对应的正弦值啦,这就用到了CMSIS的DSP库里面的东东了,第一次接触,感慨,聪明人真的太多了,
Q15的格式不说了,避免浮点运算,选用查表法,自己怎么想不出来呢。
下面的函数就是把Q15格式的theta算成Q15格式的正弦值,函数我就不分析了,论坛里大大们一看就懂。
void arm_sin_q15(q15_t theta, q15_t* pSinVal)
{
        q15_t x0;
        q15_t y0,y1;
        q15_t xSpacing = 0xB6;
        unsigned int i = 0;
        q15_t oneByXSpacing;
        q15_t out;
        unsigned int sign_bits;
        short firstX = 0x8000;
        i = (unsigned int)(theta - firstX) / (unsigned int)xSpacing;
        if(i < 0){
                i = 0;
        }
        else if(i >= 358){
                i = 358;
        }
        x0 = (q15_t)firstX + ((q15_t)i * xSpacing);
        y0 = SinTabQ15;
        y1 = SinTabQ15[i + 1u];
        sign_bits = 8u;
        oneByXSpacing = 0x5A00;
        out =(((q15_t) (((int) (theta - x0) * oneByXSpacing) >> 16)) << sign_bits);
        *pSinVal = y0 + ((q15_t) (((int) (y1 - y0) * out) >> 15));
}
算出Q15格式的正弦值之后,当然还是转成0~1之间的浮点数啦,之后再进行DAC赋值,dac_ch2.write((int)(Q15_to_float(sin) * 4095));
下午看了下效果还不错,当然没有AD9850产生的波形准而好看了。等去公司了,上点图看看。
相比思路1和2,思路3的明显方法好多了。
1 收藏 1 评论2 发布时间:2015-5-3 10:39

举报

2个回答
stary666 回答时间:2015-5-3 15:10:48
沙发,支持原创
moyanming2013 回答时间:2015-5-4 14:11:23
路过看看。。。。。。。

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版