标题: 一个经典的单片机正弦波程序,程序很短但处处是精华 [打印本页]

作者: zhangzhao2423    时间: 2021-12-6 15:44
标题: 一个经典的单片机正弦波程序,程序很短但处处是精华

这是网上找的关于C8051F020利用自身的DAC输出1K HZ的正弦波的程序。我已经用示波器把波形显示出来了,非常完美。程序和示波器的波形已经上传网上了。
但是针对这个程序我有太多的疑问,请高手帮我看一下:
第一:sfr16 RCAP4    = 0xE4;                 // Timer4 capture/reload
         sfr16 TMR4     = 0xF4;                 // Timer4
         sfr16 DAC0     = 0xd2;                 // DAC0 data
         sfr16 DAC1     = 0xd5;                 // DAC1 data

程序有这个定义,我想知道是干什么用的?好像没看到有什么作用。

第二:#define SAMPLE_RATE_DAC 100000L        // DAC sampling rate in Hz
这是DAC的采样率,请问L 是什么单位。
         // <PHASE_ADD> is the change in phase between DAC samples; It is used in
// the set_DACs routine.

unsigned int PHASE_ADD = FREQUENCY * PHASE_PRECISION / SAMPLE_RATE_DAC;
这时两个dac的相位变化,我想知道为什么是这个公式,怎么来的。

第三:TIMER4_Init(SYSCLK/SAMPLE_RATE_DAC);// Initialize Timer4 to overflow
定时器4的溢出为什么是  SYSCLK/SAMPLE_RATE_DAC  ?

第四: DAC0 = SIN_temp ^ 0x8000;
          DAC1 = COS_temp ^ 0x8000;           // Write to DAC1
为什么要或上8000?

最后附上程序和波形图
C8051F020程序: 正弦波输出.zip (36 KB, 下载次数: 39)
视频: 正弦波视频.zip (4.47 MB, 下载次数: 26)



作者: 188610329    时间: 2021-12-8 18:51
第一:sfr16 RCAP4    = 0xE4;                 // Timer4 capture/reload
         sfr16 TMR4     = 0xF4;                 // Timer4
         sfr16 DAC0     = 0xd2;                 // DAC0 data
         sfr16 DAC1     = 0xd5;                 // DAC1 data

程序有这个定义,我想知道是干什么用的?好像没看到有什么作用。

=> 这是寄存器定义,等同于 SFR  P0 = 0x80;  只不过这是16位的。

第二:#define SAMPLE_RATE_DAC 100000L        // DAC sampling rate in Hz
这是DAC的采样率,请问L 是什么单位。
         // <PHASE_ADD> is the change in phase between DAC samples; It is used in
// the set_DACs routine.

=>  L 是 long型的意思,在Keil3 以上时可以不需要加L,但是有些编译器不加 L 的话,默认最大只支持到 65535 , 总之加了绝对不会错。

unsigned int PHASE_ADD = FREQUENCY * PHASE_PRECISION / SAMPLE_RATE_DAC;
这时两个dac的相位变化,我想知道为什么是这个公式,怎么来的。

=> 这个指示程序员自己拟定的一个计算公式,大致的意思是: 频率 * 脉冲精度 / DAC的采样率
至于,具体怎么来的,要问程序员了。


第三:TIMER4_Init(SYSCLK/SAMPLE_RATE_DAC);// Initialize Timer4 to overflow
定时器4的溢出为什么是  SYSCLK/SAMPLE_RATE_DAC  ?
=> 和上面类似,也就是 系统时钟 / DAC的采样率

第四: DAC0 = SIN_temp ^ 0x8000;
          DAC1 = COS_temp ^ 0x8000;           // Write to DAC1
为什么要或上8000?

=> 这里不是或,是 与或  也就是反转最高位,结合 SIN COS来看,就是把正的变负的负的变正的吧。


好像,你就这些问题吧?

作者: lan9863    时间: 2025-3-12 12:18
不错 很棒的程序
作者: keemee    时间: 2025-3-13 06:15
100000L,长整型?




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1