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

【经验分享】STM32CUBEMX--自定义红外NEC解码,定时器TIM捕获方式

[复制链接]
STMCU小助手 发布时间:2022-4-30 23:15
概述
" M' t! _+ {! f( A9 b! u本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。. @! Z; \1 l4 f) d0 H* a0 F

" e! Y; k- }9 x3 l& l+ c' z硬件准备
" i7 u- h6 j7 i3 {6 g3 G: l首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:( i6 l, B" @! i$ a$ H

, R5 t  j8 r  A' Q% c4 H9 j IS(PD7W85C(SQFJZNK9ANN7.png ' ?0 G' d1 C; _  i$ I

0 V( K6 M  v4 G- `7 G选择芯片型号4 V) B& h* S; Y6 N. \
& u, I) S5 t  `7 `7 ~
20200616155328854.png ' n2 Y) d. p3 r" Q" n9 B3 h
, ?2 n5 c( h. s( P, t
配置时钟源, {$ ~7 Z) \; V5 H: s% e7 X
HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:! f" \0 o6 G/ a" G4 q' n% A

" G* t( P2 ]; ^# Y5 N 20200616155740119.png
0 R6 _( K! u' z6 Z* j3 t3 A+ I! j* L$ i1 ]! e9 Y) p
配置时钟树
  n7 y. R& G4 p9 t4 l. R9 hSTM32F0的最高主频到48M,所以配置48即可:' Z  G, m! b7 P4 }+ b, H2 H# o

7 d# [" m9 Y+ m/ ?# N 20200616155804751.png $ ~6 C* G5 G- I* e3 s
* M' i( Q4 S9 d3 u. Z7 i3 y# n
串口配置$ D& |0 `7 c+ V% u# c
本次实验使用的串口1进行串口通信,波特率配置为115200。
  a8 L  K2 o" E4 m6 w
3 {/ u7 g, r$ D& a8 K0 j+ A) U6 t 20201130105900346.png 7 @$ I" ^& O0 Q+ D9 O% L

& I; l, R7 O- m9 i" |! F( j8 E7 l定时器配置

) C9 j: }. c4 g本次使用定时器1的通道2进行检测,配置入下。4 U7 E; c# Q9 Q9 |# f
* a, t8 y& J, z3 `
20200616162851204.png
+ t: P. |' |% f) `3 a, _6 M( ^+ j: L$ o* q& E
红外接收管: E: d3 R; S/ p0 q
这里使用VS838的接收管,如下所示:, d3 Q, \& X. b2 L& x8 e0 h
$ O2 L0 z6 q! e% c  u4 G3 `5 O" x
20200623160226119.png
! D6 j& _- o" s! i% A# a9 e6 q9 w% X
红外编码
1 D' V; x: l# F& N1 aNEC协议载波:38khz
9 @8 U8 J  F" h/ {, V& ^" v/ R其逻辑1与逻辑0的表示如图所示:
- O1 H' q9 T1 n: n. h" A* K. C8 r, d5 L
20200623165733766.png 6 e  R# y. Y7 x+ {2 D$ Z/ t9 D

0 e6 g8 }2 ?1 g: {+ d" iNEC协议格式:
( H  b3 u- q& ~% W4 t2 G9 D" j+ c" K; f: Y# w# L
20200623165807215.png
6 q9 [  l: w, }' i
3 Y" b/ `5 U4 D自定义红外编码
! Q9 \: C) n3 i7 K# w! d6 d8 B1 A协议如下:
( `/ g7 E( y, `
0 t$ n' N% ]7 ? 20201127160644531.jpg 1 d* U& {; A: P2 i6 {2 h

1 d/ A( W0 P6 j1 c1 D6 u( {6 d代码; M4 {9 x3 ]8 s" u
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。
0 J3 b  l9 M; s+ b9 r4 M) |7 J+ Y' d0 b1 r( \# i
  1. /* USER CODE BEGIN Includes */7 e% A- q2 i# @6 a
  2. #include "stdio.h"
    9 U5 @5 p  {6 l: |- d
  3. /* USER CODE END Includes */
复制代码

0 `  a9 K& v) u3 I  H2 D红外接收口定义) r3 O" Q) K5 X+ S& P" |

( I* U* o% s5 k- P9 H/ I5 B1 ?
  1. /* USER CODE BEGIN PTD */) s( k5 Z' N2 e( }& y. d- I
  2. #define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)
    6 G9 j9 g) r5 X
  3. /* USER CODE END PTD */
复制代码
3 \3 r' j, \* H
函数声明和串口重定向:
! q! b# Z) Z: s% E( {
7 t$ [$ h' v7 D# Q1 n0 [: [+ H$ {) ^
  1. /* USER CODE BEGIN PFP */
    * U  j5 h1 N5 L- D0 j
  2. #ifdef __GNUC__9 s1 G) A' ~) ^) ~  r2 m
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)- Y/ D* [; E+ d5 K
  4. #else
    3 W% n& w. a0 L% P5 `, k( M  l
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)" Y2 f9 e1 c4 N' F  M* {
  6. #endif /* __GNUC__ */
    + L$ }6 y& ~& _: Y7 S4 i' f
  7. PUTCHAR_PROTOTYPE
    2 z- z- x" ~% Q; B$ @
  8. {, x* o, s7 x# W5 {- b
  9.     HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    & T' |, V. y. }6 ~3 V6 w( [
  10.     return ch;0 x" j* K& `& ^0 m; P! S5 c; C4 X
  11. }
    . `9 n' s2 o( S% y5 y' l4 B, S' ?
  12. /* USER CODE END PFP */
复制代码
  1. /* USER CODE BEGIN 0 */% o& m" ]0 Z% Y: k1 L' y
  2. uint32_t OrderData = 0;; b/ @6 P8 L; ^& s4 a! V% J
  3. uint8_t ReadyFlag = 0;9 m( H2 L* ?* V* Q" t# I
  4. uint8_t OK = 0;
    7 i5 ?! T, g# u/ y& ^3 i  k3 G4 Q
  5. /* USER CODE END 0 */
复制代码
# d1 K. \5 ^* p; W9 ?
定时器配置9 y  I2 y2 L* j2 B- h7 O( R

+ |; w2 B+ e/ o  S  e. R
  1.   /* USER CODE BEGIN 2 */% e0 }( G; p4 u& Q
  2.         HAL_TIM_Base_Start_IT(&htim1);//启动定时器: N/ }. F- N7 R! G; J6 u9 {: y+ r
  3.         HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
    $ l! a; Q" D( c/ L
  4.         printf("IR Capture !! \r\n");
    * H" B' Y/ W- z9 o* Q
  5.   /* USER CODE END 2 *
复制代码
& {3 _' v9 v. V# ~# n% w
红外接收代码
3 V9 F# F& h9 {& ^2 o7 ~: @! `
( J' V0 d- T6 Y: Q2 K* h[4400,5000]是用于捕获4.5ms的信号* f: ]+ Q% C8 r, S% v
[550,700]是用于捕获560us的数据0信号
$ y7 r: o6 S* m' S[1100,1250]是用于捕获1120us的数据1信号
# C, w" [5 |% v- ?. Q[2000,2500]是用于捕获2240us的截止位信号
# R# j7 ^1 X7 y1 W$ V8 B4 L7 G/* USER CODE BEGIN 4 */
6 N/ M- B! t% k// 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
+ E; |' S8 H8 e5 a# V( x; g5 P- ]
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    . E, R8 a- {! w2 ]! g* X) v) q
  2. {8 {: q6 k5 S  c  L, u) {
  3.         uint32_t fallingCount = 0 ; // 下降沿计数1 l7 d& ^8 x+ `1 g# C, a" `
  4.         uint8_t temp = 0 ;) R7 Q: x. _4 J9 \
  5.         // 判断是否是定时器1的外部捕获口2
    " `7 ?+ ~/ _, z3 ]! P+ D4 y
  6.         if(htim->Instance == TIM1)
    1 K3 }; d$ s+ R, I1 N+ ~$ t
  7.         {
    - y3 M; \7 O0 ~6 h5 C: t2 _
  8.                 // 捕获到了上升沿( M8 H- j" A- C
  9.                 if(IR_IN1)
    - Y$ e. i2 B+ B6 w7 o1 W
  10.                 {
    ( U& }. y3 C, n( w3 p& D# d% ^
  11.                         __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
    " l  J/ R: c/ B- B% M9 q& C! r2 s
  12.                         __HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计, m" w0 J- n# j) ?4 K6 ]4 c1 s6 ~0 N
  13.                 }
    ' G6 j$ C3 j6 X$ R5 I* ]
  14.                 else4 ^; [+ E" m( h
  15.                 {, a& R$ k& l( V
  16.                         fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间
    4 H2 d# u! G. G# f9 D" x* N8 {" }4 V
  17.                         __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
    # r- i" F' Y+ R+ R" Y
  18.                         if( ((fallingCount > 4400) && (fallingCount <5000))) & W% h! l0 z; f5 o( k0 X( q5 M. O
  19.                                 OK = 1;/// 4.5ms引导电平
    2 u+ E6 w% u3 n& v* L
  20.                         else if (((fallingCount > 550) && (fallingCount < 700)))        + y# o8 m/ Q$ H; ^( T# w) E" j
  21.                         {1 i: X" }# e$ v! l
  22.                                 temp = 0;//560 us,数据为0& u; p* A/ p, L4 L! C0 Y7 N
  23.                         }        ; j; W) p  q& C1 X
  24.                         else if (((fallingCount > 1100) && (fallingCount < 1250)))
    ( `6 h$ t0 G7 a. J6 I7 m& z
  25.                         {2 \' L" {" c& _  q. ]0 B9 ^- p* J
  26.                         
    " G% u! Q2 {% i* `' d
  27.                                 temp = 1;//1120 us,数据为1! O- \6 x& s+ t8 |/ \1 j) I( i
  28.                         }# y: T3 E7 t4 f( Q
  29.                         
    # t3 j& q9 c' o
  30.                         else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500)))        //2.240ms截止码
    0 w4 |4 t! J6 `
  31.                         {
      O* x/ O! Z) r4 x
  32.                           ReadyFlag = 1 ;4 e) f. g3 ^  f8 d& P9 B
  33.                                 OK = 0;
    ; j. M( i4 l  q: m" I* o
  34.                         }6 g* Y$ b6 e! @& M  O1 |7 N
  35.                         if(OK)4 N; x$ F6 ?( ~% f- V7 Y" {
  36.                         {# }- Z4 m) O. u; h: [
  37.                                 OrderData <<= 1 ;' C. Q' [$ z" T, s/ \1 i9 i; v
  38.                                 OrderData += temp ;0 e: ?( ^7 e  b3 D2 D" g) W
  39.                                 KeyCount = 0; // 按键次数& |  q3 A$ V( H3 K# h
  40.                         }
    - b" y8 N1 M) o' L
  41.                 }) T# _" \5 Q8 U; j6 v* E! |2 d
  42.         }5 _9 D/ \8 ^7 w* v% C8 P% O' q9 C
  43. }  _$ b5 V) q, l* `5 {' y# j
  44. /* USER CODE END 4 */
复制代码

$ d3 p% J, ]0 H主函数( m5 T. f/ f5 ^% Q3 x: l  x
# P2 t4 Z; s2 Y% @+ ]1 i7 c! U
  1.   /* USER CODE BEGIN WHILE */2 J  U) G: P) {7 n. L2 F
  2.   while (1)
    % p# |: ?" f6 {
  3.   {
    ' E9 F7 U' J/ {9 l4 ^' Y2 G0 A
  4.     /* USER CODE END WHILE */
    ; {  ^8 @+ D: I1 d3 v" ~

  5. ( Q6 A$ Y! M& l: S$ L) M  W
  6.     /* USER CODE BEGIN 3 */
    ) b! z2 L& U" ^3 P1 W
  7.                 if(ReadyFlag)3 I) W8 A+ e- I) h8 u
  8.                 {; d' G6 A! x7 V; i0 q& X+ F& `( |+ p
  9.                         printf("order=%08X , code=%d\r\n",OrderData,OrderData);/ S# R) N% R  q: ~
  10.                         OrderData = 0;
    $ j, f  R' Y8 e" t
  11.                         OK = 0;; [$ u/ k# j* O1 p4 r
  12.                         ReadyFlag = 0;                : \: e" F( X5 n) Q& o
  13.                 }% A: K1 N1 @+ B0 x
  14.   }
    0 z% Z# ^! l& ~/ Q
  15.   /* USER CODE END 3 */
复制代码
/ g2 W5 P" x! t/ `% |
结果演示

5 b% Y- P* h, {, e红外连续发送5次码值,发送分别为
  c. p. L, ~) i8 q  K/ G
% J0 g: s, C1 h/ i- P; L' V2 R1011(11)) d5 K) A3 y' T$ {( E* H
11 1010(58)' C$ |+ }. z7 H. P' h( [% k! J' e  P
11 0001(49)
# X3 x9 |' E) O  o. _3 w7 m11 1111(63)+ U5 ?/ ~7 T& M! o6 z
11 0011(51)
& ^" S7 X+ I# C$ g1 ]% T分别如下所示:
! D" M  H) a. I( ?4 e4 V2 C
* M! \' ]2 |& [4 C0 w, K( L1 w; V 20201128092712393.png
5 \' q9 f% \& n0 Q9 v8 y' O/ U
0 }- n0 z" N) C. @8 g: |, y
6 n# }: g; S4 V3 Y6 l8 K
赞 收藏 评论0 发布时间:2022-4-30 23:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

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