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

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

[复制链接]
蓝凌风 发布时间:2017-5-22 10:32
代码如下,小伙伴们也可以增加波形的类型,使其输出更多的波形- q& j$ ~. p* Y" \( g# Y% G
  1. #include "dac.h"( v& L; s* }1 {6 x2 `
  2. #include <math.h>3 z2 {2 o% X/ n/ P1 q3 D0 o

  3. # {/ D& a/ C) U- k1 [8 S
  4. $ Q8 ~* _' o# }& a+ O6 w0 u( {- `
  5. #define MAXWAVECNT 2005 L% F) X7 w; [$ r
  6. #define WAVECNT 100          //波形的阶数,阶数越大波形拟真度越高,频率会越低
    ) s* y( r& _' ~0 y+ B* e
  7. u16  wavedatatab[MAXWAVECNT] = {0};   //存储任意的波形数据+ V" l/ w, P; b6 z- [! `
  8. /*自定义波形数据生成4 f) U9 F( z( _8 f: U
  9. Amp为幅值 0~3.3V0 L5 v' u+ `4 c  r( B8 d% l
  10. offset为偏置  值0~3.3V
    2 o+ B  ], f( G) y
  11. wavetype为波形类型:
    5 r# k& D3 W: \5 b% M8 H8 A! \
  12.                     0为正弦波
    $ X% N5 a0 T0 v* ], [& D$ A
  13.                     1为三角波
    * l: D& r' Q4 q! p% j3 j# K, |
  14.                     2为锯齿波
    , k% {  e, x! _' F0 _
  15.                     . R$ ]; C2 R4 B) P
  16. */: y# M; T- I. T. k/ C
  17. void GEN_WAVE(float Amp,float offset,u8 wavetype)
    # \/ y7 M) [2 q4 b
  18. {
    3 R! P3 f, U8 n) A
  19.     u16 tempAmp = Amp*4096/3.3; + G0 ?2 F) U- f" n8 m6 c9 c
  20.     u16 tempoffset = offset*4096/3.3;
    $ E" y- |( ?; e( c; `
  21.     u8 i;
    : c5 R/ P) v6 ~! ]# Z6 M5 d8 R4 {/ d
  22.     u16 step;
    - }# M, j3 C) r+ t4 k7 a
  23.     switch(wavetype)/ V5 X0 K( v4 l- c) o& Q
  24.     {
    . G* @6 a) C& |1 ]6 O
  25.         case 0:     for(i=0 ;i<WAVECNT;i++)
    # ?* \5 f7 t! z; e" S. `' K
  26.                             {
    / ]; I7 }$ f" Y4 |
  27.                             wavedatatab[i] = (u16)( tempAmp*sin(2*3.14*i/WAVECNT)+tempoffset); ! K& Z  H& s. F; }
  28.                             }6 @! ~. P6 z. D2 j
  29.                             break;
    ' ?8 @  w7 J4 m7 [2 Q2 w4 k
  30.         case 1:    step = tempAmp/(WAVECNT/2);
    , k! Q$ z8 c0 }1 N, w. i8 ^) L
  31.                     for(i=0 ;i<WAVECNT;i++)  6 H5 |0 A/ b0 \* P% L& ]0 ?
  32.                             {
    ' m" {; }3 h, w' h- t4 Q
  33.                                 if(i<(WAVECNT/2))    wavedatatab[i]= i*step+tempoffset;3 T; G& a0 W- H# H, U
  34.                                 else wavedatatab[i] = (WAVECNT-i)*step+tempoffset;
    ) E, h% d1 k, Y! n. \
  35.                             }   
    & h9 F# T* B& s! J& w6 O8 w. l
  36.                             break;
    2 q4 m5 q0 L+ A  |; r% q
  37.     case 2:     step = tempAmp/WAVECNT;     0 L# }7 q$ ?: v: Z& R
  38.                 for(i=0 ;i<WAVECNT;i++)  
    2 Z5 M; n4 R2 e$ ]9 p/ _
  39.                             {6 n8 ]- c: A) \
  40.                                 wavedatatab[i]= i*step+tempoffset;
    ; s+ W0 L9 \0 l' q- I9 h1 D( u
  41.                             }       9 [  d* g4 X- c3 p5 ~2 d
  42.               break;                            1 l: R7 C. ?3 ?3 p( q1 n
  43.         default:break;      
    + @- }1 @% X0 X# w- {) ^. _' v8 f) E
  44.         }4 X! y4 ~& G( s" Y! f) P
  45. }   
    1 U$ R9 M9 f) s( P  ?% t
  46.                                          9 Y" [* ]3 b. z/ p* h
  47. void TIM2_Int_Init(u16 arr,u16 psc)
    4 q" t+ B' J) n! F
  48. {
    - Y% k0 k' Z! D* J7 f. Z
  49.     RCC->APB1ENR|=1<<0;    //TIM2时钟使能   
    3 j2 K) o) m) b# z( V5 y
  50.     TIM2->ARR=arr;   //设定计数器自动重装值
    ( F* `! F/ j9 L& C$ o( L4 l
  51.     TIM2->PSC=psc;   //预分频器    * `# v3 {* J" {8 z; N. v/ b. H
  52.     TIM2->CR1|=1<<7;       //ARPE使能 ) B' k! G( [. A$ T+ s; I
  53.         TIM2->CR2 |=0x2<<4;    //TIMER更新做为TRGO源   
    ' z$ q9 ~: r3 y5 A
  54.     TIM2->CR1 |=TIM_CR1_CEN;    //使能定时器2
    4 n7 P: z, O- v" c
  55. }
    / Y$ ^- \1 Y+ _0 I- _
  56. void DAC_DMA_init(void)
    ; L* h$ N+ {( R$ j8 x
  57. {
    2 ^; h  P/ q$ k* b7 p! ?
  58.     RCC->AHB1ENR|=1<<21;//DMA1时钟使能 - \6 H# g& g: W, @- c5 e
  59.     DMA1_Stream5->PAR=(u32)&(DAC->DHR12R1);       //DMA外设地址
    3 E, }' E. V/ l& x; h! R8 B
  60.     DMA1_Stream5->M0AR=(u32)wavedatatab;     //DMA 存储器0地址- T0 z/ a" I! E& @  `1 _) l  l
  61.     DMA1_Stream5->NDTR=WAVECNT;              //DMA 传输数量
      o" H$ C! u: C2 Z/ K7 T: T- r
  62.     DMA1_Stream5->CR=0;          //先全部复位CR寄存器值 7 x& d7 D9 [0 V/ z* G
  63.      . M' ^* k& \0 L; s* i" i
  64.     DMA1_Stream5->CR|=1<<6;        //存储器到外设模式8 u+ e2 w3 U, w- W* U! o
  65.     DMA1_Stream5->CR|=1<<8;        //循环模式
    5 d2 u; k' c1 U! n! h/ I
  66.     DMA1_Stream5->CR|=0<<9;        //外设非增量模式
    , M. }& {4 P" r( N
  67.     DMA1_Stream5->CR|=1<<10;       //存储器增量模式
    4 k; p% ~/ k4 ^) I. z0 A. `
  68.     DMA1_Stream5->CR|=1<<11;       //外设数据长度:16位2 ^( F' V# h) Z+ P/ r
  69.     DMA1_Stream5->CR|=1<<13;       //存储器数据长度:16位
    5 t  R0 L. p6 t/ K; s  P
  70.     DMA1_Stream5->CR|=1<<16;       //中等优先级
    ! V. q6 O5 [+ g& s& G/ R8 X% u
  71.     DMA1_Stream5->CR|=0<<21;       //外设突发单次传输
    # y8 F" i/ U9 `9 C5 x7 z2 ~
  72.     DMA1_Stream5->CR|=0<<23;       //存储器突发单次传输+ D5 j% Z! P8 g+ \! D! C" A" o
  73.     DMA1_Stream5->CR|= 0x7<<25;//通道选择
    9 n% X& B# d! u( V
  74.     DMA1_Stream5->CR|= 1<< 0;//开DMA
    4 ?# c, R* M9 [' L
  75. }
    & D( d4 G1 ]. Z6 L% i5 S+ O

  76. 4 M& q7 R1 [  O' H
  77. //DDS初始化
    0 q7 Q1 h- r: m6 ^2 L
  78. void Dac1_Init(void)
    " ~! h5 O, K, o" k1 O1 V, D9 P
  79. {   
    . R$ ?1 Q9 i1 O, |/ ~0 O9 U
  80.     RCC->APB1ENR|=1<<29;       //使能DAC时钟      
    6 Y" Q! c; e. v  L
  81.     RCC->AHB1ENR|=1<<0;    //使能PORTA时钟   
    3 g0 n$ R; }/ C! e% F
  82.     GPIO_Set(GPIOA,PIN4,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA4,模拟输入,下拉   6 E  O2 Y* t; G4 `4 P

  83. 6 o7 N0 g/ `% D# n6 f
  84.     DAC->CR|=1<<0; //使能DAC1$ p) J$ O) `" ^$ \' I- m* h
  85.     DAC->CR|=1<<1; //DAC1输出缓存不使能 BOFF1=1) `4 I4 Y* o1 c* i
  86.     DAC->CR|=1<<2; //使用触发功能 TEN1=10 J$ Q& c' F+ s* X4 B' |. P8 R
  87.     DAC->CR|=4<<3; //DAC TIM2 TRGO,不过要TEN1=1才行
    ( F* p7 |; q5 K# [+ ]( @- ]5 X7 V
  88.     DAC->CR|=0<<6; //不使用波形发生
    1 }# Z- f* f( i1 `5 T( Q1 n% k4 K
  89.     DAC->CR|=0<<8; //屏蔽、幅值设置# @! e& J8 o3 r: f: X& i/ l
  90.     DAC->CR|=1<<12;    //DAC1 DMA使能    ! t* k. _% f5 F1 @4 g
  91.     DAC->DHR12R1=0;
    9 M- f( n2 w3 T  i) V, K' Q( f
  92.     DAC_DMA_init();
    + T9 F& M1 I3 s7 w% L
  93.     TIM2_Int_Init(100,0);
    ! H! h4 l( G) e% z# ?
  94. }
    * V: l) |0 |8 e% x+ t

  95. 7 Z) C7 j4 P3 Z
  96. void SET_DAC_FRQ(u16 frq)5 t2 ^! C( k3 F8 H$ h8 N
  97. {
    ; A) H$ `( E' b$ J* m
  98.     TIM2->CR1 &=~TIM_CR1_CEN;9 [, i: r8 M# ?/ G" O5 J
  99.     TIM2->ARR = frq;
      v/ r8 _/ i$ Q: u8 u2 \9 Y
  100.     TIM2->CR1 |=TIM_CR1_CEN;; l- v6 i& p4 Z: @% e) q
  101. }0 H2 s, Y1 U5 u4 e4 ?. u0 B1 C

  102. & H: p/ H8 B+ @7 |% s
  103. void DDS_Output_Wave(float Amp,float offset,u8 wavetype,u16 frq)
    6 K' q8 E3 L4 q; d" M& G
  104. {
    * ^& U) y  x6 Q
  105.     DMA1_Stream5->CR&= ~(1<< 0);//关DMA: ~2 l1 t% v" l4 W* d
  106.     GEN_WAVE(Amp,offset,wavetype);
    3 S' s8 ^* ^4 O
  107.     SET_DAC_FRQ(frq);7 m) T$ B' V. v% @
  108.     DMA1_Stream5->CR|= (1<< 0);//关DMA/ f! C; M' z2 n) z
  109. }
复制代码
6 [; g' @' W; j1 e7 T! r& @
9 @% k  K1 _3 c% Z% E
收藏 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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版