|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机正弦波发生器(1~100KHZ) 用DAC0832+定时器中断实现
) @( {$ Q5 I/ K X! K3 z& ]: C/ x# O( X& H; k
1 `4 a N! u4 I( |- @: ]' e! U6 E下面给出一个设计实例,在实例中通过定时器中断和DAC0832结合的方式来产生1~100KHZ的正弦波,幅度为0-Vcc/2。
$ T. {4 E- g9 }7 y/ l3 B; x1 ^首先按照下面的公式建立一个正弦波样本表,样表中将一个正弦波周期分成128个点,每个点按7位量化(127对应最高幅度Vcc/2):: f0 z( G4 W$ c. f4 x! o
f(x) = 64 + 63 * sin(2πx/180) x∈[0…127] $ n/ s/ Z' U0 Z
程序中使用16位定时器0产生取样中断,及定时器0的中断时间即为正弦波的采样周期。(T=1/(f*64))。本例中将正弦波分成64个采样点输出,及每隔两个点要从采样样本中取出一个数DAC0832的输入。
% b; ~/ \" D( G* t% i; T单片机源程序:
. _5 d" W; x, R6 z- U# I#define SIN_GLOBAL 1" Z, F. w; X& i) M! Q
#include "sin.h"
, B3 I: Q3 W9 L$ f+ S//正弦波128个采样点寄存数组 ; n6 R( a5 H( t
code uchar Sin[128] = {( `% e# P. s4 x/ T
64,67,70,73,76,79,82,85,88,91,94,96,99,102,104,106,
9 q) ]: l- T- C/ e6 u" S. R 109,111,113,115,117,118,120,121,123,124,125,126,126,5 k/ \2 v+ ^3 \' S1 C
127,127,127,127,127,127,127,126,126,125,124,123,121,3 |3 {' ]/ M& R2 z y8 Z4 D; q
120,118,117,115,113,111,109,106,104,102,99,96,94,91,
7 {) i: k/ u2 O% o 88,85,82,79,76,73,70,67,64,60,57,54,51,48,45,42,39,' n0 y; L" j5 D; f; g) q
36,33,31,28,25,23,21,18,16,14,12,10,9,7,6,4,3,2,1,' U7 W6 S5 j- {. G; o4 |
1,0,0,0,0,0,0,0,1,1,2,3,4,6,7,9,10,12,14,16,18,21,23,$ X0 |2 S4 V# m) _
25,28,31,33,36,39,42,45,48,51,54,57,60: N" h8 d; j. M( S! o
};, F2 T: \; U/ h: G
/**********************************************************
$ H+ M$ m+ l" T# k1 X/ q( x*函数名称:Timer0_init(double timer0Delay)
3 n5 u) i5 G3 Z" S9 z*函数功能:定时器0初始化
2 ]3 X# I2 H& n/ T Y8 X*函数入口:timer0Delay,定时器定时时间,单位为毫秒 U( b) S+ y/ `$ F& F
*函数出口:无/ d+ ~; }, R# x0 \& F0 n* S5 F
**********************************************************/
) S3 x6 p6 k1 x1 |void Timer0_init(double timer0Delay)
3 H5 G" z& d% h7 t0 y% Y1 \{
& ? p0 B! ]- ~/ @6 g f double time;
" U9 k+ s, \* X7 h double timeTemp;
9 G6 U% W% V- b. k) \( e. r2 c* f) z3 R timer0TH0=0x00;
4 q8 M5 ^- X5 D timer0TL0=0x00;7 L" R! r9 x) H4 Y2 l
timeTemp=0x00;: K0 ]( d" n7 @7 ]7 b. m
time=(double)(((double)12)/((F_CPU)/1000000)); ' b$ I9 }+ M' H: x* I
if(((double)255)*time>timer0Delay)
, _: B$ d' Y+ h" V {( q$ W9 J5 ^' y* z$ |8 ?* Y
timer0TH0=0x00;
6 z3 W0 }! r8 J- {! P timer0TL0=(uchar)(256ul-timer0Delay/time);6 l% `) \/ A) g% j
}
% ~, o5 j7 k& W else, c9 p3 v. S6 O1 E% L3 [3 p6 i! i
{5 l: }7 V" C2 S
while(timeTemp>timer0Delay)4 g. O$ y$ @5 ~! `: y
{/ c+ _+ }1 e: ?
timeTemp+=time;/ H% ^, C X& J1 F
timer0TH0++;
/ ^: \5 c- I8 d3 z1 n }: R5 F2 i1 ^( _" v" Z
timer0TH0--;
5 z4 ?2 l: c! D' {7 s4 @, l4 h timeTemp=timeTemp-((double)timer0TH0)*time;1 W' }+ j0 T6 ^4 D# {7 Q- \; |# |% L" s
timer0TL0=(uchar)(256ul-timeTemp/time);
9 H* h% g9 H" Q }
5 d) A9 b% n- b( s; @: w$ x& I TMOD|=0x01; //GATE=0,TR=1运行;C/T=1,counter,0,timer;01十六进制 B& R; \% ^3 Z5 }
TH0=timer0TH0;
9 p4 Q, K8 f. `* j* G) `2 c TL0=timer0TL0;5 Z i% j; Y# P, ^4 B/ J0 A$ t
TR0=1; //timer0 控制位,为1时启动timer04 O2 g9 ]) m, B% M# p$ z6 F+ o
ET0=1; //timer0 中断使能* r+ K; S7 ]; z0 I! Q
}0 u) E0 a$ n$ R& W. Y
/**********************************************************
- q9 D- e5 z& P0 S1 a1 m2 Q*函数名称:dac0832_init(void) # u8 v* p/ v# R6 X8 q3 h# L
*函数功能:D/A转换芯片dac0832初始化
# _* @/ t+ I4 m% P. H*函数入口:无
, ]( \7 |9 y- Q! i*函数出口:无! ~4 O% q$ U" @
**********************************************************/
3 x, w2 q& a0 f3 l7 |void dac0832_init(void)
. E5 d6 s. t4 W; d{6 L3 K* f$ S: ?
sinCodeCount=0;
" o% I. t* i9 _1 O! O& } DAC0832=Sin[0]; 9 T2 v8 x. H' P, S8 A' g
}" }! W+ I9 W9 \- X+ G, n/ s
/**********************************************************
# m7 B- {" ] D5 _# P*函数名称:writeDAC0832(uchar dacDate)
- j8 g4 S' a3 u, C9 k* f*函数功能:向D/A转换芯片dac0832数据口写数据
- S' o0 x6 E/ V8 W* Y8 w*函数入口:dacDate
7 q* V' q8 _( E, ^) ?*函数出口:无/ |& I* g K+ s( ~* R
**********************************************************/3 y/ Z3 _7 p& Q2 M: `. m, S% q
void writeDAC0832(uchar dacDate)
: n' r7 y# m z( v8 C( I& \{
8 F$ w1 a2 s! T& a DAC0832=dacDate;
! C) _7 ]& p5 r8 }3 n7 V: ^}+ `$ ] u! w/ ^2 v0 M" d
- w& u. ]3 L5 ]: x2 o' w2 @下载:* S1 z0 y) y2 s8 ?
- C8 {. |& h9 i8 X; [
3 H' Q- J0 P4 j% y- ? c9 k
|
|