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

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

  [复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
7 P2 Q0 `: j9 G/ x' o
采用STC的51单片机,STC12C5A60S2,可以直接串口编程,而且是1T的,非常方便。
/ }% z$ _% I2 Z. b( f, m# w) |, R9 W& M/ G
一、红外遥控器读码# D* ]" |9 L( C1 X7 e
读码程序没怎么修改就成功了。& @9 Y- A: G2 b" o  F2 V9 U- a
注意:这里的延时程序是STC12C5A60S2的,如果用别的单片机,需要修改。$ Y0 G& }4 u, M9 H
7 ^2 ?% N  F* Y; f1 u
#include <STC\STC12C5A60S2.H>
' p/ r* A' }+ x5 f+ c#include <INTRINS.h>
" m' f( J8 r, A& B' w" B% R8 \& T
" X+ v; g7 w; ~# ?; H+ y/ E3 G4 _//采用1T周期的STC12C5A60S2单片机,11.0592MHZ
! f* Z0 v7 Z1 Q& i//WXL:一体化接收头默认是输出高电平,有信号时输出低电平;接P3.2脚。8 Q! g# i2 K4 c2 E! b
//WXL:这里按“低位在先”
  k: b- r  k7 _# P" x0 u& e* o/ R# k- p
/******************************************************************/) m8 `" n' c# R& J! z
/* 本程序的蓝本从网上搜集,经修改并注释,万能遥控器解码成功 */8 l1 \$ Y; K8 Q
/* 晶振:11.0592MHz */
8 z  \3 b1 g- V: w6 X' a' y1 m/* 整理与测试:单片机教程网  胡琴 2012.5.15 */
' x  x1 D/ X6 }" b9 Z: J% X9 _/************************* 说 明 *********************************/
# k2 l$ A) f6 C2 C  o/* 以一个9ms的低电平和4.5ms的高电平为引导码,后跟32位二进制代码 */6 t% F: H. w/ k
/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码 */; x* h4 I; }, f5 |) O/ t
/* 以脉宽为低电平0.565ms、间隔高电平0.56ms、周期为1.125ms的组合表示"0"; */! ]0 p8 f# @8 e- t* m; J2 m1 v) U
/* 以脉宽为低电平0.565ms、间隔高电平1.685ms、周期为2.25ms的组合表示"1"。 */
% x, c+ @0 l; e' H1 l4 q; s/* 注意:接收码的脉宽与间隔是对发射码取反的,即间隔是0.565ms */
7 P' F  }" K* G5 p4 r/* 解码后共有四个十六进制码,本程序取第三个作为识别码 */# X! {7 t- N. ^, c# |
/*******************************************************************/' A* k2 {9 `3 E# `9 m, l

2 n6 D& ^" S; f#define uchar unsigned char! B# g5 D- _/ R: `2 J6 c' M7 t3 [* o
uchar data IRcode[4]; //定义一个4字节的数组用来存储代码
& N& _- M: b" B: N, T* duchar CodeTemp; //编码字节缓存变量
+ `& b/ J! Q. h4 W) z& e* S# Wuchar i,j,k; //延时用的循环变量
5 X% D3 ^: g; O- }sbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)% _2 c: E) t5 k: A6 @! s9 s
sbit P0_0=P0^0; //P0连接到 LED 上
0 H8 R2 `8 g3 ]; v1 s/ @! rsbit P0_1=P0^1;# C8 C, C6 A" W4 K
sbit P0_2=P0^2;% _: m1 E& k- v  j$ [* c
/ ?. _1 z5 o: o. `

! {" u7 d; R8 l+ {( \# d9 T( U! U  x+ w7 t' E* M; D6 H
/**************************延时0.6ms子程序**********************/
& ]% I+ c' i( e/ o$ U" Ovoid Delay0_6ms(void) //@11.0592MHz
& U% J6 m7 E5 I* P7 C{) n, f  W0 s) Z3 J/ @
unsigned char i, j;6 f( e" o+ d! A* r$ \
( H7 F0 i/ H& I1 p1 V/ J; v! s
_nop_();/ x. _8 f% V5 W, G: M
_nop_();
2 S1 V/ k( u3 H1 S: H& di = 7;) ~: g, n2 Z% _( \/ g
j = 112;! d: C: Z  p7 r& B; E4 K9 y. C: _# I
do) q# L0 \) x) c+ N/ g7 K
{* l8 n" r9 L/ C: M* D, r0 {3 j" q% w
while (--j);+ L; l2 ?! d4 X; d# ?" @1 a) K# v
} while (--i);
. p5 K" h( m% l# O$ i* S' P  @  _4 ^
, g) [5 |+ F' f( S& _9 Q9 j}' W1 k  f5 @& e; P, }

# F; [# t: Q; d( @# y8 @+ _7 X- q7 [+ `
/**************************延时0.9ms子程序**********************/
8 x% V' n/ h. X- q" F8 w2 ]$ jvoid Delay0_9ms(void) //@11.0592MHz; l0 b$ W* x% f% @! U$ w* Y
{
. |" W0 w9 J" j, T+ l+ P& Ounsigned char i, j;
  |- W% M# ~9 B_nop_();0 V/ O: q* J5 U1 b1 O6 k
_nop_();
0 G+ e% x) L. N& ~_nop_();
+ w0 c+ Z, H; {3 M; o  ?% Gi = 10;7 r1 I. y" o9 R' D2 i/ ]% O2 b
j = 170;
* B6 t6 N. e: i7 n' z0 }( Hdo
- ?# i$ t* I# {! f% i{8 o; R: s# S) t' P
while (--j);* @) Q4 t( V* w* c2 `' t' a5 D
} while (--i);
7 _" C* o0 z. U4 `' @2 s}
4 ?- p$ w: ]' f; e
  Z# K8 D% D0 r; B% t' x* ]/ I7 O9 |& X. ?( f* |1 I0 |
3 ^, n4 o* r% i3 M2 K6 O

, ?; R) g; ]' R! H5 J! v/***************************延时1ms子程序**********************// ^1 Z2 {) w5 L! R" _8 a4 w
void Delay1ms(void)* _+ K: |5 v7 y1 v0 m
{, j6 ^( l. h' W) t
unsigned char i, j;2 {. x" N) v3 u, H
/ x6 ~4 f7 e- P1 [. `( b
_nop_();, B8 p" K& n" v: h
i = 11;0 O! }; D1 R1 E! g
j = 190;/ C! T: h  S, d' e( G, W
do
4 O" r8 q. E' F, h( x) P1 B- H{& H! p; V" s+ B% r3 b
while (--j);
" O1 j& `0 s  k% |* D} while (--i);  _% L/ D: @+ J4 [! G' ?
}
1 J3 z4 g& l% l  d# M! A' d1 |' Y
6 s$ a, n$ Z+ ?5 b& P9 L/***************************延时4ms子程序**********************/
" y3 f" o- k3 lvoid Delay4ms(void)
5 o& L/ U% S' F$ d{
. R' H7 e( D0 {8 Y- F+ A6 `$ q5 ]* hunsigned char i, j;
' ]# Y1 ]% n- P" L; h# L: G
1 b" `9 ?* j& Q_nop_();( l6 z+ q+ @7 P- t' x
_nop_();
) v+ w$ z$ r, F  u* y+ H0 r9 m_nop_();
5 h6 Z! ]' Q6 Ri = 44;
; p' f" p+ X; S9 k1 _j = 3;
1 B, `6 j7 [4 n* Cdo
6 R7 k- k5 ]- {7 b% z, o* Y5 o/ R{, @5 X! h$ W7 i. q! }$ M7 n
while (--j);$ B( u0 I$ }! d/ m7 Y7 P  ]
} while (--i);1 @* |( c2 H8 o1 K7 z' r: {8 @
}
( g" D9 ?9 a# m7 t  g6 ]6 G; ^+ S/ m& \
/**************************** 延时子程序 ************************/) B, c2 s) Q( B& f$ \0 _
void Delay(void)
7 m8 K9 [9 ~$ ^1 K1 A4 T* J{4 |$ ?9 G* s+ {" O( a
uchar i,j,k;5 ^/ A4 o0 ]9 i+ D0 b6 }8 g
for(i=200;i>0;i--)
' }# r9 s- v6 w0 p; K# t+ nfor(j=200;j>0;j--)
6 Y& x, i' `5 y9 ~8 E: [for(k=3;k>0;k--)  ;/ u) H) |7 D9 Z  b  Z& C' U" t
}+ i% u+ _) J2 F6 O& T
( Z4 U; g: j3 |( j' T5 ]; j9 m4 \
/******************** 中断0解码服务子程序 ********************/
9 l3 K3 T" J" H5 w( Ovoid int0(void) interrupt 0 using 2
9 O! X3 G( g/ f9 Q$ A& u/ Z{
! Y8 l& F! A2 i; d- I  P8 WEA = 0; //??? 可以这样,跳入中断,但仍可对P3.2(INT0)进行电平变化的读取9 {. \, Y3 y0 d) b. n2 p0 {
for(k=0;k<10;k++)$ Z- I6 ~; w, D4 y3 L2 h& J$ m3 i6 W: a
{7 U+ N! [/ S( ]# M6 ^- U2 p
Delay0_9ms();
9 ^8 p4 ~8 g- B1 y3 t, {9 gif (IRsignal==1)        //如果0.9ms后IRsignal=1,说明不是引导码,退出中断
9 C7 Q  g0 E% f{* ?) N4 A2 L8 ?/ r  M% I
k=10;2 Y2 y* y; `% o. C
break;: A4 ]6 B. A# [7 b* _2 A4 o( V
}: O: [1 [+ M6 I! ^5 G

7 ~. W. j2 |: Q0 Z: k7 Y  delse if(k==9)         //如果 持续了10×0.9ms=9ms的低电平,说明是引导码。WXL:一定是从引导码开始( E. i; d. @& R: Z4 a5 ~
{
3 }- f% ~/ J( swhile(IRsignal==0);      // WXL:因为红外头默认输出是高电平,故用while(IRsignal==0)很安全,而用while(IRsignal==1)则可能会进入死循环5 L. ^# M: i5 r( N
Delay4ms();       //跳过持续4.5ms的高电平     WXL:要超过4.5ms更好0 y2 w( [2 C. _5 g; {; q
Delay0_6ms();: f# b" R, E4 m( E! ^% B
) o6 @6 L; ^+ L4 ~
for(i=0;i<4;i++)     //分别读取4个字节  U/ S5 l/ h6 f5 k4 I- D( {% K
{
  `7 f9 l6 W$ X6 Y  {7 Sfor(j=1;j<=8;j++)    //每个字节8个bit的判断
, ]/ n! Q; W" n{
3 a) W& g# j" T5 Awhile(IRsignal==0); //等待上升沿,此处用得很好:因为0.56ms的低电平(接收时)是代码0与1的相同部分5 d$ Z/ w+ A, J  }% h4 S. K
Delay0_9ms(); //从上升沿那一时刻开始延时0.9ms(因为0.9介于0.56(=1.125-0.56)与1.69(=2.25-0.56)之间),再判断IRsignal
4 Q6 e' n1 Y' h3 F( p$ o9 ?if(IRsignal==1) //  如果IRsignal是"1",高位置"1",并向右移一位* w4 v, K7 O$ X: @
{
, {6 G3 L$ |+ x6 }4 wDelay1ms(); //为什么要延时1ms呢?因为要使IRsignal跳至低电平(即0.56ms的0与1相同部分上)' s3 X9 f! I! m
CodeTemp=CodeTemp | 0x80; //此处的算法很好: Y% B7 Y5 h! A% j6 {* h
if(j<8)  CodeTemp=CodeTemp>>1;! B' E- U# c1 p& E4 J7 G: \
}
) K8 _5 H2 t0 L% ?4 Selse       //  如果IRsignal是"0",高位置"0",并向右移一位
# v$ C, Z  T- sif(j<8) CodeTemp=CodeTemp>>1;   //如果IRsignal是"0",则直接向右移一位,自动补"0"
9 p' z2 Y- r! `% Q7 V  I# A$ S# R& G}
  a; F$ Y7 D0 R$ v5 p2 q. nIRcode=CodeTemp;
6 z3 P% c; r$ x5 oCodeTemp=0;2 y9 ?( N' p5 |+ Y) U% ^. u8 j4 M: M& {
}   //end for7 W; [" c: y7 y5 N6 D

, f( T+ S9 b5 h; _9 }( b) Zfor(i=0;i<4;i++) //通过串口将代码发出( [+ G, M! L) h, a% `  f9 f# X6 P
{2 }: |9 {, x0 @  F8 ?8 \. Q4 Y
SBUF=IRcode;
: N  E% z6 V1 ]* |5 C6 xwhile(!TI); //等待一个字节发送完毕+ v! j3 `: X. p
TI=0;
- U7 C  I. ~" y5 }5 T8 d}
. J- ~! f( n. N; U$ m* R9 o" k8 ?# Q7 g: x( U
Delay();/ ~3 J0 I+ {: |+ h( ^
}    //end else& s2 v6 u. p2 ~4 Z
}   //END for
- V$ R1 D+ X& BEA = 1;
- X+ J% \! ]$ [6 e. P}2 d( U9 Z# B8 \) j# q2 S4 S0 c
5 R4 y4 \  x3 k' |7 Q4 p$ r% z
/***********************串口初始化程序*********************/
. y  ~8 D$ i* [: r& Y! mvoid initUART(void)
, G3 f4 {3 J# L- d{6 E, q& c' ]( [0 ^: O
TMOD |= 0x20; //2 }9 K# Y6 l8 E  z/ Q- s
SCON = 0x50; //% J5 F5 t" K- R1 J" }* I+ V: Q
PCON |= 0x80; //1 ?! X3 c; l+ B2 t  a7 X! p
TH1 = 250; // 9600 bps @ 11.0592MHz5 g& C6 M9 y1 T7 v" ]) N2 A1 R
TL1 = 250;
: l) C: e; V. {# N( JTR1 = 1;% f  I. Z" d; S) |
}" Y/ y7 z" j5 Z

7 a  g8 |: N- g/ N* \' G& [/**************************主程序*************************/0 V" Q8 L# A, N; n2 N; W2 J
void main()# v/ t. I- ^) r/ a
{
7 _6 ~2 ]# |7 r+ W$ z& b( N4 Z//P0=0XFF;
! z% U( U3 v' w7 R! z3 `initUart();
+ d' ]' f  I( H& f# b2 I1 @0 l: @IT0 = 1; //INT0为负边沿触发, (1:负边沿触发,0:低电平触发)
$ q. O* V( h$ E% O; pEX0 = 1; //外部中断INT0开, (1:开, 0:关 )
4 j; z0 n0 ?  JEA = 1; //开所有中断
$ v7 t) _# {2 Y& G* b$ E% K
: q& e- Z- G& QCodeTemp = 0; //初始化红外编码字节缓存变量2 v' D' E  k: a. G5 ^$ q- M% `
Delay();
0 k9 G) p: H6 O4 u! Zwhile(1): R0 f. W% y. p' N, T5 A
{+ B) T: i2 O2 t: f: P  ?& z2 ~

+ P; |; G+ b/ Z}
6 j. V& ^- r1 q& |) H: Y( z}
4 y0 Q' Q8 f& C% T6 q1 E1 m2 A- M1 f, d$ ?9 z. h
+ z. z1 `, ]  ~/ |) f6 @  |9 S

% |& N6 ^% c7 n0 w8 w2 ^
/ Y. w' u- A! `6 y& b* A0 z1 T. @' R1 }6 V& k

' R- D* M( E, W9 n二、红外遥控发射5 _- a" _' F5 \  ~% C
( s1 W* H3 W2 I3 X% C: o: t& a& A) \
网上的程序是http://gudeng614.blog.163.com/blog/static/818017420101545648734/
% c- d; a! s# i8 k$ e7 {" |; U  _' K5 V8 F- R
做发射程序费了很大波折,因为网上的程序不好用。
* L! f9 a$ M3 z2 @+ }
( R" P$ S3 l( N4 ^后来不得不用计算机的并口采集了发射数据,发现数据有异常,终于找到了问题所在。9 U" A' g1 h# K9 o' k2 a

/ q& M5 n0 w2 u/ q原因是count变量是int的,对其赋值或比较时,汇编语句一句完不成,会被中断服务程序中断,造成count变量赋值或比较出现问题。7 }& N$ F8 R' y; c6 ?8 ^& q- V& {
解决方法是必须在操作时屏蔽中断。而flag变量是bit的,一句汇编即可完成赋值,故不会有问题。9 ]" g% p/ U! W3 d* ^0 _

" B3 l5 `: X8 I; G其间还发现别的遥控器会在起始码前加一个前脉冲,以为是这个问题,其实不是。
2 `  Y8 h9 Z; n$ S8 W. l2 M, i; F6 p% W7 G- s* K( T1 K
注意:由于13us会中断一次,这里是采用1T的单片机。如果采用普通的51单片机,由于是12T的,不知道能不能成功。
$ A1 C% P! R7 K* b6 W1 P
$ Y, u0 P. f( M7 x3 c//程序从网上修改而来
: Z/ _' S9 F% S) O- G7 p9 _//由于中断需要13us中断一次,即中断要在几us处理完,因此需要单片机速度比较快,用24MHZ晶振才能保证正常$ ?% A% |- K+ q
//但24MHZ晶振,用串口不方便
4 ~( j  _2 |  N8 g/ p6 u. O//这里采用1T周期的STC12C5A60S2单片机,11.0592MHZ,可以兼顾。
/ q' n( s+ y4 k$ f! ~: B% A4 p//STC12C5A60S2  引脚可灌入20mA电流,直接从正电源→红外LED→串1K电阻→P0.0脚。# x* o) G8 y( C- G5 m1 b9 n
//串口1默认选T1作为波特率发生器
. e4 H  ~8 p4 k: S( A" Y//TO用于中断
+ ?  _5 r* C5 X. C0 P4 Q6 B//发送时,低比特位优先! n4 n: X! N$ C8 [6 Z
, x+ I  \$ k) \# p% ]0 @
#include <STC\STC12C5A60S2.H>/ Q* G; y) @6 ?6 y9 N7 Q
#include <INTRINS.h>
/ u( }5 }5 y$ E$ s
" s. \* s7 [1 B7 Nsbit  P0_0 = P0^0;5 k2 V& _; c4 i9 V7 ~

( g# w" \7 a" p5 y7 X4 J+ Qstatic bit g_OP;            //红外发射管的亮灭
# M' K0 z7 @4 ^6 bstatic unsigned int g_count;       //延时计数器
) z2 e" h0 r$ b( W$ cstatic unsigned int g_endcount;    //终止延时计数
  D( e4 K( z; w! O! Z3 G* G6 d( Ystatic bit g_flag;       //红外发送标志
- J% e" x" i. K0 nunsigned char g_iraddr1;     //十六位地址的第一个字节
3 z" d5 \. T, g0 r: f# S0 d" dunsigned char g_iraddr2;     //十六位地址的第二个字节) f$ Z' k4 U1 F( }9 n
+ x1 M9 z% y6 X5 a7 e
0 Y) K; J0 B9 O) X5 A& o6 E
//定时器0中断处理
  w- x: x4 V' g. {$ ?# B' Xvoid tIMEInt(void) interrupt 1
; |  i4 p9 l- f7 N{- T' m  f/ [1 B6 Z; r- l
  g_count++;
$ d. w2 c- E. P6 f: e3 O7 F  r  if (g_flag)    g_OP=~g_OP;$ T6 q5 }3 R: {$ l8 s5 w# D
  else    g_OP = 1;    //LED不点亮
* U, f; N* Q0 t) _- r: V  P0_0 = g_OP;* m" L2 C( T$ B2 @
}2 n& P+ S  e7 u/ @: @& w3 t

& Q7 K. R5 R% D# e. L2 \0 w5 ]% Q' b9 f4 c. y- q+ t
/////////////////////////////////////////////////////# o5 e% P. c( s  r! ^' C
void SendIrDAta_38KHZ(unsigned int temp1, bit temp2)
) L$ j. r, Q4 ~+ j. M{; ?# n0 t; j6 c; y; ?
  g_endcount=temp1;
% m9 z6 @' D' L7 f  g_flag=temp2;
3 z* j6 h( X. _7 b; g% M  EA=0; g_count=0; EA=1;  //避免中断影响count置数2 i8 Q1 U% I) n
  while(1)
7 B8 p  O  o/ q9 ]$ j1 K% B  {
9 K' G, {3 ^1 D7 n$ ~5 j- w6 V   EA=0;
7 a- c3 r* ]2 w$ N+ q6 T   if( g_count < g_endcount ) EA=1;  //避免中断影响count比较' x9 Y  f- s0 E, l7 e/ E
   else
3 ?8 d9 N( l% `% l( _   {
- u4 T# @% R7 v3 f0 m# u. c   EA=1;
4 s. q6 U# |% m, v" L. J   break;
0 V- c! |1 B) ]* m3 d& _   }  % S0 K2 W+ B: j, N' {9 B0 d+ J: `7 ]
  }  
5 D5 g. x4 T+ N}" _9 z. {4 v9 a
- Z/ p2 ~( y& J4 S& g
/////////////////////////////////////////////////////
6 y1 A8 Z3 B0 R$ W2 d4 Nvoid SendIRdata_BYTE(unsigned char irdata)
" N; y, e" V8 m" H- o6 Y. p+ J6 H, x{& N+ V' @9 `1 i- ]) L
  unsigned char i;
: N7 }8 g; G" @# v  for(i=0;i<8;i++), D( Y9 Q: a9 r; |8 P
  {* e/ k) H# C6 \2 ]
     //先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)
5 m: W& Y2 M6 o0 eSendIRdata_38KHZ(43, 1);   //13.02*43=0.56ms6 C; c% W. _* s2 N3 [0 q  K% ~. l+ Z

: k0 O. N* C9 A' ?" i1 V+ x6 f    //停止发送红外信号(即编码中的低电平)# @. a5 u, ]- Q" D, P" e: N
     if(irdata & 1)  //判断最低位为1还是0。   低位先发送!!
. ^' u' a, m0 K( B& M: ?       SendIRdata_38KHZ(130, 0);         //1为宽电平,13.02*130=1.693ms
% m8 `3 _3 t" e4 S( F4 @    else      SendIRdata_38KHZ(43, 0);   //0为窄电平,13.02*43=0.560ms
5 F/ d4 `8 K3 k$ f. `6 ~5 c: d: @4 E# N
    irdata=irdata>>1;
( F! E1 p  q; U3 o7 F* R  }
  c1 O9 m8 h0 o1 g* q( M}
: _4 ~7 A  e1 G7 j5 }& m
' x9 ^) m! {0 e7 H6 s/////////////////////////////////////////////////////5 T" |5 E8 |5 Q
void SendIRdata(unsigned char p_irdata)
! W1 }9 s. [' D6 L  C- ?{/ k; I* l4 f; q; `
  //有的遥控器会发一个前脉冲,如果不灵,可试试加上前脉冲
* J2 R: Q$ f# P, {7 y9 _& Z  //发送起始码前脉冲,高电平有38KHZ载波
) b# X- q/ D& Q4 h* q  //SendIRdata_38KHZ(18, 1);2 \4 |1 Y; G- d' _4 T) ~6 `& B% {
  //发送起始码前脉冲,低电平无38KHZ载波
7 Y2 ^! j9 s2 `- @( j  //SendIRdata_38KHZ(18, 0);2 W, y" U- I. f, w

+ T1 l0 T  @9 L' b/ Y6 ?; e  //发送9ms的起始码,高电平有38KHZ载波( {/ k5 v- x" }/ K+ @0 V
  SendIRdata_38KHZ(692, 1); //13.02*692=9.010ms8 N+ {' k& P7 g+ `" u9 k( J. g

, Z9 t; N1 ?# |1 E+ I* x# \  //发送4.5ms的结果码,低电平无38KHZ载波0 V  y9 z* O1 M: E6 |4 {
  SendIRdata_38KHZ(346, 0);    //13.02*346=4.505ms" ^- l2 K7 S1 a
0 r+ p- T* }# {/ m
  //发送十六位地址的前八位$ |* y# m) z0 m: O! ~6 L5 T: w
  SendIRdata_BYTE(g_iraddr1);# c* l: c# i7 h
9 x- U' N0 \" v9 O
  //发送十六位地址的后八位
" O/ h/ ^! i, ?4 w4 r' a  SendIRdata_BYTE(g_iraddr2);
2 E* f7 L2 r2 ~6 B. i1 Y8 ~& f* Q) }5 ]" P" x
  //发送八位数据! m/ v# ]" m/ T  q5 n) p& C
  SendIRdata_BYTE(p_irdata);
3 W  ~' ~# v  \1 {" Q6 r
* r) [9 }8 O0 |  //发送八位数据的反码
1 f1 k3 k8 y' i( H  SendIRdata_BYTE(~p_irdata);  ( Y1 t) e" y$ z! B. O6 [4 b* l
3 T8 g: ~  G3 G9 U; W
  //发送总的结束位1bit
/ g) d3 _9 V/ c& x  SendIRdata_38KHZ(43, 1);     //13.02*43=0.56ms
! y& X& s  y. W( K/ b
! R% \7 x; k6 M" W9 Z+ U* M: m9 n3 S; a" y
/*  //后面这些可以不用发
+ M. w$ k7 r" M* N9 @% F: z" r5 s, }  g_endcount=1766;
7 y) W( }/ k3 D1 g7 @. p1 V% j3 t  g_flag=0;
$ y' T6 H! x4 h, p- i/ `  EA=0; g_count=0; EA=1;
0 z2 G6 f! l; ]+ d  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   
; `; c. \- P; E% N0 b  q' i( \) \+ g. z. U3 d5 ?
  //发送9ms的起始码,高电平有38KHZ载波
2 `4 J- J) H- f# j3 P; N: a3 U  g_endcount=692;   //13.02*692=9.010ms; g9 a1 _7 w2 u5 n  K6 D. h9 Z/ N7 y
  g_flag=1;' s4 g/ L  P8 m) z
  EA=0; g_count=0; EA=1;  O9 _$ n1 n5 X7 O2 N! b) Y  {
  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   
/ {8 J. @- H) e5 n7 q; x% W
9 O9 q1 d5 G, \# @+ B  //发送4.5ms的结果码,低电平无38KHZ载波
6 V1 Z7 t% J, z  Q" M5 u; w  g_endcount=346;    //13.02*346=4.505ms
/ E  Q' `8 X+ g8 y4 A) G9 |. n2 l1 K  g_flag=0;
# @& b" p7 F; |# r  EA=0; g_count=0; EA=1;, [1 M( u3 l" |: P  m6 s- a
  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   8 N, ?+ ~! a6 t2 U

9 Z* C: _7 G( [& Q* }6 K//发送总的结束位1bit
1 @6 A! N! h8 |* A( k+ l2 Q2 \  g_endcount=43;    //13.02*43=0.56ms
7 h. c$ t* s  ~  g_flag=1;' v6 `% f4 J) m7 A
  EA=0; g_count=0; EA=1;, W% n, N' P& a3 H0 ^$ Y8 n1 |
  while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; }  }   
- d+ e* a# O7 H1 S2 S* r: i6 [6 G/ U- N6 g8 q
*/0 V7 u% @% @4 g9 e
* `- y' |/ y& T- C
  g_flag=0;. `9 |4 v2 U7 ]# O! s! D

$ r& F5 K1 N) b2 o0 Q6 t; b. w+ L5 ]: R* k8 {6 u
}# |  @2 C  o( U

' Z7 ^+ W0 R0 B8 E2 C# Y
: x! r9 `1 k9 K( X2 M% r8 Y  o
. Y+ u; J* }, l; L, a) ?4 F+ I///////////////////////////////////////////////////////////0 J$ A: }% _) }, f
void main(void)/ |" @5 [0 y3 t1 j7 ~4 F+ [1 W4 s
{
4 T& [+ p+ A2 j2 D$ d! J# B6 n  Runsigned char com_data;    //数据字节
* ]- V% s4 V" ^& Z. |6 k" K2 v& U8 i  x# w1 y
  g_count = 0;* `/ n' J/ P5 c+ Z
  g_flag = 0;
( g, ?" ]* ?; Q5 v6 o; U  g_OP = 1;
7 J9 U0 A5 `$ u* ~( j4 `  P0_0 = g_OP;   //LED接电源正极,不点亮- u& _' G& f) p) y6 S; y9 i6 D  K

( l& T7 w) W7 y3 P) ?: n6 W/ b1 LSCON=0x50;  //串口方式1    01 0 1 0 0 00  模式1,非多机,允许接收,无数据位8,清中断标识TI和RI* d% k" a3 y3 P: y# P, Y

7 b4 d/ v: q! U- [2 ~2 `  TMOD = 0x22; //(定时器0和1:方式2,自动重装,8位)+ q7 u' E. U/ y" Q
TH1=253;  //11.0592MHZ,9600bps。没有设置SMOD,故波特率没有加倍。即:11.0592/12/3/32=9600bps
* U: a" Z" u4 u5 O$ dTL1=253;" U  G: |2 V. X+ I: @9 {9 r% R3 _8 I
TR1=1;    //启动定时器! O1 Q! L' m& [3 |5 w( v# H7 m

$ Q7 f2 o8 |$ f0 `  TH0 = 244;5 A1 l% ~: p) V/ s' K: S" W
  TL0 = 244; //(WXL:即计数12次中断一次,即11.0592MHZ晶振,机器周期是1.085us,12次*1.085=13.02us,这样达38KHZ。  13us一次中断,时间太短了,所以单片机要快)
2 {% N6 E' c  _  b: W  ET0 = 1;   //定时器0中断允许+ \( F+ L3 t; b1 }" i
  EA = 1;    //允许CPU中断* J/ X5 F* c7 q" n; K5 {
  TR0 = 1;   //开始计数
7 o: k/ h8 W* j9 l7 Z* ]$ u* X3 ?: C* X! _1 w% x7 @
  g_iraddr1=0;       //地址码% h% @) w" A9 o5 Y
  g_iraddr2=255;     //地址反码
3 q; U2 f7 Y& ~8 w  o7 {: A+ b, c' X# O- L
RI=0;% ~* N9 ]/ g: d
while(1)
& `: F' T, N; K4 V0 j; H{
' o8 ~6 P* Q2 c8 }if(RI==1)
" B* h1 r: q# u4 U{- D: G; v3 S2 l9 I& l
com_data =SBUF;
, @4 X% G! L3 O9 o& m/ ZRI=0;       //要人工清RI
. @4 |  [6 V$ B" s% s5 g, \7 vSendIRdata(com_data);   //发送红外数据2 V+ D# \0 ~' p
TI=0;' V# s* f) C+ ^5 z& s
SBUF = com_data;   //输出字符
4 A, x. E4 h8 t; qwhile(!TI) ;     //空语句判断字符是否发完,TI=1表示发完$ T" u: K! {$ F; X( l
TI = 0;         //要人工清TI
4 S! V6 z! o, ^- G: G}. m& y' A: i5 Z. p3 T
}
/ ~( ?$ d4 c" n2 u6 U% e; y5 m! C! e7 w5 J
}

该用户从未签到

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

/ f1 }  c: }# h0 H" j谢谢楼主分享,收藏参考学习下,在学习中

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-12 19:27 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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