|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机正弦波发生器(1~100KHZ) 用DAC0832+定时器中断实现
+ o; \) i2 T l* R/ }6 M
& }0 a/ y: W) l" w
# P8 t0 u% J* t+ Z R下面给出一个设计实例,在实例中通过定时器中断和DAC0832结合的方式来产生1~100KHZ的正弦波,幅度为0-Vcc/2。: ] s7 o+ f4 j4 w# D
首先按照下面的公式建立一个正弦波样本表,样表中将一个正弦波周期分成128个点,每个点按7位量化(127对应最高幅度Vcc/2):
+ P f1 Z7 J% `; f+ q7 `! t9 ~f(x) = 64 + 63 * sin(2πx/180) x∈[0…127] 8 Y1 @& g" c: i. A& I
程序中使用16位定时器0产生取样中断,及定时器0的中断时间即为正弦波的采样周期。(T=1/(f*64))。本例中将正弦波分成64个采样点输出,及每隔两个点要从采样样本中取出一个数DAC0832的输入。
) E0 J; q- `) H/ m1 w3 }* g) k单片机源程序:* v9 \6 j% R" J' G
#define SIN_GLOBAL 1' K) [3 f& L9 A" u
#include "sin.h"" y8 u G- j$ f. L
//正弦波128个采样点寄存数组
0 C0 x) d3 o3 E3 Ycode uchar Sin[128] = {
# i5 M0 H: R+ j! j- B9 Z 64,67,70,73,76,79,82,85,88,91,94,96,99,102,104,106,+ C$ ? ?% K" ?" l! k$ f
109,111,113,115,117,118,120,121,123,124,125,126,126,
8 A4 ~. j: {2 ]3 X" ` 127,127,127,127,127,127,127,126,126,125,124,123,121,9 ]" a' n0 b u, j# G# t7 T
120,118,117,115,113,111,109,106,104,102,99,96,94,91,
M& a& H/ R I1 b# d 88,85,82,79,76,73,70,67,64,60,57,54,51,48,45,42,39,
7 w1 `7 R+ q9 M( X" R8 ` 36,33,31,28,25,23,21,18,16,14,12,10,9,7,6,4,3,2,1,
4 Q n7 d* G! r9 R5 e( W 1,0,0,0,0,0,0,0,1,1,2,3,4,6,7,9,10,12,14,16,18,21,23,
* S- b% o/ U" j; U k 25,28,31,33,36,39,42,45,48,51,54,57,60; g! X3 e$ F- u4 k
};9 f# W: U, L2 V8 d+ G5 f
/**********************************************************3 i5 n p p5 T+ t: w! |# \1 H
*函数名称:Timer0_init(double timer0Delay)8 e' \0 L* ^* r
*函数功能:定时器0初始化
9 q$ @- H T# f*函数入口:timer0Delay,定时器定时时间,单位为毫秒
& ]8 w( y% [0 x7 Z+ s*函数出口:无$ [4 x& q! K$ W3 y) p6 C% [
**********************************************************/
$ _/ @! Z7 S- o) _void Timer0_init(double timer0Delay)
$ e/ W* u0 u' Q- z' S. ^# a$ g( b) _{0 I; s d# E$ m8 Q
double time;3 O5 s' \% O. @9 _; [& C5 N" X
double timeTemp;5 K! c3 H1 d3 E: t. ?* ^
timer0TH0=0x00;( {; ^& ], l0 l" i; G
timer0TL0=0x00;1 u6 U7 t3 `+ f
timeTemp=0x00;* m6 [$ I' C; f8 f. [
time=(double)(((double)12)/((F_CPU)/1000000));
' d. o: j N8 i: E$ S if(((double)255)*time>timer0Delay)4 O& e( i K! v9 q. `
{2 {4 \2 K0 s! d9 p! X
timer0TH0=0x00;9 A9 ]( u' D( \' O' L5 J
timer0TL0=(uchar)(256ul-timer0Delay/time);1 v& v0 i7 [0 A$ C" \( R
}
) d) }- m0 v$ d+ w+ w/ Q3 l$ u else# X: m8 s' ?4 f' M7 q8 L- F: Y
{$ i, S6 w: ~' h# f! {4 _1 @# S- A( \
while(timeTemp>timer0Delay)
- h3 E( y1 k* I5 O9 D {: s) d* D/ n7 Q+ f
timeTemp+=time;6 [1 b6 F# N3 g1 C+ Q
timer0TH0++; 1 L6 i7 `8 e" x4 `1 X" Y& I
}
( g0 A- l+ ^& c2 F& T- }2 {# i% U timer0TH0--; / D( Z& r: P" g7 K3 a2 J( Z
timeTemp=timeTemp-((double)timer0TH0)*time;5 k! y5 F* s1 [5 D4 k2 v
timer0TL0=(uchar)(256ul-timeTemp/time); V: E7 M' b, g" H8 X$ @
}
" U$ d- X: ~ H: l1 W TMOD|=0x01; //GATE=0,TR=1运行;C/T=1,counter,0,timer;01十六进制 ; ]; |4 ~+ i( \$ f" F- w
TH0=timer0TH0;# Y5 e% C ]* f8 Z* w( o3 u
TL0=timer0TL0;
3 m$ I9 b6 h+ t$ ^# F& e# w TR0=1; //timer0 控制位,为1时启动timer04 b5 u9 O8 \! W9 ~* |7 D: ?) b- M$ {
ET0=1; //timer0 中断使能, h0 t+ n/ q+ i I% `& W# C3 h7 i
}0 o# L3 i) v! b, R0 f' k" [
/**********************************************************
1 }; J- X6 H# S) B# O# K*函数名称:dac0832_init(void)
% T- y, P" }9 P6 J, Z, n*函数功能:D/A转换芯片dac0832初始化6 c5 M. L& v, P+ G3 M: J
*函数入口:无, L, a! p3 l( W0 |. M$ Z8 g' p
*函数出口:无9 E6 p, M# I; u/ p3 Z( ~9 t% ~' E
**********************************************************/6 ]) a! S; i& V" {( `2 }* B$ P
void dac0832_init(void) , M. k6 R% ^- }, T h4 [
{, s' l: g$ g2 r* x3 }
sinCodeCount=0;
3 A3 T# [0 S6 x" E) d+ ~* \ DAC0832=Sin[0];
7 o9 Y/ O& M7 z: G}, J" E2 `1 q P' ^
/**********************************************************& h% c5 w* q( O d8 s5 ]
*函数名称:writeDAC0832(uchar dacDate)
5 r7 M% b: t% ~*函数功能:向D/A转换芯片dac0832数据口写数据
! g: j, B, s6 W" O1 Q*函数入口:dacDate4 V* \1 L: i* H- Z: q
*函数出口:无' s! ^# ?) M" T v. N$ I- a1 L* w
**********************************************************/
9 r1 G" |6 C! M% T$ f) w6 D$ Pvoid writeDAC0832(uchar dacDate)
! i2 p: v/ N$ q+ I0 c' z L{# `; h3 p$ B. P8 C
DAC0832=dacDate;
1 {5 E& \7 y/ q2 Z0 h5 [5 a}
- |) v- H5 z, t) \' N" s; A, j. o' f& H% {2 S
下载:, i% M0 E, @) l6 D/ S
* z c. S4 o: j& Q
3 y( T2 w' T7 ^6 J% M, ]6 T b$ s |
|