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

STM32f103的数电采集电路的TIMER定时器的使用与时序控制的程序

[复制链接]
fightingboon 发布时间:2017-7-17 16:47
STM32f103的数电采集电路的TIMER定时器的
使用与时序控制的程序
STM32 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成。STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。1 l/ k/ d# v% x, T( n% M

0 k) ]2 k; b" v6 I( K通用定时器设置的一般步骤可以总结为如下几个步骤:
0 c' \0 x9 H) X; [& i% `) L/ W3 j! A( Q* m1 t
1.定时器时钟使能
1 M* {$ D& F) p3 {- [3 k
5 v2 H$ A- }- `2.设置定时参数
, f6 K2 q5 ^6 B, w0 i6 B) W! |4 Y7 x' O+ U
3.定时器工作方式初始化
" }  s5 }; G  \1 J0 D+ c3 Y7 c: U. @/ S) o! Z6 c1 W2 ^
4.定时器中断方式使能( C7 V: b9 d( n) |7 H

! J* X9 k# A0 `5.开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)- {7 {) f7 F( L, y6 d$ D
7 L6 Z  Y$ d3 r5 ?3 E8 v; Q
6.使能定时器8 p+ B' t+ p7 |: n5 Y
  y  K$ l4 n) e
7.编写中断处理函数
" D. `: f& `+ a% b6 X4 ]/ H
4 V- v. I( W3 \% A2 X; a" r前端采集模块采用了TIM4定时器作为USART1串口的定时发送,定时间隔为10ms,采用中断方式在中断服务函数里面使能USART1的DMA通道,使USART1能自动完成数据的发送任务,减少CPU的工作量和大大减少中断转跳时间,同时和ADC采样时序是相互独立的,不受ADC采样的间隔影响,确保了数据间隔时间的稳定性。
+ E7 U+ \3 ^: l- h# W* A4 J6 j
  1. [cpp] view plain copy7 s& U4 i6 h" C5 a  }; ~5 ^7 D
  2. //通用定时器中断初始化  
    + u8 E& q( G6 y" i1 K; Z
  3. //这里时钟选择为APB1的2倍,而APB1为36M  " s( @* E5 f1 r9 R/ y2 B9 g
  4. //arr:自动重装值。  ! z- C  h! Q& R' b2 n9 V
  5. //psc:时钟预分频数  
    ; ~, j" u) i8 d, q
  6. //这里使用的是定时器4!  
    8 _" {+ x8 W! N2 z. m$ `7 J
  7. void TIM4_Int_Init(u16 arr,u16 psc)  ( ]) B8 F0 L1 M+ x3 b* y7 `( Z& s
  8. {  
    , D. ]* D2 w1 w' q: a
  9.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  
    . e2 v# j/ [2 d: {8 U! x
  10.     NVIC_InitTypeDef NVIC_InitStructure;  
    ( I' Z$ C  Q1 m+ E) c( V) j
  11.   
    * `5 T3 R9 C! M3 O& G+ K* Q( j; Q) v
  12.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能  + }  {9 h, }' {6 j: x
  13.   
    % ^7 F' q4 [! z. V
  14.     TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值    计数到5000为500ms  
    7 r; b5 s% A+ C$ x% I0 z
  15.     TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率   
    - G9 t* K4 h& h- R
  16.     TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim  + c* h: p7 U0 v. Y6 {
  17.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式  
    $ r/ p; H2 ]5 a5 g- s$ f; \
  18.     TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位  
    ( j, v0 F4 ], L* b7 V8 \
  19.    
    . }; ?: C; K1 D0 w
  20.     TIM_ITConfig(  //使能或者失能指定的TIM中断  % _  q, V* Z% M. j
  21.         TIM4, //TIM4  
    % w. u; Z+ X" m/ Z2 P2 O
  22.         TIM_IT_Update ,  
      j1 P. |7 ?  \) ~7 `; b$ U
  23.         ENABLE  //使能  
    4 G1 |$ n5 I1 n& d
  24.         );  2 `( ?( o) f6 g: m/ n" ^
  25.     NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断  4 L  a$ E: j4 H! ]& w% F4 @
  26.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级  : ~# u3 g4 }: e
  27.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级  
    0 x! [9 u0 _3 j* d. k! ]
  28.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能  2 ?# E* B+ w1 z# X4 ~
  29.     NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器  
    3 s7 D/ U, e( w" ?
  30.     U8 Z  r  N' Y( X! V7 Y
  31.     TIM_Cmd(TIM4, ENABLE);  //使能TIMx外设  
    $ y0 h/ k+ b& `: N( R
  32.                               
    : C0 C* {. i4 z
  33. }  - f8 {6 s/ G/ B4 k6 d- u
  34. [cpp] view plain copy
    ) }5 w" r( O$ p3 S( n
  35. uint8_t HexTable[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};   //16进制字符表  
    ; r+ H6 p. v; O. ~* q9 G4 j% |
  36.   4 @) r/ S; D! s. O7 \8 ]8 b
  37. void TIM4_IRQHandler(void)   //TIM4中断  0 `/ s# ~) E& a6 l4 [8 q! s
  38. {  % k7 h9 d% E7 N, @/ R! K
  39.     if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源   " J+ l9 N) O% ^, l! o
  40.     {  
    8 D$ R4 l# Z/ p/ J6 m
  41. <span style="white-space:pre">        </span>//进行数据读取并转换成需要发送的字符  - c7 B- q# l$ Q! v" @
  42.         AdcChar[0] = HexTable[(adcValue>>12)&0x0f];  
    8 Y- T3 W3 L3 G3 H; a! N! l
  43.         AdcChar[1] = HexTable[(adcValue>>8)&0x0f];  8 H, _, b! ]0 N1 {; T. O' F8 D
  44.         AdcChar[2] = HexTable[(adcValue>>4)&0x0f];  * Q  J& Q4 x% i  A& Z* \% r
  45.         AdcChar[3] = HexTable[(adcValue)&0x0f];  ! D0 ~. q0 r' o, l7 }. D3 |
  46.         //将数据加载到串口发送数组  
    1 W' M  }6 \' [+ x
  47.         SendBuff[0] = AdcChar[0];  
    & L8 f8 a2 y" G! ~, P% j9 B3 g
  48.         SendBuff[1] = AdcChar[1];  . f6 ~, t3 r- b- ~) V$ G8 _
  49.         SendBuff[2] = AdcChar[2];  
    2 `, g  @, c: \; W$ m$ S
  50.         SendBuff[3] = AdcChar[3];  ) I2 t. R$ ~' X+ t
  51.         //USB_SendString("Connect to stm32 test the max lenght and more over 22 Byte.");  7 B' _4 K$ s  X) a5 z2 O, a
  52.         DMA_USART_Enable(DMA1_Channel4);  8 I7 F( }1 C& u8 ^) F! Z7 D& J
  53.     }  
    / v0 ^! _; z. I( b7 E5 m& d
  54.     TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源   
    5 X: e: |1 n1 E: }! H. X: V3 }
  55. }  
    : l4 |) T- s  M; s% L: E  e" D
复制代码
为了保证数据的采样率的稳定性,这里使用TIM4进行采样率的控制。TIM4定时一到,立即进入中断响应,在中断函数里,将ADC采样的数组空间进行数据读取,并加载在USART发送数据中  V# d' P) V  k& w; a# W
这里的数据报文采用了进制的字符形式发送,通信数据报文如下:(这里是双通道ADC的报文,单通道的报文则取前5位)

( M$ t" I, q) [+ S$ B6 F- W5 k QP)6)9K[FV8AGHB)I~)2ZPQ.png
; y" |7 F4 ]2 g$ m0 n) y注意:Data7、Data6、Data5、Data、Data3、Data2、Data1、Data0 是字符形式
0 u# Q( ^$ l9 @) Geg:ADC1 数据 1024 mV => 0x400
" _. s0 l# G- gADC2 数据 2048 mV => 0x8006 M2 @) \7 j$ }! u- U" U8 O) Z

- f' G+ ~: V' [9 [  o1 B8 c数据报文发送:P0400Q0800( v' h4 z5 ^" T
. c( U9 m. B" |+ e
2 T% o: a" S6 @, s. D- ~5 e
+ K) y( z: A: L6 t
0 z( c/ p/ I- T2 B$ l  [
赞 收藏 评论1 发布时间:2017-7-17 16:47

举报

1个回答
埃斯提爱慕 回答时间:2017-7-18 13:38:20
提示: 作者被禁止或删除 内容自动屏蔽
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版