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

用TIMER+DMA+DAC写的一个简单DDS,能输出幅值频率可变的正弦...

[复制链接]
蓝凌风 发布时间:2017-5-22 10:32
代码如下,小伙伴们也可以增加波形的类型,使其输出更多的波形
& e8 A; C" }/ d% a# s
  1. #include "dac.h"( W  n0 R5 Z0 R5 `1 X5 U/ j# R+ n
  2. #include <math.h>
      l* m/ I- z' Q0 v( [2 u9 y1 S; Z' R
  3. - ]# e/ _/ M, ^( o; g2 y3 D3 |
  4.   Z7 h5 h3 W7 B$ _3 q9 ~
  5. #define MAXWAVECNT 2005 @9 B- {& }. h5 w& q2 |: q% X9 S* p
  6. #define WAVECNT 100          //波形的阶数,阶数越大波形拟真度越高,频率会越低) P9 l4 x7 P5 C4 b" L7 G( _
  7. u16  wavedatatab[MAXWAVECNT] = {0};   //存储任意的波形数据" D  n$ r$ d& `; o
  8. /*自定义波形数据生成
    # a! P( b' P; X( V. A! Z' @5 z
  9. Amp为幅值 0~3.3V8 F& g" r$ ~$ p
  10. offset为偏置  值0~3.3V! {" R6 @& _( J# j; o  x
  11. wavetype为波形类型:
    $ g) Y% j1 H. i4 t8 r
  12.                     0为正弦波  K  z, i$ x0 A7 @
  13.                     1为三角波
    7 X3 k' t# m9 o; O. {: p
  14.                     2为锯齿波) W+ S/ o. @- m" w. i! P8 ^" t' I
  15.                     
    9 X  p  ~6 J5 _( ^
  16. */) X: e' M$ ^" m
  17. void GEN_WAVE(float Amp,float offset,u8 wavetype)
    8 b  L4 p8 d/ g
  18. {, s4 R7 }! K3 X4 f
  19.     u16 tempAmp = Amp*4096/3.3;
    0 S& h* `) L2 B" ^
  20.     u16 tempoffset = offset*4096/3.3;
    - J- y2 n; r. N8 j5 k
  21.     u8 i;
    ! f2 u$ p& I$ S0 h6 C
  22.     u16 step;- Y; H9 h. O1 z; t2 w
  23.     switch(wavetype)" H) Z3 q/ `5 c: e
  24.     {
    ) ^% }( B) J# G; U- s0 I
  25.         case 0:     for(i=0 ;i<WAVECNT;i++)
    6 z  w' Q& _' X5 N2 j( L0 Z- S
  26.                             {
    # j1 R+ C5 Q- o) u# J* M. B; n9 L& U& w
  27.                             wavedatatab[i] = (u16)( tempAmp*sin(2*3.14*i/WAVECNT)+tempoffset);
    4 N) {9 M- L. Z! M/ K6 b. e- e
  28.                             }2 K8 @: b. m* X$ u  w
  29.                             break;  ~7 ~5 D% W% U/ g1 s
  30.         case 1:    step = tempAmp/(WAVECNT/2);
    % R9 {5 {  ~# l3 r' i6 i( j2 q0 e
  31.                     for(i=0 ;i<WAVECNT;i++)  
    ) u5 J/ P& F- S* U& t3 t% p
  32.                             {/ f/ r3 q! u' n
  33.                                 if(i<(WAVECNT/2))    wavedatatab[i]= i*step+tempoffset;/ x  W8 ^  E, N" R
  34.                                 else wavedatatab[i] = (WAVECNT-i)*step+tempoffset;" k0 e1 I1 g3 ^$ o* K" \
  35.                             }   + c( D6 P0 \% R& v% N
  36.                             break;- T) ]0 ]9 b3 g3 O! X
  37.     case 2:     step = tempAmp/WAVECNT;     
    ; M9 t( Y5 f; {3 j- t
  38.                 for(i=0 ;i<WAVECNT;i++)  ' Y( m$ q# t1 {( Z' s! m
  39.                             {
    # |( `* P  s" [4 l% w" v3 t
  40.                                 wavedatatab[i]= i*step+tempoffset;; \. C* p3 O5 W, O
  41.                             }      
    & w% T& @/ n; d0 G# v% X
  42.               break;                            7 i' ?1 I) \3 ~. `6 v( l
  43.         default:break;      $ r. O9 I" x' k& }3 ~
  44.         }( o' n( ?6 @$ Z8 r, Q& i7 D3 {$ d! z1 y
  45. }   
    ) y& z8 A* C6 U9 h
  46.                                          
    ) F3 s. K0 p8 p2 H% y  x
  47. void TIM2_Int_Init(u16 arr,u16 psc)
    3 h: I4 j6 [2 M- R
  48. {# G2 o' o" a' r: R1 D- M
  49.     RCC->APB1ENR|=1<<0;    //TIM2时钟使能   
    . ?8 K$ s/ s% S
  50.     TIM2->ARR=arr;   //设定计数器自动重装值
    4 t6 V6 d; Q& C: v$ ?' I- Y
  51.     TIM2->PSC=psc;   //预分频器   
    ; k9 f  D5 X2 L7 m- J+ K0 t7 \
  52.     TIM2->CR1|=1<<7;       //ARPE使能 # \3 {9 e! R3 N( l& u
  53.         TIM2->CR2 |=0x2<<4;    //TIMER更新做为TRGO源      d/ x# z! {/ h4 [3 ~
  54.     TIM2->CR1 |=TIM_CR1_CEN;    //使能定时器2
    # U# p- n2 ^6 M/ C
  55. }) u* B+ G. {0 ]
  56. void DAC_DMA_init(void)
    ) R2 w5 [, N) V9 n$ z5 J( [
  57. {
    # }/ w+ z7 o1 s
  58.     RCC->AHB1ENR|=1<<21;//DMA1时钟使能 8 \# y) n* _; h, Z6 G8 j
  59.     DMA1_Stream5->PAR=(u32)&(DAC->DHR12R1);       //DMA外设地址0 ?" r, A2 t* w9 k1 x. y7 `( K
  60.     DMA1_Stream5->M0AR=(u32)wavedatatab;     //DMA 存储器0地址
    9 w; M+ j% i5 R& p- N7 `2 O5 J8 H7 c
  61.     DMA1_Stream5->NDTR=WAVECNT;              //DMA 传输数量$ N9 L8 A4 Q+ `6 D+ q
  62.     DMA1_Stream5->CR=0;          //先全部复位CR寄存器值 6 t8 |) s5 u. D
  63.      : B# I3 n2 @; X' c/ t
  64.     DMA1_Stream5->CR|=1<<6;        //存储器到外设模式* M  \; _" K* |( D* Z7 c: F
  65.     DMA1_Stream5->CR|=1<<8;        //循环模式
    2 b8 [  T% n* `
  66.     DMA1_Stream5->CR|=0<<9;        //外设非增量模式
    $ @+ e" ^7 X3 Z0 O; U
  67.     DMA1_Stream5->CR|=1<<10;       //存储器增量模式
    " m! _9 o' e! L# P7 Q1 ~
  68.     DMA1_Stream5->CR|=1<<11;       //外设数据长度:16位9 }  L- `# q( N5 g. o$ z: M+ X
  69.     DMA1_Stream5->CR|=1<<13;       //存储器数据长度:16位
    5 Q. s! \( x" `4 B) m0 {
  70.     DMA1_Stream5->CR|=1<<16;       //中等优先级: v9 p' n6 c$ q5 G
  71.     DMA1_Stream5->CR|=0<<21;       //外设突发单次传输
    / S6 \) _0 Y* I/ D" f
  72.     DMA1_Stream5->CR|=0<<23;       //存储器突发单次传输& m" |% f! v2 ]- m
  73.     DMA1_Stream5->CR|= 0x7<<25;//通道选择! x: g% E' [8 i. c" ^" ^8 H) }% ]
  74.     DMA1_Stream5->CR|= 1<< 0;//开DMA
    - H4 E% a8 W9 k: d- g
  75. }' G5 c% @6 g# ]
  76. 6 {- K1 _' F* {7 N1 b7 S5 d9 d- o% k
  77. //DDS初始化
    2 J0 h( s  {* V- G! G
  78. void Dac1_Init(void)
    ' V/ n% C; W8 M- ^) I5 W
  79. {   ! @( ~' _1 }2 M. Y3 Y+ j; F& A
  80.     RCC->APB1ENR|=1<<29;       //使能DAC时钟      # J" _1 A( U) u
  81.     RCC->AHB1ENR|=1<<0;    //使能PORTA时钟   
    + G! e! B! h! Y8 _9 A$ I
  82.     GPIO_Set(GPIOA,PIN4,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA4,模拟输入,下拉   9 V$ e: u; S2 n# z. p
  83. 0 c% Q. Q  `+ o* c% s5 N3 u
  84.     DAC->CR|=1<<0; //使能DAC19 {* H2 Q, ^! K& K
  85.     DAC->CR|=1<<1; //DAC1输出缓存不使能 BOFF1=19 O7 E/ G# L& f4 v2 D) s
  86.     DAC->CR|=1<<2; //使用触发功能 TEN1=1
    ( M( E$ Q& t4 D6 c- I: }5 Q" T. E
  87.     DAC->CR|=4<<3; //DAC TIM2 TRGO,不过要TEN1=1才行6 v! \1 |6 R6 J$ |2 [. ]9 {+ b
  88.     DAC->CR|=0<<6; //不使用波形发生
    4 ^! Z+ k0 |6 z6 O+ T& K2 x
  89.     DAC->CR|=0<<8; //屏蔽、幅值设置# m7 E0 R, l4 J' q% V
  90.     DAC->CR|=1<<12;    //DAC1 DMA使能   
    & Y+ ]9 k" n7 B, ^5 ]# D
  91.     DAC->DHR12R1=0;
    ( w, u9 D2 c  O: |0 c
  92.     DAC_DMA_init();
    : |8 R+ L' z" R8 g
  93.     TIM2_Int_Init(100,0);
    0 V& e! q* U5 y* m3 H7 R( R
  94. }" R% }& O: h# k, x7 c
  95. ' T8 h; m, ]" u0 }4 G  C
  96. void SET_DAC_FRQ(u16 frq)
    % l( M0 ~: t3 b; [9 P6 c
  97. {
    7 E+ R5 }, C* h0 @
  98.     TIM2->CR1 &=~TIM_CR1_CEN;
    ( h# M5 {/ l- F* B: W
  99.     TIM2->ARR = frq;
    / ?# R6 q5 g" L7 [/ O
  100.     TIM2->CR1 |=TIM_CR1_CEN;
    0 Z* H9 H$ g  R) t; G
  101. }
    ! E5 F1 _! P3 p0 L$ I; v
  102. : o3 t8 r5 K- }. z: B! [
  103. void DDS_Output_Wave(float Amp,float offset,u8 wavetype,u16 frq)
    + A- V2 C( x* a2 M; C8 e
  104. {5 p- Q! |8 @- C- Y. Y! w
  105.     DMA1_Stream5->CR&= ~(1<< 0);//关DMA% Q7 x# S' w: y2 j4 I5 {9 @: }
  106.     GEN_WAVE(Amp,offset,wavetype);
    + P0 Z+ _( S! {3 E, z" ~
  107.     SET_DAC_FRQ(frq);
    ) J5 O9 V/ b) Y' U5 Q) I7 _  E: U) I' o: |
  108.     DMA1_Stream5->CR|= (1<< 0);//关DMA. m8 R4 s& s* x' m& g" ?5 s) S+ h3 H
  109. }
复制代码

8 W- j4 |5 ^( ^7 J" t+ D% `
8 l, j8 z) b6 h3 R& d7 ~' c) s
赞 收藏 1 评论4 发布时间:2017-5-22 10:32

举报

4个回答
wolfgang 回答时间:2017-5-24 08:20:57
好帖,顶一下
风905067 回答时间:2017-5-26 09:33:54
请问你这个对于的是哪一个MCU啊?
风905067 回答时间:2017-5-26 14:07:02
为什么我把你这个代码复制到我工程里,却只出来高电平?没有正玄波?
xiao风残月 回答时间:2018-11-11 19:05:54
好帖,顶一下
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版