|
概述 本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。 ; J. [: k7 ` `, f
硬件准备 首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:
, X) p3 {; A' X' j( C
* M- u" ?8 L7 T. }; R' `0 u Z
! m) d5 i8 P/ `; M选择芯片型号 使用STM32CUBEMX选择芯片stm32f030r8,如下所示:
3 r7 t" ]7 u/ i2 t$ Z1 {
% O* A* l; S7 L9 \/ o
配置时钟源 HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:
- u& U2 E9 ]) g/ g2 q! v
) L* F& K+ H' Z$ s( H
. ], z& S1 ?# \9 i8 D% A 配置时钟树 STM32F0的最高主频到48M,所以配置48即可:
j9 H. n& t' n
, L6 q+ \7 z$ P3 b4 r3 l
/ \# t' G+ r |4 R# Z/ `) k) u: s+ d0 H) O+ x
串口配置 本次实验使用的串口1进行串口通信,波特率配置为115200。
; v% R; L' `9 U8 A; @3 v& _$ I' r1 V# k ( ~4 i% w+ Z) w$ q5 s* k
7 M! T7 Y, ]+ [; Q- ]; K% X" o定时器配置 本次使用定时器1的通道2进行检测,配置入下。 0 {( P8 X, Z$ \8 u% x
$ w: L K: b% _. p$ }/ w红外接收管 这里使用VS838的接收管,如下所示: 0 d2 ]4 p, \. C) n9 q' l
+ n3 D3 A/ e# f& i; o+ C$ S红外编码 NEC协议载波:38khz 其逻辑1与逻辑0的表示如图所示: 5 F, B" q* A: v5 d p
0 m* ]+ d1 u! k( @- G. M/ r NEC协议格式: 5 F7 u* I5 d: W7 O% c; L( _
8 h8 B0 [$ s/ o! h1 R
自定义红外编码 本文中数据1的低占空比设置为1120us,总时间为1.68ms,不是上图的2.25ms。 协议如下:
7 L. c& x0 w! W' E0 l% }; ]' J+ K" K. x8 M; J9 w/ s0 ^% j5 W. d
生成工程设置 注意在生产工程设置中不能出现中文,不然会报错。- b+ j% w7 }4 `4 u
( Q1 K$ i' c' D
) H( w, D2 @" v9 o代码生成设置 最后设置生成独立的初始化文件:
- x& ?; J, i3 x: b: B
2 k, \0 Z- @# |
1 G! t" `. k! A+ F; R: W5 P0 b
生成代码) W9 a6 f1 K: s& \! J, W7 c
- ^& E3 ?. y/ p# P# U, X5 y; V
配置keil" ^; ?1 D1 `4 c7 a o
! E5 p9 i$ c, u; Y5 q3 B
. J3 m* f* E, w- U
在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。 - /* USER CODE BEGIN Includes */1 ]3 Y8 P- H% h6 T
- #include "stdio.h"# I6 T/ _' m) }- Y
- /* USER CODE END Includes */
复制代码
! k0 J- P4 H) a. ?. V 红外接收口定义 。 - /* USER CODE BEGIN PTD */
" `5 O; R# M# i - #define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)) ?. ?1 L7 y- h5 P: D3 p8 g+ N
- /* USER CODE END PTD */
复制代码 - Y2 d- r# E) L4 v/ Q* I9 @. b9 ?
函数声明和串口重定向: - /* USER CODE BEGIN PFP */
3 C; x1 P$ v. \& G - #ifdef __GNUC__
; A5 T9 p* U) C" u; ?3 I- B - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)7 Z( W9 g+ }! @* X1 D9 ?, s
- #else" d" D" L- Q8 Q$ i
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f), a, C5 a+ ~9 X7 I% }
- #endif /* __GNUC__ */, L* J+ d3 L( {5 }
- PUTCHAR_PROTOTYPE' l4 i: ?0 S3 K& \/ ?* @
- {# r1 W- E/ @ {9 G8 e+ ~& ^
- HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);! ~7 Y1 S* _, Z0 y3 s
- return ch;
6 @/ ]# G0 E0 P; Q# D - }$ Q8 ^: P1 _0 M! [5 G3 Q, ]2 t* V4 N- G
- /* USER CODE END PFP */
复制代码 * W% n; p) {/ m' }+ E( T0 v) X
定时器配置: - /* USER CODE BEGIN 2 */9 p5 w* A3 l: I) S' ?6 P; h
- HAL_TIM_Base_Start_IT(&htim1);//启动定时器* C! L7 `; s ~# ^. O3 j6 Y
- HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
, N- n$ I# N2 q8 b! k0 x4 s - printf("IR Capture !! \r\n");; W P) G4 n+ m' E
- /* USER CODE END 2 *
复制代码 9 h' g, ^# \5 G% P: j
红外接收代码 [4400,5000]是用于捕获4.5ms的信号 [550,700]是用于捕获560us的数据0信号 [1100,1250]是用于捕获1120us的数据1信号 [2000,2500]是用于捕获2240us的截止位信号
9 i8 [+ O& }# }5 `
- /* USER CODE BEGIN 4 */ Q( z% R& I% [- x* v, ?: p3 i
- // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
, Q4 ^% Q& ^/ L# K, \ s! g( | - void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)+ p" S; r; @3 J# |$ ~2 S
- {
; M9 X5 B8 o- B6 l- ` - uint32_t fallingCount = 0 ; // 下降沿计数
2 W1 T8 Q5 }: n$ m% ]* t ? - uint8_t temp = 0 ;
3 ]; G4 n' |2 ?, F8 j - // 判断是否是定时器1的外部捕获口2
% s" T9 u9 r. {1 x - if(htim->Instance == TIM1)
9 `# F1 j% R" b# p6 d- S# ~1 V - {/ Y; W! z1 S# N9 p9 O" N5 E
- // 捕获到了上升沿6 ~ k( ^" Z8 K8 }9 M+ ^( R
- if(IR_IN1)1 k; A' b6 k; C+ k, x
- {
3 Y; v; [8 c( ~3 C, ]" q& J( ` i7 O - __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
r7 P4 ]; K' }( e2 \% p/ C& P$ H - __HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计
) M& d( O' ]2 w5 p* q# F0 Z* H - }" w5 X+ V0 E! ]* S" ~5 q7 p. T ?
- else
5 w4 x& d. o9 N - {+ o! S0 n( U1 G4 m
- fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间& [$ B O1 I/ |8 q W" z
- __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
4 F" ? ~+ ?9 F! `- D - if( ((fallingCount > 4400) && (fallingCount <5000)))
: z& A# i6 J) A1 E# I1 Y - OK = 1;/// 4.5ms引导电平
& T/ _6 P' T5 v( i) p& ` - else if (((fallingCount > 550) && (fallingCount < 700)))
5 S9 f }1 N* { - {
" G5 L, x6 o; B# i& z( H( t - temp = 0;//560 us,数据为04 z) J3 M J$ a- S7 w
- } 3 r% W) V" v2 K+ n# x1 w
- else if (((fallingCount > 1100) && (fallingCount < 1250)))5 q& m4 T* a: L5 }8 O- H
- {
! ]- n' Z, {& Q6 k( s - , h9 @3 ]8 l8 b
- temp = 1;//1120 us,数据为1. r/ n7 ], ~/ H! N* Q
- }2 R6 d* p- f9 V3 L
% P% O6 e, Q2 E, F- else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500))) //2.240ms截止码" B. L1 I& r5 v" u
- {
Q( i. B& F9 a - ReadyFlag = 1 ;
2 _! Q- ?; D) ]' [% o - OK = 0;' h4 a7 N7 a7 }; p: b* h2 _
- }0 f( e2 v1 W5 j
- if(OK)
: F" E8 D u+ x% V! v. f - {
. F. @; T7 s* q- u- X J - OrderData <<= 1 ;: }5 ]/ N. E8 J$ U- u( B
- OrderData += temp ;5 u/ O! J$ W/ Y/ N# F
- KeyCount = 0; // 按键次数- ^8 |$ K8 Z4 J# p' G2 O
- }* e9 T" r" j0 z. F2 Y0 q
- }
: r: A! E& G7 ~& X) o* X# b) L - }( i4 b% S9 |0 c6 j' L& Q0 A
- }
* X) Z$ O8 A, p" N - /* USER CODE END 4 */
复制代码
" x6 F1 _1 j0 ?4 D6 W- \1 N
a# V* w3 a/ Y5 J+ O! A3 | 主函数。 - /* USER CODE BEGIN WHILE */
! l. n, d- c& W - while (1)
5 i- B7 ?4 V! A: h, z1 R+ A% o - {
) c+ a+ p& a% x3 a! m# a0 Q - /* USER CODE END WHILE */7 s) V+ [- H# ]: T% p4 ~4 b! v
, x2 v: {" q; t3 `, v0 T- /* USER CODE BEGIN 3 */- d- e9 `9 e7 k ^( n- @8 {. v2 Q
- if(ReadyFlag)
& t p2 G; @; c& ?1 s+ J# ~" z0 M) G - {
, V+ e8 V/ L0 u4 K0 }6 k$ O - printf("order=%08X , code=%d\r\n",OrderData,OrderData);- ?5 U& Z8 D- G! r- K
- OrderData = 0;: S' n+ @3 P9 d
- OK = 0;
' _% p L9 Y; e# z: G - ReadyFlag = 0;
& q3 h6 A" b; D" O2 t( f) | - }& a3 I" e6 ^. U+ j' D% o& Z2 \" d
- }
复制代码
( R- u* B) \! ]; |% B% `! Y F5 ^4 \; R5 E6 f% _1 k8 ?2 T0 q) j+ g/ P( ^
演示效果 红外连续发送5次码值,发送分别为: 1011(11) 11 1010(58) 11 0001(49) 11 1111(63) 11 0011(51)
7 q! ]9 q) g8 G6 m' q
分别如下所示:
) c, x& M2 j* o( M$ @ A/ q1 ` 7 n c# B/ g0 p$ U. _
; E9 @. P U; B
转载自:记帖
& U& N' o# m5 x6 k6 w如有侵权请联系删除) H, Y) {8 ]/ H- m, C3 L
) ]# ~4 @5 L! A4 N7 C( [
. @/ Y9 v4 s+ V9 N ' r' |) T. U2 K; d
" f# i% D* \4 y p
|