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

基于STM32CUBEME红外NEC解码,定时器TIM捕获经验分享

[复制链接]
攻城狮Melo 发布时间:2023-4-13 18:15
概述
   本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。
! w+ S; J$ ]. H; T. s9 ~7 H
硬件准备
    首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:    % Y5 \9 @2 |( P9 T. d. k

3 S, R2 L% L2 o1 C4 N
微信图片_20230413181540.jpg

( x. E  L0 W$ S- O0 X选择芯片型号
       使用STM32CUBEMX选择芯片stm32f030r8,如下所示:
" b% |  |, B2 t! l, A
微信图片_20230413181536.png
5 Y6 w0 ?$ K7 q# L! H" i* q! e
配置时钟源
    HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:
0 W" u2 b- ^/ r5 |' e+ e; g
; q' |0 |8 M) g6 U# }# ^" A$ T
微信图片_20230413181533.png

6 p' a$ {  X8 G3 @% w$ X9 z+ i
配置时钟树
    STM32F0的最高主频到48M,所以配置48即可:
+ A) A% R! u8 J& S" L

1 ?5 O  g8 y4 ~  U
微信图片_20230413181527.png

  I0 o+ h' ]% d/ F; `$ ]1 l5 [8 Y$ b9 c1 D: q6 v7 L
串口配置
    本次实验使用的串口1进行串口通信,波特率配置为115200。# l4 X0 w- H- P1 B/ J8 i9 A7 C: h5 Q

4 \# d* ?2 X9 o1 p8 T9 u
微信图片_20230413181524.png

+ O9 F3 H4 q' L4 j7 A; t3 T) y定时器配置
   本次使用定时器1的通道2进行检测,配置入下。

# O5 Y" l  Q- I5 u: C
微信图片_20230413181521.png

' |: h4 v8 N& k0 U) b( E2 B/ j9 ]红外接收管
    这里使用VS838的接收管,如下所示:

4 C$ a8 Z( i: c* B
微信图片_20230413181517.png
- F  G$ m; R; K5 L, U8 E' y
红外编码
     NEC协议载波:38khz
    其逻辑1与逻辑0的表示如图所示:

# `0 l8 l9 K  P6 G  F8 o& [+ l
微信图片_20230413181514.png

# n" D4 v6 R9 ?* m% S
    NEC协议格式:
微信图片_20230413181510.png

3 O% G" I. I) P8 A
0 O/ Y5 b. }. p6 |. W7 }, o( x自定义红外编码
    本文中数据1的低占空比设置为1120us,总时间为1.68ms,不是上图的2.25ms。
    协议如下:

7 ^& \9 x. l+ b
微信图片_20230413181507.jpg

: ]- L! m4 e, J0 v5 h6 e! b: t生成工程设置
    注意在生产工程设置中不能出现中文,不然会报错。! h9 t8 N% P( x8 `1 d6 a2 ?- A" D

' h; F6 B5 a- t$ o. c$ B; K$ U
微信图片_20230413181504.png

* L( i" `& X( u# Z, U代码生成设置
    最后设置生成独立的初始化文件:( b" V6 a+ b' J$ |9 U$ f

. h2 J1 }0 T9 [9 C' k
微信图片_20230413181452.png

: z# i# \6 m" y2 K5 m9 Y
生成代码
" ]$ \. a* ]( r$ y
微信图片_20230413181448.png

" r4 H' q! i! \, A/ o9 R配置keil
% F- m- e' |, e; r9 i& M7 {7 `* ^
微信图片_20230413181445.png

) q7 k. r, M- D, u3 }
微信图片_20230413181441.png

4 T. j2 y0 l7 ]  e8 n' F' W- P
    在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。
  1. /* USER CODE BEGIN Includes */7 Z! b  q4 l: v( c
  2. #include "stdio.h"( t' c  A9 I: ~$ b: _/ |/ s/ W
  3. /* USER CODE END Includes */
复制代码

1 E) V  J: ]" Y# U, i6 f
    红外接收口定义 。
  1. /* USER CODE BEGIN PTD */
    4 R1 r$ N: C# L4 r
  2. #define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)3 J) t1 m2 s1 k; ]- x
  3. /* USER CODE END PTD */
复制代码
* O# j$ I: F. J5 h( d& e4 h
   函数声明和串口重定向:
  1. /* USER CODE BEGIN PFP */
    6 i' S. i; D) ?5 l5 Q9 T
  2. #ifdef __GNUC__
    ' |( R5 W/ Y9 K; h5 f% G9 G
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    1 p0 s; J6 F' }3 @0 ]( q
  4. #else6 \4 Z3 s' K# t$ r* L
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)6 X8 \7 S; o$ i# M) }) D
  6. #endif /* __GNUC__ */& V" P- S$ \- u. S' H$ {. G  U
  7. PUTCHAR_PROTOTYPE7 |# p6 F' V9 M7 L2 s
  8. {
    ; I) E4 g  O5 c% `, Y' `5 ]
  9.     HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
      H$ f8 Z4 J) a2 H) s
  10.     return ch;
    ! {3 b$ X$ o: B! p* G
  11. }! ^% z- N  ^: Q/ `+ c: k0 M( F
  12. /* USER CODE END PFP */
复制代码

' \# r" C$ {0 G+ ?8 `2 D
    定时器配置:
  1.   /* USER CODE BEGIN 2 */$ H. G, _! l, U# Z1 [3 E! X; Q
  2.   HAL_TIM_Base_Start_IT(&htim1);//启动定时器
    2 s7 n4 ^3 I! C( @0 ?4 n
  3.   HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
    " N; I; b, d1 Z  h8 l# ^7 D( j
  4.   printf("IR Capture !! \r\n");
    3 t" |7 J' Z) f, T: Z0 U, @1 x: |. j
  5.   /* USER CODE END 2 *
复制代码

1 \0 _" a! ^! V$ Q
    红外接收代码
  • [4400,5000]是用于捕获4.5ms的信号
  • [550,700]是用于捕获560us的数据0信号
  • [1100,1250]是用于捕获1120us的数据1信号
  • [2000,2500]是用于捕获2240us的截止位信号
    ' N8 }8 H3 V7 o- U0 j
  1. /* USER CODE BEGIN 4 */
    $ c0 F8 ?# o/ b. W- e
  2. // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数; }# D+ E' Y  i1 h; g; _: ~9 d
  3. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim), Q% i5 M% }, g3 v: ?8 U
  4. {7 D$ `$ v; Z( N" }1 x" t
  5.   uint32_t fallingCount = 0 ; // 下降沿计数
    ( I3 K, G* @$ C2 f) q" D
  6.   uint8_t temp = 0 ;1 ^* ^2 {9 W( ^8 q5 e% h
  7.   // 判断是否是定时器1的外部捕获口2' J4 I" j& S+ _! V! v
  8.   if(htim->Instance == TIM1)
    6 v+ }! N$ I9 j/ v. k( |4 B
  9.   {
    ( d: }! W/ m) k6 W3 k" x4 Q
  10.     // 捕获到了上升沿3 ]! H, w  t- Z" l' B
  11.     if(IR_IN1)  C0 r! I  g1 \+ G4 S3 {6 h
  12.     {& q$ [4 w3 C8 K" g
  13.       __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
    4 V1 _; t# v- w8 ]( p
  14.       __HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计
    / h0 t0 y% z* {& V/ Y
  15.     }: t( J* y4 K) [; J% y
  16.     else
    ; Z- k/ p7 x6 ^1 W
  17.     {2 a; C" M+ n2 A9 Z# v3 y
  18.       fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间
    6 j2 a/ u2 G1 b% E' T
  19.       __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
    2 t  U! U; v; M3 {0 n! D
  20.       if( ((fallingCount > 4400) && (fallingCount <5000)))
    & A! g. Z- h) o+ U' Z+ ^4 y
  21.         OK = 1;/// 4.5ms引导电平
    * E; e4 s3 v  F0 i* {! y
  22.       else if (((fallingCount > 550) && (fallingCount < 700)))  * ^; x$ S/ L$ v5 T: k3 O
  23.       {5 B! I  E" z2 p4 e. V
  24.         temp = 0;//560 us,数据为0
    ) d" _4 ^* M) K+ j' u# a& z% p$ n
  25.       }  
    9 P2 s6 I3 H& r7 A
  26.       else if (((fallingCount > 1100) && (fallingCount < 1250)))1 l, H; O! _. v, T
  27.       {
    & @/ c& c* ]: a

  28. 6 s( O4 U9 N/ W6 o5 r0 @$ h
  29.         temp = 1;//1120 us,数据为1
    - \7 i- U& d0 J" Q2 b
  30.       }
    7 O! ]0 l& O$ h1 |9 C

  31. 3 j' Z: k! h9 }) K8 c
  32.       else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500)))  //2.240ms截止码+ s" G1 z# y( o
  33.       {
    7 J& m$ A3 Q' f9 F) ^% ?5 v
  34.         ReadyFlag = 1 ;. J2 F" R  ^- L; ^/ \" a
  35.         OK = 0;
    5 F! x; D0 z+ S. _: C3 X
  36.       }
    # ^3 D" |9 P, j* E, L/ x/ F
  37.       if(OK)/ d2 A- L& w. J$ D1 Y: ?4 d2 j
  38.       {( v( H! I' `2 L
  39.         OrderData <<= 1 ;3 C* _4 w0 c/ M  [' }8 M: J
  40.         OrderData += temp ;
    ' B% @% C- I- [% s" Y# ?
  41.         KeyCount = 0; // 按键次数
    9 @) J+ \5 v1 f7 D9 ^. h, T, A  c
  42.       }
    . W" u" b" A5 x0 h! r$ g) C* n
  43.     }  l% Q5 o5 \" \& B/ z
  44.   }
    6 e/ _8 O4 ~! k2 {9 K3 i$ c+ g+ d; w
  45. }
      y, {7 E7 h( D4 h0 y; d9 W
  46. /* USER CODE END 4 */
复制代码
( _3 G" g: a; G' f" \+ j; r
5 O( |9 O- F) D6 B$ _* p& M7 r
    主函数。
  1.   /* USER CODE BEGIN WHILE */
    - m) X: P9 P& z( z# ~/ j
  2.   while (1)
    ) j' {4 g$ n  s7 z3 b- ^
  3.   {) F* X" v/ b$ ]8 ?; e
  4.     /* USER CODE END WHILE */; ^6 i2 G/ O0 S4 T" Y6 m

  5. 0 J; G$ v1 i* W- v/ A
  6.     /* USER CODE BEGIN 3 */1 e, C3 K7 b( L8 z8 r
  7.     if(ReadyFlag)* {" Z+ f1 P0 }, ~& t: V7 N% |; F3 P
  8.     {: c6 I- m( o. `$ E1 d* U4 M1 h
  9.       printf("order=%08X , code=%d\r\n",OrderData,OrderData);0 n1 q; i& J" i+ [0 [: ?7 M: N
  10.       OrderData = 0;% Z# C* \3 ]) ~& r
  11.       OK = 0;( y8 }9 k. V* v, U2 Z% h6 }1 A! f" u4 {
  12.       ReadyFlag = 0;   
    8 q- R# }6 [+ t* A; N- F
  13.     }
    ; _0 b3 e4 {  }, Z9 s2 n
  14.   }
复制代码

1 S! G! Z: h7 z# N

" w2 F8 b4 F' S( |& `- a演示效果
    红外连续发送5次码值,发送分别为:
  • 1011(11)
  • 11 1010(58)
  • 11 0001(49)
  • 11 1111(63)
  • 11 0011(51)

    # K8 r8 P3 c3 V4 o0 J5 j, i: ~0 A
    分别如下所示:5 v8 g2 M; E* h) V
微信图片_20230413181437.png

7 ]8 w1 B  p1 F6 k
% a( b5 Y5 x" u4 W& z
转载自:记帖
; i9 \) a3 _' I7 x* D
如有侵权请联系删除
0 F' {0 z9 L4 h8 h/ u, E8 J$ H1 p! w. G9 ]% g$ M7 e, z$ z

$ q9 S1 Y( C7 b; T" ?5 Y0 o  L! I: J

$ f! g' z8 K( C0 f3 b( v1 `0 b0 f& A9 U8 T
赞 收藏 评论0 发布时间:2023-4-13 18:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

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