找回密码
 注册
关于网站域名变更的通知
查看: 272|回复: 3
打印 上一主题 下一主题

51单片机红外遥控器读码、发射程序

  [复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-5-19 09:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
( m4 e+ W6 O! ?, H# H+ k
采用STC的51单片机,STC12C5A60S2,可以直接串口编程,而且是1T的,非常方便。
% G: t4 M$ F+ c' _& Y
# O  s4 @5 o0 R2 E( ?$ s; z% D一、红外遥控器读码5 D7 V) a: X" ]' O) c  Z; K
读码程序没怎么修改就成功了。& T; C) k9 Y) M# Q3 M
注意:这里的延时程序是STC12C5A60S2的,如果用别的单片机,需要修改。0 j4 z5 q% }/ W, x
, Q: B8 s. h  G* ~1 x. r; P7 h
#include <STC\STC12C5A60S2.H>. ^& ]7 o- o% A+ E8 X# i- j
#include <INTRINS.h>& p$ T. I' B% ]# i
  [& p! c% A) [* J1 P
//采用1T周期的STC12C5A60S2单片机,11.0592MHZ5 Y$ ?, p0 p+ ~2 a' }+ t
//WXL:一体化接收头默认是输出高电平,有信号时输出低电平;接P3.2脚。7 Q* w. K* Z3 I4 B- }
//WXL:这里按“低位在先”
& c- ^3 {7 g; e# C9 P) b
* ^+ b7 n% N! g/******************************************************************/
, @& R6 m; E6 e3 r. x8 H; H7 y/* 本程序的蓝本从网上搜集,经修改并注释,万能遥控器解码成功 */
- O+ V5 |2 W. E8 c. E9 J0 _# S2 V/* 晶振:11.0592MHz */
1 f0 K: u8 W. Y* C/* 整理与测试:单片机教程网  胡琴 2012.5.15 */
2 v2 s# Z: w" Z. E0 b/************************* 说 明 *********************************/
2 a. e! z' g; E/ u: X1 e/* 以一个9ms的低电平和4.5ms的高电平为引导码,后跟32位二进制代码 */* ~, X7 r4 v) h7 J
/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码 */
( S, F5 s  h  B; [1 f& d/* 以脉宽为低电平0.565ms、间隔高电平0.56ms、周期为1.125ms的组合表示"0"; */5 A: C; L0 G* m# `# T
/* 以脉宽为低电平0.565ms、间隔高电平1.685ms、周期为2.25ms的组合表示"1"。 */7 |- @) @% }( W" Y, k% g* ^) c
/* 注意:接收码的脉宽与间隔是对发射码取反的,即间隔是0.565ms */9 V& V: E4 |0 a3 u5 k+ X' Y3 R
/* 解码后共有四个十六进制码,本程序取第三个作为识别码 */7 c; R5 v# M, ~# F3 P
/*******************************************************************/) e* f8 r/ V4 B4 G+ x

: ?& I+ R5 }3 i* w+ C( d#define uchar unsigned char
, w: y" R( t# b# Juchar data IRcode[4]; //定义一个4字节的数组用来存储代码
7 m4 D# z+ T% Z4 y1 i$ s  I2 q# a/ Ruchar CodeTemp; //编码字节缓存变量
7 [1 O8 K% ?4 |* |" S7 G$ luchar i,j,k; //延时用的循环变量* ?  ~% O3 B8 Y/ U4 {
sbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)2 F2 O2 M5 K  A/ _1 `; {1 [
sbit P0_0=P0^0; //P0连接到 LED 上
5 t  c5 u4 q$ T" ^  ~sbit P0_1=P0^1;9 g4 [8 }8 M0 Y8 Q& s6 K
sbit P0_2=P0^2;
+ \8 u3 E' f- b- l
/ i; E% V! Y% j$ u
* \3 ?9 O" T  f* e) F8 @2 a- O; m- Z5 C4 R4 [, a6 U
/**************************延时0.6ms子程序**********************/
) m7 S2 c5 F- k& @void Delay0_6ms(void) //@11.0592MHz# M$ A5 }8 J% }# @  s5 x
{% z/ W7 D$ i9 ?
unsigned char i, j;
0 M  ?' m3 Q* w0 p4 t; m/ F  Z0 o2 y' w1 o2 ?! M
_nop_();7 V' R7 P. c( i2 F4 ?6 `
_nop_();1 w- b3 z6 b5 g+ ]& N$ k8 Z7 o% ]
i = 7;; z0 u1 a4 z. n4 c6 H5 h# a) }3 V
j = 112;6 y) p1 p0 C! g; ?' I0 U
do
1 x- D# ?1 m) `" U; L0 o{- c! F* L0 k6 o! H3 I* R
while (--j);
$ z0 u( R: a, _% C: w5 ~( |! M* N} while (--i);
2 G- N# h$ K6 ~+ v0 B! N$ K6 I9 b3 K! X
}
0 v+ x0 e+ l* c0 |! g5 d9 e" L
: ?/ Q5 m8 M1 {7 \( [$ r. G) r/ z  x+ s; g+ ]$ N# |
/**************************延时0.9ms子程序**********************/
; R) u: M- \/ p5 z* Z0 N8 yvoid Delay0_9ms(void) //@11.0592MHz
, g8 Y- J5 z& N  s5 U. T: l6 r{
2 P% w( e9 m5 f# ~+ junsigned char i, j;
3 ]' n4 Z( h4 |* }) R/ A7 v_nop_();
! I$ K. P5 n+ Z3 j4 m# y_nop_();
! g5 e2 n( ^* B( y& E9 l' q9 i_nop_();
1 ~( D: v( A. Z3 i2 w+ d) q7 Qi = 10;
: [4 \& O/ m; r8 |9 z( p3 Pj = 170;2 S2 Q0 G3 N# F% g7 Y( g% n( P
do& m4 E# E5 y8 s7 q/ `4 q0 \2 p) j
{6 L6 X; S+ i) z
while (--j);8 L+ n  t0 ~# K$ I& b9 h
} while (--i);
. K* J( h3 a4 E7 K, k}  j8 n2 t% |9 a2 ^# t! S$ T" ^
- [7 l" \% @' I# E  g+ V
/ W( |0 ]; r0 M1 D8 p$ j$ Q1 |

' l! C) B  P2 X; U4 r- z9 P* j3 O3 i! B1 Z/ ~& M, E: ~! J
/***************************延时1ms子程序**********************/
4 J3 y5 U$ S; W; xvoid Delay1ms(void)) Q# K, }- t. x3 S, Y
{
1 i8 d2 z$ l" j+ gunsigned char i, j;
4 @  c1 Y6 ?. b1 r3 A# [" m8 k, l) e9 R1 D+ d, Q( K7 ^
_nop_();
2 c2 g! B5 M$ I/ f0 e5 mi = 11;
! S3 `  \, p3 a' ^0 d- i' Mj = 190;
! V* ^! @' I, c. W/ M$ bdo+ ~: ^( {8 Q8 [0 s9 _6 h$ ?2 w
{
( d: _3 L" D1 Y+ nwhile (--j);
% A$ F) e8 i3 `* t: `7 |- X+ J9 V' W} while (--i);/ A0 u( z/ S7 U4 n! I) [
}' s9 {8 n* I+ ?1 k/ S6 m5 U7 `

7 h; O# o$ }: M& a/***************************延时4ms子程序**********************/2 H; V3 ?1 v4 b' X7 i; K6 H2 w
void Delay4ms(void)
1 r3 q4 q5 h# A{
" c( U- W% w9 s$ Y, Qunsigned char i, j;, x1 l+ X) B1 P6 o% L+ i: w. M
4 p, G, E# g( p
_nop_();* l- Y' Q6 _1 U- v- m3 L
_nop_();3 t2 Z% ?- }) d2 y3 {
_nop_();( L( m( w6 b; ^5 l9 Y$ s. H  Y
i = 44;
: h& r7 Q: T" K9 U/ xj = 3;
; r1 W& w0 k$ ]  Udo- }8 @2 t$ M. W! {* p( J  ^
{7 w2 h2 B* e1 E$ Q# G
while (--j);: f/ I  K6 H4 I6 {7 g
} while (--i);
4 X/ G" r/ x- C}
4 y7 `3 ~# f) _' \1 b4 ~1 b) P, M7 D' |( [2 I7 z3 y
/**************************** 延时子程序 ************************/1 i; c) ~5 [7 h/ P
void Delay(void)+ @* J) y+ ^5 @: u+ ?' [' z& E
{, `* Q7 k" ]4 D, o% T3 H0 }+ u
uchar i,j,k;
$ n3 {% |0 U& N; u6 {3 r" xfor(i=200;i>0;i--)& i0 b. C6 p' _( ?  B
for(j=200;j>0;j--)
% S8 t4 {" _5 |9 X1 c7 {for(k=3;k>0;k--)  ;
  A/ M% i; @" \9 E}
: e0 u/ o0 b8 V
$ i6 O# x/ @( \7 w2 J# O/******************** 中断0解码服务子程序 ********************/
% J; b1 d, {6 Q: @1 Y. `void int0(void) interrupt 0 using 24 L9 G! u/ y+ L4 M
{
8 v' \/ R% H3 s4 k& |3 aEA = 0; //??? 可以这样,跳入中断,但仍可对P3.2(INT0)进行电平变化的读取
/ D1 u4 ^$ J5 H7 E+ K% Ofor(k=0;k<10;k++)2 R4 Q9 ~! p5 k+ z2 @
{
. F5 v+ l2 f& Z1 ?Delay0_9ms();
2 w) B$ W/ ?: Z1 A6 d! \8 Gif (IRsignal==1)        //如果0.9ms后IRsignal=1,说明不是引导码,退出中断
2 Z# ~" i, H" B) x{
- m7 `9 [; Q8 n1 t9 jk=10;; W5 z# A9 Y; x: R9 U
break;
0 r' p3 y/ `4 I8 q8 _# p* x' i}4 ]6 K& @- A& v% W4 m
" d' J* f6 o& o3 Y# W3 y
else if(k==9)         //如果 持续了10×0.9ms=9ms的低电平,说明是引导码。WXL:一定是从引导码开始
- m$ z6 O$ V+ H- F{
# M' e) z/ @, D- C& Xwhile(IRsignal==0);      // WXL:因为红外头默认输出是高电平,故用while(IRsignal==0)很安全,而用while(IRsignal==1)则可能会进入死循环/ o/ x% H8 D, B7 J8 j' Z2 J, s
Delay4ms();       //跳过持续4.5ms的高电平     WXL:要超过4.5ms更好
4 e  F9 h5 |. r$ m! m& TDelay0_6ms();. b% }1 ?- T: G
1 W+ J& S, X* S9 h$ c" z: @
for(i=0;i<4;i++)     //分别读取4个字节! r) p1 a+ E2 S5 o7 b6 G" A6 T) o: a
{& l' h1 _% _2 k: P9 q! |
for(j=1;j<=8;j++)    //每个字节8个bit的判断" w& x/ b8 v  o5 X$ w
{
  \5 ]) e" p0 g- S5 U+ }( owhile(IRsignal==0); //等待上升沿,此处用得很好:因为0.56ms的低电平(接收时)是代码0与1的相同部分( {, Y8 m, w7 |
Delay0_9ms(); //从上升沿那一时刻开始延时0.9ms(因为0.9介于0.56(=1.125-0.56)与1.69(=2.25-0.56)之间),再判断IRsignal
$ d5 F3 L; S+ Z- C0 iif(IRsignal==1) //  如果IRsignal是"1",高位置"1",并向右移一位
2 \7 t! t5 _$ H* |. g7 M$ _, D{
; C. N1 A) K/ a" lDelay1ms(); //为什么要延时1ms呢?因为要使IRsignal跳至低电平(即0.56ms的0与1相同部分上)
% {0 |( t# d2 JCodeTemp=CodeTemp | 0x80; //此处的算法很好/ R7 V. a  y! Z' U: F
if(j<8)  CodeTemp=CodeTemp>>1;/ x+ H/ V5 s& ?5 `) f4 E
}1 {9 p2 h; U5 m! Y* H( p
else       //  如果IRsignal是"0",高位置"0",并向右移一位
, _( w( Y4 d' X& A* Mif(j<8) CodeTemp=CodeTemp>>1;   //如果IRsignal是"0",则直接向右移一位,自动补"0"  B/ a/ j: l# v% E( V
}  }* E. n* P6 W& |
IRcode=CodeTemp;
* B+ s  p  c( m  E7 pCodeTemp=0;& A3 S) [% ~: a, D' p, h$ t
}   //end for
- b4 V* V$ C& {% u8 w& ?0 L/ D, C; z% Y1 e2 r
for(i=0;i<4;i++) //通过串口将代码发出
! g9 A! H, }( J5 N  m( O: m{
, c6 c7 b' A2 ~5 i/ YSBUF=IRcode;7 T+ k2 `, w5 T
while(!TI); //等待一个字节发送完毕
; J: \7 k& X8 X+ PTI=0;' S3 w# u3 S: F, Q$ d
}
& E3 Z& I' Z& M& j0 `. Y" ~( M  \# x) \5 F5 R0 V, b# i* o& O9 j
Delay();
- N5 {+ k7 l( Z5 t" E: I5 f}    //end else. T% B6 L  y% H) \
}   //END for3 \& f. d3 p1 F! r) z
EA = 1;
6 n1 `* ?! S$ I5 D- V+ k+ Y}
  \2 x% F  x4 Y! Z# v. u4 |, M
7 b# y; ?' ~" J6 z/***********************串口初始化程序*********************/$ x8 C) k1 F6 _
void initUART(void)
% Q7 G5 k  K8 v" ~# c' P5 \{8 }; E) Z9 U" ]! X2 N, `* D
TMOD |= 0x20; //  Y+ h% x9 J+ C" G5 A! Q6 Z
SCON = 0x50; //
) O0 Y4 v* K3 [4 N; u% V" iPCON |= 0x80; //
5 A  O( k1 Y& O4 ~' J. TTH1 = 250; // 9600 bps @ 11.0592MHz
) A- k! b. i: U  V$ ETL1 = 250;/ ^: X3 q9 w  m" ^+ m4 k1 A
TR1 = 1;
7 ?, ?( t7 a5 z$ g}
& ^5 F+ k: u% X# a1 x
1 y7 Q6 U3 T4 n' e9 K9 V/**************************主程序*************************/. g! g# t/ n0 F0 u* E
void main()
8 `3 _5 x, d4 P2 _{; k9 ]+ s" e8 }7 X
//P0=0XFF;3 V! a  ?, G4 w3 @
initUart();
9 {2 q, I' [2 fIT0 = 1; //INT0为负边沿触发, (1:负边沿触发,0:低电平触发); f1 A* R/ h: u# G2 @
EX0 = 1; //外部中断INT0开, (1:开, 0:关 )
- ^* l6 F0 t; v# CEA = 1; //开所有中断
6 E, K7 R% R' `! e( z) `0 H& f' R5 D! K7 H; p- w$ Q
CodeTemp = 0; //初始化红外编码字节缓存变量- X% \: i# v' c. V8 Z2 U
Delay();: s  }3 ]# o. `. _
while(1)/ b; Z* N2 V5 s+ m7 n9 J
{  |3 G; P1 h! a4 h
+ @. D, b3 P! m3 b/ m  |6 w3 _
}( c9 d7 [* S2 y" @
}9 |! C- h: D( o# [' {+ s

' ^8 Y: O3 J7 J! |! K
( ~' C+ M( Y5 }! N/ v9 p
1 Z' _  K7 r! \3 [" {" W: n- m3 o. J' A  w
- I+ W- `; @' U

; ~2 ^: Y  `9 c- A& F二、红外遥控发射' x, X5 y; C: n9 |0 }

$ R! ~6 o" N. ]9 Q# j( h4 s  u网上的程序是http://gudeng614.blog.163.com/blog/static/818017420101545648734/
' N6 u2 \# y; L6 Q3 ]$ N9 i
6 H# h4 O: c4 `0 j4 I3 N0 p做发射程序费了很大波折,因为网上的程序不好用。
/ e3 D2 i* E5 n* H
$ q7 ?" F: v/ D+ l! p6 ?9 u后来不得不用计算机的并口采集了发射数据,发现数据有异常,终于找到了问题所在。2 \) P1 H% M% r' u- o0 e/ a

7 }8 o- J( ]! V) D原因是count变量是int的,对其赋值或比较时,汇编语句一句完不成,会被中断服务程序中断,造成count变量赋值或比较出现问题。, Z: }9 [/ x3 o5 d
解决方法是必须在操作时屏蔽中断。而flag变量是bit的,一句汇编即可完成赋值,故不会有问题。' S2 |3 U  K+ P& j

5 R0 z+ ^* A3 L, I1 m5 G其间还发现别的遥控器会在起始码前加一个前脉冲,以为是这个问题,其实不是。
* [: @7 r# D/ D7 W0 L  _9 @# n' e9 Q7 u9 f- L# P
注意:由于13us会中断一次,这里是采用1T的单片机。如果采用普通的51单片机,由于是12T的,不知道能不能成功。$ M4 ^) b3 D1 [5 V  |
4 f( U* `, l* J1 _, U6 s* U: m
//程序从网上修改而来
5 B: T8 A4 V) r( O( |0 c//由于中断需要13us中断一次,即中断要在几us处理完,因此需要单片机速度比较快,用24MHZ晶振才能保证正常4 \( p) z& e0 J& F8 P
//但24MHZ晶振,用串口不方便" E& C5 K0 \+ ^$ j9 m
//这里采用1T周期的STC12C5A60S2单片机,11.0592MHZ,可以兼顾。" }# _$ _- [4 S* G- L4 x& s
//STC12C5A60S2  引脚可灌入20mA电流,直接从正电源→红外LED→串1K电阻→P0.0脚。
! C5 j( D9 F+ C; a; l: c8 M! Z8 P//串口1默认选T1作为波特率发生器
1 O: C* G$ r. v6 c3 s, @//TO用于中断
' ~5 v  H) G4 J  U" g, {//发送时,低比特位优先$ R7 E5 I1 X- Q9 H
) l6 S4 t) _5 w5 U5 _$ r' |
#include <STC\STC12C5A60S2.H>4 o5 n4 P" u/ W* P
#include <INTRINS.h>
2 `: e; I& Q8 ~9 J
0 {8 C5 M- X/ F7 wsbit  P0_0 = P0^0;# R8 a  |' a3 ^9 x4 M
5 c$ b9 v4 d% |3 O1 h; G8 `
static bit g_OP;            //红外发射管的亮灭1 d8 d# r+ {  p4 ?2 m( l
static unsigned int g_count;       //延时计数器
1 j! k, ?& k  k, Y1 T/ O* x( bstatic unsigned int g_endcount;    //终止延时计数
7 v# q; o' S# f& [+ {4 ]static bit g_flag;       //红外发送标志. x; R4 k0 ~' F* C, m/ t2 V
unsigned char g_iraddr1;     //十六位地址的第一个字节& i+ _7 ^0 A8 T! e+ r! [
unsigned char g_iraddr2;     //十六位地址的第二个字节
" s* G3 f- v* a8 m$ k# k* Z2 C% v# D* l5 ]- |% R, w
0 m; f& o4 Q% Y. b
//定时器0中断处理
% p2 n) m- M% ?  avoid tIMEInt(void) interrupt 1+ l# C* s0 ]' U4 V4 y0 N
{' h5 t8 P( ?* {, s( ]* ~0 P; @
  g_count++;2 t7 P& X. ~1 L; d7 c- Z; x, k* ~
  if (g_flag)    g_OP=~g_OP;
( F/ a: [% ~& x2 o5 O8 f& r7 c: d  else    g_OP = 1;    //LED不点亮% q) T% }0 ^) D  u" l; t
  P0_0 = g_OP;
, @0 N: w3 d, A+ [/ y  M! s  n}- K+ C8 U0 u. M
- i: H" l" C% C( o4 a- B
0 `. y- A9 \! t2 g- y$ r
/////////////////////////////////////////////////////, i; o* M! z# R6 c
void SendIrDAta_38KHZ(unsigned int temp1, bit temp2)" W4 d0 H, j: Z. d7 y& d
{
1 Q0 }5 t: v4 `$ b; C2 B0 R2 f  g_endcount=temp1;
0 y+ d% u" t1 y7 z' ?8 {  A  g_flag=temp2;: J$ R# y# P! \. `3 f3 P7 Y7 @
  EA=0; g_count=0; EA=1;  //避免中断影响count置数
1 e6 P# g3 [3 a/ D4 B  while(1)
4 ~" I4 Y4 K: z3 K4 Q0 m  {
( K3 i% c* W+ u  k8 ?   EA=0;$ A' Y, Q4 Y" w) `0 z5 r1 q
   if( g_count < g_endcount ) EA=1;  //避免中断影响count比较9 }; ]2 X% m5 Q8 O1 n
   else
! n+ U# Q  `6 _0 I! O   {
$ h4 T0 f5 V3 n   EA=1;
) m4 \" t6 q3 ?6 m; H- J& R( L   break;
+ c" d; w/ Y. l5 ]# i* y8 z3 V. C  I   }  7 l! ~8 Q& [. r- S4 x: o% p/ e; N
  }  
" {1 Z' U& V' G. _}4 @% Y7 s9 m: q6 `* c

6 r2 O. N$ K9 i/////////////////////////////////////////////////////
9 l; a. Y, U9 G2 j( `void SendIRdata_BYTE(unsigned char irdata)2 ?9 F' ^8 l) j0 ~$ j% X
{% k3 L7 M  _- Z- u
  unsigned char i;6 }0 T. a3 P6 q/ w8 y/ Y1 y: u
  for(i=0;i<8;i++)0 N; ^/ [/ s: u" z1 g) Z) Z9 W
  {
& C5 I) \3 Y7 H  |. S5 Z     //先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)
; U- W, F. y& r/ ]; ^SendIRdata_38KHZ(43, 1);   //13.02*43=0.56ms9 b5 O: h5 \0 m: ]3 n
0 P; W5 {8 \0 d) V" e& @
    //停止发送红外信号(即编码中的低电平)2 k: g- J; x! S# d" n
     if(irdata & 1)  //判断最低位为1还是0。   低位先发送!!
* Y4 w1 ?: W% X( r       SendIRdata_38KHZ(130, 0);         //1为宽电平,13.02*130=1.693ms) ^9 E( ~: ]" k3 N* G
    else      SendIRdata_38KHZ(43, 0);   //0为窄电平,13.02*43=0.560ms5 P( o. h$ }$ m
1 {0 i/ R0 ?3 E; I6 ?; V$ K
    irdata=irdata>>1;: d+ M1 h( E6 |- {
  }) W$ |0 P6 ]  |+ Q1 J0 ^0 I; D
}
4 Y( U; E' M) ?9 K2 o9 w1 S. s& Z5 t  D- `. I
/////////////////////////////////////////////////////1 ~  }" B( m4 q8 `  j/ m& ^, C/ t
void SendIRdata(unsigned char p_irdata)& J5 Z; m( V, S0 J
{, W4 ^$ o! e# `# `; v! G
  //有的遥控器会发一个前脉冲,如果不灵,可试试加上前脉冲, I# M# l" {3 a; o: T% U! b
  //发送起始码前脉冲,高电平有38KHZ载波, ?5 s" a! P) B9 B! [+ k4 ~
  //SendIRdata_38KHZ(18, 1);
* W& n' V- c- }  //发送起始码前脉冲,低电平无38KHZ载波
2 i. u1 \: i( L$ F( u  //SendIRdata_38KHZ(18, 0);
/ h3 j* i2 R' u0 m9 d( v* R
6 K- }1 Y6 i) M' o( }2 e7 f  //发送9ms的起始码,高电平有38KHZ载波5 m2 W$ H3 t) m4 h8 B1 v
  SendIRdata_38KHZ(692, 1); //13.02*692=9.010ms  [5 \# x' A. I5 M

4 w" @, V/ U% c) \: Y, k1 O5 o  //发送4.5ms的结果码,低电平无38KHZ载波
# U1 T3 I0 Y7 A# J8 M4 ~2 v3 A7 e4 y  SendIRdata_38KHZ(346, 0);    //13.02*346=4.505ms
2 e) m6 s; T2 n/ `9 m0 O$ i! h5 ?7 e! f4 q) c$ c7 u+ l. U. w
  //发送十六位地址的前八位5 Z. I% J* _5 P% O% S% d! O
  SendIRdata_BYTE(g_iraddr1);/ `6 d  D7 W* Z" U! x% a

$ c0 Y/ L! z" z0 E2 v, [6 z3 ~  //发送十六位地址的后八位
; ^* R: m# `4 Z3 ^  SendIRdata_BYTE(g_iraddr2);' Y# C. c% s4 r7 N6 w) C8 B1 m) `
& a- u* z. b) @; T: S+ u7 K7 z
  //发送八位数据  @1 ^" j4 `/ h8 t. e
  SendIRdata_BYTE(p_irdata);( N3 F) V4 O5 b0 ^3 ~; l* h) l

; g& p9 Z. s- A- H  //发送八位数据的反码0 ], B8 o2 K0 ~* K, R7 x! C
  SendIRdata_BYTE(~p_irdata);  
( ~+ t0 n) O+ ?; H/ a, `' V3 l0 {; ]% y
  //发送总的结束位1bit
$ s4 i6 w6 c( Q  SendIRdata_38KHZ(43, 1);     //13.02*43=0.56ms
& X8 s" _7 w: c7 q+ O5 B" e# a4 u" L. k/ q* ^

) q; O/ r, r% p! A/*  //后面这些可以不用发
' O; a0 R9 ]7 ^6 y5 x- |  g_endcount=1766;0 w/ |+ _9 g% p. ?4 A
  g_flag=0;* h  u# `, G; F" J8 ?
  EA=0; g_count=0; EA=1;7 f  e9 P% I% `9 c% h5 v
  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   
: B  l2 _0 I* q' Q$ b" {4 R; Y2 w2 f
  //发送9ms的起始码,高电平有38KHZ载波
# A. S! x; ^7 k" h5 m# P! v* p& p9 n  g_endcount=692;   //13.02*692=9.010ms
# n/ \" I( E# e: e8 b, P- i, B  g_flag=1;
! O3 F2 A9 B% k9 k  EA=0; g_count=0; EA=1;
5 W3 c  C! s2 n. ?3 k3 M  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   
+ b7 s: r/ J$ s
* j+ H+ p9 m  ~5 B% U7 C: O  //发送4.5ms的结果码,低电平无38KHZ载波4 X& h# P3 L$ R8 Z
  g_endcount=346;    //13.02*346=4.505ms  W* }+ [& b, }* n; C7 M
  g_flag=0;
1 s8 m1 E- j5 g) M5 e6 G* V/ r  EA=0; g_count=0; EA=1;, p9 g9 f, `* S2 ^0 y
  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   
6 f' d$ r. Q7 P, b( G6 |+ x. h
9 u  X/ m) m3 z5 r1 C7 ?( h//发送总的结束位1bit
4 Y' k' }$ t& F8 g" Y0 u0 B' J" j  g_endcount=43;    //13.02*43=0.56ms6 G# O* x( T$ A1 Y1 Q4 y
  g_flag=1;" D" ?/ d1 o3 S2 E, \" ^
  EA=0; g_count=0; EA=1;
% ^* ~: Y2 t: S5 K0 N/ ?  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   
# m' C8 z( j/ ~
. Z5 ]$ ~0 b# f5 \9 H: @*/
0 X8 g# T" G+ t2 c1 W- `2 v) N# R5 v$ P8 ]
  g_flag=0;4 h/ L* B/ _# {. ~1 {: X( u" D

# ^- ]" A0 i( p2 S) R7 ]  j
% }1 H$ O4 a+ H* l$ s/ H( ?& k}" f. W- r: ]6 H, ~
2 \" G% `/ D( s, K; Z; W
  V: u( k) q9 y/ t" j" m% R5 j1 ?
+ e* o- A, h: u6 ]0 d4 C3 a
///////////////////////////////////////////////////////////  P7 y0 z5 ~1 `) y
void main(void)
. n  z  h0 m0 e' f6 j" V) U{# E! \5 b7 Q  w
unsigned char com_data;    //数据字节' z. h5 I+ c7 T

" _0 B$ b& n7 j. P' e* B  g_count = 0;
2 g1 r3 V; A: b5 \" `+ M  g_flag = 0;+ s' L  s; t% G; H4 A
  g_OP = 1;
! V: y' @, ^9 T1 ]) ]9 S1 I' T6 t  P0_0 = g_OP;   //LED接电源正极,不点亮
8 _0 s  {. l3 S) @! J' F9 l
( k1 d) {( l7 ?4 zSCON=0x50;  //串口方式1    01 0 1 0 0 00  模式1,非多机,允许接收,无数据位8,清中断标识TI和RI
+ U! k  P- h# t* l0 e9 \( t$ w7 S9 m/ i" }
  TMOD = 0x22; //(定时器0和1:方式2,自动重装,8位)
, k9 y( I/ G: K/ z) i4 N1 ~TH1=253;  //11.0592MHZ,9600bps。没有设置SMOD,故波特率没有加倍。即:11.0592/12/3/32=9600bps. C: P. u& i0 G- R* h( Q" P. ^
TL1=253;: ~  }4 c; Y1 I' k( _% O$ k: n
TR1=1;    //启动定时器# d. ]* G# i, k$ m$ U

: ~$ c5 @; ^8 t! Y  TH0 = 244;
! S2 A% ~1 K5 {" D  TL0 = 244; //(WXL:即计数12次中断一次,即11.0592MHZ晶振,机器周期是1.085us,12次*1.085=13.02us,这样达38KHZ。  13us一次中断,时间太短了,所以单片机要快)
, P6 p9 c% ~9 n  ET0 = 1;   //定时器0中断允许
4 T$ a4 p/ v* p# B/ @! n- T! F! ?" m  EA = 1;    //允许CPU中断
$ z: f$ H! f; c" x7 S+ g: `) i  TR0 = 1;   //开始计数
# R$ n5 d$ O; D* |# p3 ?  n. c% ?/ _' c  ?. i& o
  g_iraddr1=0;       //地址码2 h1 Y# ?2 v, Z$ p( V
  g_iraddr2=255;     //地址反码
( E6 D* U* Y  j, U2 [8 T5 H. z% S* e2 H! _
RI=0;! k% r! ]6 u7 g% p) Y
while(1)2 W/ R6 w$ w1 R
{
4 l& Z$ G4 _4 Z, Uif(RI==1)8 P  M! E" b2 Q7 e! S$ P% J
{
3 G; M$ _& [, z2 Fcom_data =SBUF;5 e( {- e; w- M: B
RI=0;       //要人工清RI7 z3 E0 T+ k: Y  o3 j6 ^+ Z
SendIRdata(com_data);   //发送红外数据
, v: d# ?4 p# }8 UTI=0;  G' m" n; u1 R+ K& g
SBUF = com_data;   //输出字符
$ w# G9 ]3 p$ F: k) wwhile(!TI) ;     //空语句判断字符是否发完,TI=1表示发完
& _$ o# ]! l6 o' Z; H7 Q* t% _TI = 0;         //要人工清TI
2 o' ]& s5 d0 x  x1 K}4 s1 G8 A- r3 q3 y6 P" M$ B# C) y
}# C" F, A' g# V9 E5 V

7 o! F1 }, y# m9 Q, B( t* ]) K}

该用户从未签到

2#
发表于 2022-5-19 13:00 | 只看该作者

- z. p# @% X. n, W) S谢谢楼主分享,收藏参考学习下,在学习中

该用户从未签到

3#
发表于 2022-5-19 13:54 | 只看该作者
感觉就是很详细啊。O(∩_∩)O哈哈~

该用户从未签到

4#
发表于 2022-5-19 16:42 | 只看该作者
O(∩_∩)O哈哈~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2026-4-18 23:38 , Processed in 0.125000 second(s), 24 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表