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

【经验分享】STM32Cube HAL DMA传输

[复制链接]
STMCU小助手 发布时间:2022-4-7 15:34
一、原理图) v: G2 {% `! k

3 Q$ g; b) V) v2 A# C L$D(E9(U2FSS881TGD2@_%Q.png * {# I5 ]7 Y5 M6 m3 V* G6 }

% L' o# A5 c( o( }4 q2 ]二、 CubeMX配置
1 h3 u" v% \, X! G% @  @- ?5 u( E. n5 \/ C7 F$ d
Step1.打开 STM32CubeMX,点击“New Project”,选择芯片型号,STM32F103VETx。
* H1 B0 C( B9 s$ [8 m0 m5 `' l: N( [0 [
MG$E]IKM_FJEOYN)KJYV)`Q.png 1 }. n0 D! S1 D8 ?+ G% k) Z  D

, R* _& L3 \' D2 E Step2.选择时钟源,并配置时钟树。选择Crystal/Ceramic Resonator,并配置系统时钟为72M。
( l+ |# a: k. ^! b$ V+ E( t+ ?. i/ `
7RXFX8MLB3`ES{@AY_Z]3.png
$ ?% g# e' L; N
, B! X% {: B. }" B, p6 T L9Y`A_O]RE7U~9(D(ZIM[5Q.png
* K% n& H. b, i8 q# T
% q1 H: f" C6 T7 e$ _% s, DStep3.配置SYS,我们这里选择的是Serial Wire。(正常情况配置不配置不影响,debug可以使用。但是你不可以把这两个引脚用于其他复用功能,如果用于其他复用功能,debug就不起作用了。)
' B  _: ]! X/ ~2 y+ u
& G- s  L+ E& f: h0 f3 W PZ1H1IW]}IB61W7AZ6)H]1L.png . x- r- ~& h0 C9 H7 g" `

* l  ]2 L# Q$ v7 v. U" }( E& ^6 e Step4.串口配置(主要为了在串口调试助手显示测试的电压),因为没有用到中断和DMA所以我们就不过多讲解。
8 I: b. z0 E" I# F* U$ s0 e( t6 L7 u9 B2 B
V7TD{2XU2}$}H_6X2H7[7(Q.png . c! Q9 b2 n* |* ?( [. j
. ?) R- V7 _0 d( x+ m
IFGW@R}Z471`ER{_EUMUO7H.png
/ L' h" l, \1 F' b' v. @: {2 O) K0 }3 `) a2 a, \1 x' @! b& t
Step5.ADC的配置
' n. w0 s2 A) s# b4 ~% K. p
0 d. H  w8 ~$ I. B0 p# G5 o ]61ZJ1Z0M1EHWND%BQO61KI.png
$ p7 K, h+ j; d4 l4 _5 |# [! P6 @( s! B9 m
[K~5B[5{Y3@NDA{N11YHL9R.png 9 O" O' o% q% }- i( K7 f

" v( ]& ^0 y/ K& @7 |Step6.因为多个通道需要使用到DMA传输到内存,否则ADC的存放转换数据的寄存器会不断覆盖上一个转换的数据。DMA模式:循环模式,重复传输,而常规模式则是传输1次。地址自增,因为ADC外设本身就只有一个寄存器所以不存在地址自增的情况,而内存是需要地址自增来存放不同通道的转换结果,如果不自增,则会覆盖上一次的结果。数据宽度:根据传输数据决定,因为此次传输的是12位的数据,所以使用半字(2个字节)就可以了。
9 ^6 ~  L9 E: M* I2 ]/ D, ~
( ]; M9 P6 Z8 L8 t6 @5 _% O' ` XP1FE3[%XMP6ECCPOX%4S.png
/ |) D0 L/ K& T+ a, n6 b# t# I1 @- s
! v, m" A6 L, p( Q3 ` $M[M2WZ97C%5ZZ)GHAPS.png
4 B% W1 P" g) n! H7 ]/ f  K) w& r3 G& v( f" K& E9 n( v9 P3 P& C4 T5 p
6(YYA}W@(CDYAJ]%UFT`21Q.png
2 d4 ?# s5 L! I- f: U4 X  e2 g& G1 [
到这里关于ADC参数配置基本已经完成,只需要根据之前文章《STM32Cube HAL:GPIO输入/输出(一)》Step4-Step8,设置相关工程参数和生成代码。
2 r& u6 t- Z  T( b8 Z& l0 F2 t' z, M- h8 N
三、添加功能代码! Z1 _( `" J* N5 _  h3 S, z

& X# G( O  I$ @  ^) u7 x1、我们等会会向串口调试助手发送数据,进行实验结果的验证。 发送数据我们采用printf函数,所有需要重定向c库函数printf到串口。注意使用时需要在keil设置中勾选微库(use mircolib),同时需要添加头文件#include <stdio.h>。重定向代码如下(usart.c)
9 J& v( F, A* ?* w3 [
1 O  j  v0 v* Z
  1. //重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
    1 d& T5 g) |, H2 E5 `
  2. int fputc(int ch, FILE *f)
    . B0 g" Y' P, `1 B  `
  3. {
    ! \: {, u- @3 N: x' R0 g
  4.         /* 发送一个字节数据到串口DEBUG_USART */5 i; g- Q" E% \4 w! }
  5.         HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);        
    9 q; j8 t. G9 ^8 J/ Y4 {* T
  6.         * x& p& p. S6 i" Z
  7.         return (ch);1 d0 G0 c+ ^! s  }, v0 I2 i1 P
  8. }
    ; M% y6 \& I2 \+ a% j/ @" W" {

  9. ' b8 Q( W/ Z) T5 H# A4 q3 J
  10. //重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
    4 f- L& Z/ T* s' N
  11. int fgetc(FILE *f)! F( ]& Q( U, ]! ~: b# N$ f
  12. {               
    9 P5 P5 i9 Y' e6 e% K( s
  13.         int ch;
    5 i$ c* c4 Z; y2 X: d. U
  14.         HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);        
    " Q$ w, R$ L) s/ T3 c2 y  T
  15.         return (ch);! s# R/ c, [, a' t4 H
  16. }+ u  ?) Z6 [6 X8 c& ?; |$ D
复制代码
" c4 c9 g  i2 {5 P3 p8 @
   2、定义相关变量,以及使能相关ADC和处理代码(main.c)+ x% U1 R9 }0 H7 o8 U/ E
0 _3 N* ~1 |# B( ~, u' S
  1. //全局变量
    6 z  V7 b; `0 R  U# q, V
  2. uint16_t conv_value[6];//用于存放DMA传输的数据
    3 S  ?/ O$ S# r/ [- a2 [, g2 y
  3. float voltage[6];//计算后的电压
复制代码
  1. //使能相关外设
    # |% @% k" G& N" V4 e
  2. HAL_ADC_Start_DMA(&hadc1,(uint32_t*)conv_value,6);//开启ADC转换以及DMA传输,6是DMA传输的次<span style="background-color: rgb(255, 255, 255);">数</span>
复制代码
  1. //在WHILE(1)中,输出电压值$ u4 s  V0 ?0 m0 [, w) s0 ?
  2. while (1)
    4 _7 S3 O3 W+ n( {9 k' f2 k3 a
  3.   {+ }6 I8 A$ x$ P5 B; D' x2 I
  4.                 voltage[0]=(float)conv_value[0]*3.3/4096;//通过转化的值计算电压值
    * n/ F+ i& E- ^4 y/ W: J# D' L$ s
  5.                 voltage[1]=(float)conv_value[1]*3.3/4096;
    6 S3 U' C7 c# b4 ^# U; D' H
  6.                 voltage[2]=(float)conv_value[2]*3.3/4096;! R+ [* P& F( l9 K7 }# b
  7.                 voltage[3]=(float)conv_value[3]*3.3/4096;4 D5 G$ {; \! |! ^* y! V! Y
  8.                 voltage[4]=(float)conv_value[4]*3.3/4096;9 q( C* f+ N+ z2 H
  9.                 voltage[5]=(float)conv_value[5]*3.3/4096;
    * j: v0 B# y- `4 z( {$ ~2 V( D
  10.                 $ u* l$ v/ g$ [" N! M1 f
  11.                 printf("\n\rCH0 voltage=%.2fV\n\r",voltage[0]);//输出电压值) J5 N* Y) d/ r" Y0 o& d( d( [( U
  12.                 printf("\n\rCH1 voltage=%.2fV\n\r",voltage[1]);: \4 O& o+ A6 B  k8 k" j, X6 o; R
  13.                 printf("\n\rCH2 voltage=%.2fV\n\r",voltage[2]);
    6 K1 G9 ?" V4 J
  14.                 printf("\n\rCH3 voltage=%.2fV\n\r",voltage[3]);
    5 O2 b& ^0 J' ]& j2 H7 l0 e
  15.                 printf("\n\rCH4 voltage=%.2fV\n\r",voltage[4]);
    1 Q0 A* O2 Q( k4 x- |7 }- k2 j: X( o
  16.                 printf("\n\rCH5 voltage=%.2fV\n\r",voltage[5]);. n' v3 [; M0 |3 ~0 a7 r
  17.                
    + p% x( ], i; T( A9 u: Y
  18.                 HAL_Delay(1000);//延时1秒        ' I; j0 }; _, U4 T
  19.   }
复制代码

' E7 c5 Y& w& A8 X5 K7 t) P, T, t' H4 E' a0 U
在实验中主要注意的是函数% h2 B8 W& T: J3 F! z) V
6 R/ v% ?/ G7 \
HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
- x; U2 F0 N# T# G7 v1 b, _; k7 [6 L& h. y& I
hadc:adc句柄
6 w' T, V! y' A  _$ [( f
4 c5 \; m# \! w) U' k8 Y9 P- m. JpData:buffer缓冲区指针
; |% d: w" ?1 `' L3 W& t; U- K6 }& q; h
Length:传输的数目(以数据宽度为单位)2 i5 Y! D- \' ]$ R7 t  p' {
( G  F2 y: T. \7 |/ W$ B
例:    1:5个通道,每个通道传输1个,一共传输5个 。那么Length=5;* O5 [7 R( i: O/ {. e" L7 s

3 I. K$ f5 V: O: k           2:1个通道,每个通道传输5个,一共传输5个。那么Length=5;
) J- Q' C" C2 l0 S5 ~" K
" a1 Q  V: k" b! O8 S 关于这个函数的理解,如果有错误的地方,欢迎指出。
6 @' Q+ a# |( X
& m* \- w! P6 t' i关于length的说法,网上有些文章是说这个Length是和传输的数据宽度有关的,如果传输的是 word的话,那么Length,有多少通道就设置多少;如果是half word,则Length,是通道数的2倍。(暂时没理解)
3 |( {% [- L8 w  ?  I
' R& ~8 o7 b9 @# c* ?; u! @8 v5 ^) k1 X  }$ K7 U4 ^
赞 收藏 评论0 发布时间:2022-4-7 15:34

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版