|
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
} |
|