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

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

[复制链接]
STMCU小助手 发布时间:2022-5-1 16:38
概述: {# j7 M" B6 C( `- z
本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。
7 y& E4 b- P# i" u# X5 g7 ^/ j
7 Z: W* c0 l. R" h硬件准备
% D/ h0 ^& B# Y5 m, \/ b. L4 M% B首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:/ C0 z7 q( n( S5 z

+ u, {" }& Q& h0 I  O. k% K PJ%1TK_6UZP%`(12L`ZLG2P.png
; o  X3 o/ b: _
( Y9 e; a: J% P选择芯片型号5 L- Y. s& w8 G$ X1 `' ?
. M. {: k5 j/ l$ J  l" x
Q1~F]}K1Z]S_74)S2N_FM9I.png - F1 {( r8 g* ^" D6 H, J
6 D, f, V% G: _* l+ f; \% N
配置时钟源
+ E: M7 E) n" {& `% o( v# _
HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:  A1 n& p0 x7 v. c' D. E$ D

" J( B6 j7 }6 ~. R ~QUX5CB6OZI[`O5460SX)YB.png " X# n7 O, R) A( {
( m- C' ?8 [. G% k
配置时钟树
. O4 I+ b0 j6 f- |& s6 uSTM32F0的最高主频到48M,所以配置48即可:, d; [! Q; O8 T5 e8 _

: _  H) l2 S* L+ K. T% Q
) z$ {* u2 j  b6 N. D& A, \5 l' ?% y6 ]6 X
串口配置- z8 V( S, e5 }+ ~/ }9 E
本次实验使用的串口1进行串口通信,波特率配置为115200。
& B4 L0 ^% D+ W! ]( k9 e$ f% w8 D0 p* N& ]# g) @$ Q
$W5R4OW1V{XIX[}30(P4{F9.png + J5 w! t) i- I) v3 Z" W' F) I
; p$ t9 t6 k6 m6 U" a1 L
定时器配置
: U6 h- y5 I9 V: y" M( W本次使用定时器1的通道2进行检测,配置入下。( v3 I+ z: c; b: K) O( b% f
4 K  f% y* A% b1 m- }
ML`2I9P](FD_ET4F}QUM929.png
4 e# a; l" V4 B! l! F; t1 J" M( C+ a# Q3 v0 B0 o
红外接收管
; f% Y6 q8 I( z7 y  g7 I这里使用VS838的接收管,如下所示:5 U, `6 \% p: V) y

; z( f/ e; B$ k% _- Y 20200623160226119.png . B" ^, E; O2 g' P

% H. Q5 Y/ Z+ |8 D红外编码( d1 Y  H, y+ J3 |, P( J
NEC协议载波:38khz2 A5 @9 A9 u8 t" ^7 R
其逻辑1与逻辑0的表示如图所示:
( |* R; a& V1 n! h. k( z4 N0 `' y# A  Y+ {  a- V
OPN4PQ9FT`25PF2UF{$MAIQ.png
# O6 Z9 K( p* x' `# ?4 J# w% U) r- i4 k& P
NEC协议格式:$ g2 f# o% S$ V1 U  w
9 F6 f4 N' w! ]/ W1 S
20200623165807215.png + z0 U6 @+ u# W0 ?, b8 H; F
6 O  R: l7 w1 w) J1 o- T/ w" F4 `2 {# m
自定义红外编码5 j, ~/ N, S6 l+ q7 o
协议如下:, E) o3 b6 F7 R$ M- }: E' W

, z7 Z- V( [" I1 A; v/ i 20201127160644531.jpg
3 t! W& p: p: {0 N5 W6 G' f3 r/ _. ?. m4 U; m
代码
, A, t9 E$ B- H) N$ Q5 H% G. I3 a在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。" j" ~. |. p4 u) I! v' L) b) I
% r/ I# }% i1 t8 G2 E* ~1 T
  1. /* USER CODE BEGIN Includes */
    # V5 X3 c  {$ F- c+ U
  2. #include "stdio.h"
    & H6 v- Z' h: X% T
  3. /* USER CODE END Includes */
复制代码

# \* i4 x/ t6 _4 ~红外接收口定义. v% H1 B: v# [; L# h. W

9 T9 E4 t9 @4 U# b. S0 C& d3 \8 F  r
  1. /* USER CODE BEGIN PTD */' S) j, Q. i" b. u* j: S, Z1 q1 z" q
  2. #define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)% v+ u) N! }/ p1 L3 H0 I
  3. /* USER CODE END PTD */
复制代码
8 T. I5 Q: D5 C
函数声明和串口重定向:
3 F2 j3 ?9 @$ L2 z; x- V
% m1 ^3 z) M, O3 z2 P6 Q/ z  k  {, R3 T
  1. /* USER CODE BEGIN PFP */5 g9 A; g! f0 z7 k+ e# ^
  2. #ifdef __GNUC__' }4 m- @0 y* |$ a0 v5 M9 V& u
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)/ H& c7 W" J9 q5 N
  4. #else
    % p# l2 E: [. a3 M/ l6 v: ?4 P5 I3 N5 y" t
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)5 B* W) Q' x% I
  6. #endif /* __GNUC__ */1 Z3 n# j; O* j2 v1 y5 E! t7 I
  7. PUTCHAR_PROTOTYPE' x0 K6 R! A' q& Q/ }  p1 w. C
  8. {
    ; t+ B' K  U* I
  9.     HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);) d0 y  C) J0 v* l" t- W$ y$ r
  10.     return ch;
    # {3 n3 y0 H4 b# A  e: b
  11. }  V+ n2 a3 B: d7 y
  12. /* USER CODE END PFP */
复制代码
  1. /* USER CODE BEGIN 0 */
    5 t/ c, t4 |7 T9 F
  2. uint32_t OrderData = 0;
    7 C' P+ J7 C) a4 Q/ }% w5 a
  3. uint8_t ReadyFlag = 0;
    4 s: U; d0 k3 U5 w/ J; J
  4. uint8_t OK = 0;
    3 c& ]. n$ s4 X8 |
  5. /* USER CODE END 0 */
复制代码
) {2 m; G# D  r/ |* h: v( G
定时器配置6 w& A. g$ b6 g  x: Z) G9 V: p+ R$ @4 c
: W6 s; L8 w/ \
  1.   /* USER CODE BEGIN 2 */7 L2 {1 P1 z5 `6 `' D$ R6 @
  2.         HAL_TIM_Base_Start_IT(&htim1);//启动定时器! p+ a% }9 d' T! t5 u
  3.         HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
    % {9 w2 W; u( b8 Z+ I# v
  4.         printf("IR Capture !! \r\n");
    ( s7 d5 _" I* \, O% O! r4 ~' t2 Y; w
  5.   /* USER CODE END 2 *
复制代码
2 A$ R8 r( _* _1 \
红外接收代码
& ^6 D/ Y$ p) P" C0 q& n3 Q1 Z
  H3 S+ ]; I$ o# k$ g) x2 B% I[4400,5000]是用于捕获4.5ms的信号" e; x8 [4 ~6 ]7 Y% _3 i
[550,700]是用于捕获560us的数据0信号+ H# y1 L, W% j  u4 F* N9 H
[1100,1250]是用于捕获1120us的数据1信号% ^& K& L% X5 Q5 m
[2000,2500]是用于捕获2240us的截止位信号4 }- Q9 y' ?6 I) I, d9 U
  1. /* USER CODE BEGIN 4 */
    , O3 i! z/ ^4 T6 u2 E
  2. // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
    6 k0 ~! ^5 l  ]& X
  3. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    0 y" y; I9 M8 [/ B8 O* \  B& o: Y3 @
  4. {  x3 `* R3 N! P! m) R8 I; j8 l
  5.         uint32_t fallingCount = 0 ; // 下降沿计数% p+ d* B* y2 p1 I) I4 o
  6.         uint8_t temp = 0 ;
    . }* }- K' I; O
  7.         // 判断是否是定时器1的外部捕获口2
    ; e& [3 M; ]! Y4 ?! t! {% w
  8.         if(htim->Instance == TIM1)
    2 ^! e/ B8 U* x$ W. K1 w
  9.         {& {+ {) D* }$ D* z. [* F! \! n" w
  10.                 // 捕获到了上升沿
    0 w% l( X8 p: f/ K
  11.                 if(IR_IN1). ^+ d' \& H/ e+ c# ]0 D% ]% X
  12.                 {
    : L, i; F  w( O
  13.                         __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获6 U) ?0 v  R* }4 W: q0 @& y6 Z% ~
  14.                         __HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计0 |* O* K' m9 a# h
  15.                 }$ |' J* C# m+ {6 I8 l2 W  f
  16.                 else3 ]4 w: t; d; B
  17.                 {
    3 x4 n3 e+ ?; e  o7 O7 q
  18.                         fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间3 J$ U2 C4 `' b  N# {# \# r* K
  19.                         __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
    ( D! h$ x. }; T' `2 V
  20.                         if( ((fallingCount > 4400) && (fallingCount <5000)))
    2 Z* S  b( v) D! s0 B( X
  21.                                 OK = 1;/// 4.5ms引导电平
    , }) w$ i% r5 C% x& d6 K- j! [
  22.                         else if (((fallingCount > 550) && (fallingCount < 700)))        : T3 j- _6 J. g
  23.                         {) A# P4 y! g$ W2 D/ d
  24.                                 temp = 0;//560 us,数据为0
    & @9 p8 u) ?7 W
  25.                         }        
    + c$ }# b! C9 u/ Z& b+ J3 p
  26.                         else if (((fallingCount > 1100) && (fallingCount < 1250)))
    3 m9 P* D- L; s* M1 _0 ?: a; \
  27.                         {
    4 |5 |8 ~) e  P% n
  28.                         ) H, c% i4 o8 U8 C6 u* V5 h/ |
  29.                                 temp = 1;//1120 us,数据为1
    & A  u' y; u* C
  30.                         }
    0 H4 A9 w3 |* ^: }' b
  31.                         1 g! n3 e4 I) o4 D& ?8 I
  32.                         else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500)))        //2.240ms截止码" W: q( V8 ~6 ]6 P
  33.                         {
    " {( u. s, C  X& V) Y
  34.                           ReadyFlag = 1 ;7 l+ }+ L  Q8 l5 K7 G4 W
  35.                                 OK = 0;
    ' q& |7 ?9 c8 T' \
  36.                         }9 q  p1 P' B' Q7 P/ w. U3 u
  37.                         if(OK): ~4 c% k& X/ _' g1 z# Y4 g
  38.                         {, m5 N8 N5 P2 w: g) X
  39.                                 OrderData <<= 1 ;" }. e/ ]' G7 R. y9 B* x
  40.                                 OrderData += temp ;* f6 u7 P) n3 n1 s3 F( q& @4 m) L
  41.                                 KeyCount = 0; // 按键次数
    8 e3 s7 h4 p  e
  42.                         }% C& I/ T) _" R
  43.                 }. {1 T9 `  ^' ]7 q# G5 \$ b
  44.         }
    , Q& g; H; ]) m$ D/ k: N" e
  45. }
    2 Y" P2 j: j# B6 u
  46. /* USER CODE END 4 */
复制代码

8 E% \' W0 K9 K% ?8 G* \主函数+ S5 g' I& [1 O+ w* l0 E
4 S" g) Z1 i& O, B2 f
  1.   /* USER CODE BEGIN WHILE */1 @4 ?" H% J* E: J
  2.   while (1)
    1 X- }! }2 G: V9 u( z2 f2 o
  3.   {
    " U3 s$ m* @! p! p0 @" @) ]
  4.     /* USER CODE END WHILE */
    9 `4 E0 u2 @  L3 ^) c+ g: U  D

  5. 5 O1 p- K5 o8 g; |5 c. a9 t
  6.     /* USER CODE BEGIN 3 */
    3 [# ?5 s& O  Y
  7.                 if(ReadyFlag)! e. w7 l9 h0 M
  8.                 {
    / a& J6 \, h) u; [
  9.                         printf("order=%08X , code=%d\r\n",OrderData,OrderData);& ?7 \- c( t: m5 _. p4 Z5 |1 V. D& a
  10.                         OrderData = 0;
    : h( n) n# A1 X; C& e8 f& G' K
  11.                         OK = 0;
    & p' j1 p0 c' E. D/ i# G' j) j
  12.                         ReadyFlag = 0;                5 l2 C/ _1 U# D0 W  A& }! n0 D
  13.                 }
    . t5 V: R% g% u% {4 y( U
  14.   }
    ) D) m/ @% y5 S3 S: P  I5 C
  15.   /* USER CODE END 3 */
复制代码
$ x7 j6 O$ s  w# B1 R8 m

! l8 O! T& ?+ [: t$ A结果演示

; Z6 u% P6 y0 _0 `5 }红外连续发送5次码值,发送分别为
2 ?" Q  J; E1 n0 ^; p+ i( a
" P) z' b; d0 f, E' Q2 _9 _/ o1011(11), i: G7 n$ K- W8 ^' a
11 1010(58)9 Q& K6 b  i# G" M
11 0001(49)7 R) q- B! C' A. j7 M
11 1111(63)4 d* C/ j. g" w* @& ^/ `
11 0011(51)
$ E. d9 _* Z# ?2 D分别如下所示:* F& k; [$ b. y1 k& X
  h$ [; t+ n8 F- D" n/ @/ I1 o2 g
20201128092712393.png ! I4 X3 A' B' ^/ Y, g" I
20200616155804751.png
赞 收藏 评论0 发布时间:2022-5-1 16:38

举报

0个回答

所属标签

相似技术帖

官网相关资源

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