|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
" y7 ], I( v7 S. V t% V+ } 采用STC的51单片机,STC12C5A60S2,可以直接串口编程,而且是1T的,非常方便。4 B0 s8 d1 q" S/ b" r
0 }" Q% |/ d: ^7 d% T+ V% r
一、红外遥控器读码
1 q. O. Q! C% ?+ K. h读码程序没怎么修改就成功了。5 E$ F& s( k+ y: d% E
注意:这里的延时程序是STC12C5A60S2的,如果用别的单片机,需要修改。# l! v1 _) b$ [5 f
2 w; w5 z# \9 I, T. u0 w" G" Q/ v#include <STC\STC12C5A60S2.H>% X, u9 B/ V9 K
#include <INTRINS.h>
6 @; }! y7 w8 K5 ]3 |2 ]0 O7 l% Q/ ^; P% r4 \- L* z$ K/ M, a
//采用1T周期的STC12C5A60S2单片机,11.0592MHZ
1 S5 ^2 z* z3 B+ d3 `9 D//WXL:一体化接收头默认是输出高电平,有信号时输出低电平;接P3.2脚。( U" ?3 p+ _ ?2 ]8 c5 j
//WXL:这里按“低位在先”
5 u3 u- h$ [% x" W: v0 F' }3 D# u) R7 x( e
/******************************************************************/6 _: t I& B) m. Z! c# u5 X
/* 本程序的蓝本从网上搜集,经修改并注释,万能遥控器解码成功 */5 ]9 l! y* ~+ m# [$ N# b, K% m
/* 晶振:11.0592MHz */1 Y' Q- r' U* a
/* 整理与测试:单片机教程网 胡琴 2012.5.15 */
) p% P2 u. [5 w' B* y# l) T6 [& B6 Y/************************* 说 明 *********************************/+ I7 S0 N9 P' K& o6 m4 r- R: Z
/* 以一个9ms的低电平和4.5ms的高电平为引导码,后跟32位二进制代码 */
/ ?; b4 z: m$ I8 B; c9 L/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码 */
& l% j) T* {- D/ o- n/* 以脉宽为低电平0.565ms、间隔高电平0.56ms、周期为1.125ms的组合表示"0"; */- B3 J! g0 L. ?
/* 以脉宽为低电平0.565ms、间隔高电平1.685ms、周期为2.25ms的组合表示"1"。 */) @! }4 m3 s1 g, n& f0 R
/* 注意:接收码的脉宽与间隔是对发射码取反的,即间隔是0.565ms */
/ j! v- K8 [7 x+ b' U7 P- B/* 解码后共有四个十六进制码,本程序取第三个作为识别码 */. W' g. k5 A& ~$ M
/*******************************************************************/
) S- P G* v) ~1 P. H" w
2 q' u& C* ]; f, V) h' l. ]#define uchar unsigned char& @1 M1 Z* N' b
uchar data IRcode[4]; //定义一个4字节的数组用来存储代码
, c3 F, D, A8 I- `5 G: q) n& x) tuchar CodeTemp; //编码字节缓存变量$ K8 h# B) ?: Y/ ?+ `
uchar i,j,k; //延时用的循环变量
) r$ ^' z9 b2 rsbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)& J/ T! @$ \) c% H( e' K
sbit P0_0=P0^0; //P0连接到 LED 上
+ U5 `7 W7 U/ C3 {; Ksbit P0_1=P0^1;
o) |- l8 I2 J1 \/ a8 Lsbit P0_2=P0^2;9 {: M+ b( z0 n8 c5 ]
7 j% X. f' G1 D6 ^' ~/ V$ {, i
( F; s6 |- U' F2 L8 M4 C3 R4 T0 y: n6 g- v% B( H, D5 [
/**************************延时0.6ms子程序**********************/% ^0 [0 t @# a
void Delay0_6ms(void) //@11.0592MHz
; ?# a1 W0 C# R{3 M$ N# ~6 P$ |. ?
unsigned char i, j;
6 g- E2 U' i2 H; }9 V- p( ?* O H9 O5 {
_nop_();
0 e8 [" _+ v& K/ K/ V3 M_nop_();3 H4 u% M8 ]* X& |. V8 R; b
i = 7;. v: J! I' |- B- z- |' b7 q, Z* p) g& g$ T% ]
j = 112;
( K! c" T# O- v$ l, ~* Fdo0 x, _; a& \& d* g8 H2 W* F
{
* ~( z! H e( ]. R5 m+ W5 bwhile (--j);
1 U" ]/ u, s$ j( b} while (--i);
+ h) U4 F1 F/ @- [+ t) C8 J" v
% y6 \* [% E- O$ R! O; y}2 W" [. j4 {7 z' D9 x7 M
8 Z+ i- \& K3 n+ ]5 M2 E
# p9 i6 J. |' G' M6 N" E8 s
/**************************延时0.9ms子程序**********************/1 }: |1 M" \9 y: a0 U
void Delay0_9ms(void) //@11.0592MHz' U7 h$ v# y+ C; L+ `
{" _- k6 _1 a5 ]' P' M! T2 k8 W
unsigned char i, j;
0 h8 m0 Z' b4 S$ w/ |& p0 B3 ?_nop_();
/ q. _" Y* c" P- o4 z_nop_();
" C+ U* P' H8 __nop_();
) {% J7 }" {2 O, W, di = 10;, e( T6 T9 \6 |. a
j = 170;
' i M' Z* e; u. Q$ e/ V6 Pdo
% w' C; I9 \1 ]5 ]% R{
2 O& Q6 j' s( o m. twhile (--j);' ?7 m& A5 Z, s. p
} while (--i);5 j+ `& U( |! W }6 N/ T/ ^
}7 H! i3 ~3 c h" [8 F+ |0 |5 T
9 v$ ] V" V! _1 ?5 ` a' x7 e
6 d: _" m$ y( R. @( S$ N8 L& O9 E9 w
3 g5 K' m2 P( l* \9 q* {+ b5 X
/***************************延时1ms子程序**********************/8 X" e) s9 s- ?% L
void Delay1ms(void)
* C9 `" S: f3 ^$ y" ^5 c{/ m m5 s. R* P: ^8 a( [
unsigned char i, j;/ s) k$ @* `. |( b/ L! z
2 l5 g! {9 {( H% k; D_nop_();
) f* u9 x# @! t. {3 }i = 11;5 ]' ?) O7 W W+ O
j = 190;; ^$ ^. ~, s' m$ X
do2 v% ?! E. ?3 f5 p3 M4 n" J' E
{
! j3 R# {8 f8 ~while (--j);
' N, I+ F+ \; F" U} while (--i);
& a) Y2 x# F2 B$ x}
+ G' V1 P- Q! [ O* C7 E
7 O" W/ M- Z* N/***************************延时4ms子程序**********************/$ z: `" d7 x' ~9 Y& {
void Delay4ms(void)* Y5 b& @, @8 q8 E
{
- f- _& f* [; n1 kunsigned char i, j;0 O9 B- }( \/ w8 j# o1 T
) s; w+ w& [/ z' R P8 x8 N) Y# Z_nop_();
' E* f, b4 F5 q_nop_();" M; K8 I: J/ v+ B2 y
_nop_();
" {- w- o) M( [* z4 Gi = 44;
9 ]: A2 {% |8 }' _j = 3;
6 i( Q' M9 U) H+ O! K4 V. kdo
1 u; @3 I. u$ g* j( R3 G) ~{
- R2 {! ?) `" Wwhile (--j);
; s' l) _1 v0 L3 T1 }% j} while (--i);
9 k" T; m3 o$ s5 K}6 O3 H5 T. [3 x7 R2 }6 [( u& j
5 S& k$ O* `0 D- b
/**************************** 延时子程序 ************************/
. i* J" `; v% X8 svoid Delay(void)
$ F! G# E4 W. ?" u: y/ d( C, M7 Y9 K) q{ I0 P0 `+ [4 P z) v+ p- J# {2 P
uchar i,j,k;4 d7 \% F! u, z( J
for(i=200;i>0;i--), G4 q5 g* C& H4 }! [- m) o
for(j=200;j>0;j--)9 y+ k) S B7 O5 D
for(k=3;k>0;k--) ;
% R# F0 p# Q( ?' b% G6 B}
+ X8 s9 r5 X# f- t4 x4 U
% Q- u0 {, w2 M. G- \6 z0 Y/******************** 中断0解码服务子程序 ********************/4 Y# y% w# Z! C+ [, M3 T7 y& Y7 ~' j
void int0(void) interrupt 0 using 2
- o) M' J* G- T3 r$ y( I1 h0 p/ J$ D5 s{
0 k% i1 y" B# v# s& N1 t# [8 D8 n/ UEA = 0; //??? 可以这样,跳入中断,但仍可对P3.2(INT0)进行电平变化的读取
9 t6 }5 f, l& x+ T6 bfor(k=0;k<10;k++)
% `" a7 H9 y/ R6 n{
+ |' I: x9 g( r2 n0 }$ E u* JDelay0_9ms();
9 y a* X& h* c3 ~if (IRsignal==1) //如果0.9ms后IRsignal=1,说明不是引导码,退出中断7 a( ^) W; y) t+ v
{+ t, k9 D; F4 Z5 }6 J% X# R
k=10;
, K1 Q. V% f2 i6 ~% u* M- h' y5 D) D1 lbreak;: p2 b7 T& z# s; g
}
8 J6 |4 P1 U p+ a: h# W3 s+ j
) k2 _8 o/ m. g; z h# S9 y$ qelse if(k==9) //如果 持续了10×0.9ms=9ms的低电平,说明是引导码。WXL:一定是从引导码开始; C% E4 j$ h! R4 y q
{# k, w4 n% e: V
while(IRsignal==0); // WXL:因为红外头默认输出是高电平,故用while(IRsignal==0)很安全,而用while(IRsignal==1)则可能会进入死循环0 d) O o) d* f6 A6 f
Delay4ms(); //跳过持续4.5ms的高电平 WXL:要超过4.5ms更好
# v1 \$ G" c) w; }2 F, vDelay0_6ms();1 ~8 G( @) T7 B( `' z
7 \1 P9 v: O( ~" j' r2 M
for(i=0;i<4;i++) //分别读取4个字节
+ K* y' R1 C6 b0 r, Q{! q% V) L( } e5 R! ~: l
for(j=1;j<=8;j++) //每个字节8个bit的判断1 P8 \! N$ H( n
{3 G' M! n+ _. c7 Q
while(IRsignal==0); //等待上升沿,此处用得很好:因为0.56ms的低电平(接收时)是代码0与1的相同部分
3 W4 j+ h, P- y7 cDelay0_9ms(); //从上升沿那一时刻开始延时0.9ms(因为0.9介于0.56(=1.125-0.56)与1.69(=2.25-0.56)之间),再判断IRsignal0 j/ r& O5 m+ d
if(IRsignal==1) // 如果IRsignal是"1",高位置"1",并向右移一位
# p+ k" a' t! h; P$ g{
( K# J5 x3 r. _1 @7 vDelay1ms(); //为什么要延时1ms呢?因为要使IRsignal跳至低电平(即0.56ms的0与1相同部分上)3 g- ~; s* Q3 G5 M, c
CodeTemp=CodeTemp | 0x80; //此处的算法很好4 |* D, x. e3 ^* E P, g
if(j<8) CodeTemp=CodeTemp>>1;
2 b1 h7 ]! g1 l( R" X}
4 _, D' @. @0 V+ _else // 如果IRsignal是"0",高位置"0",并向右移一位
' D1 [) K3 a( P: h! \if(j<8) CodeTemp=CodeTemp>>1; //如果IRsignal是"0",则直接向右移一位,自动补"0"$ ], L- F, `6 J7 W
}/ n- E& d% ]' c! [% E( V
IRcode=CodeTemp;
. D7 V0 b( | KCodeTemp=0;
0 Q- e$ b, ^7 x0 A; l} //end for: I3 S3 E7 L) G- S' k# R+ X& I
0 G3 F2 ]7 ]. G2 ^
for(i=0;i<4;i++) //通过串口将代码发出( `; H9 R/ U: G- l
{
/ b2 O" o. _9 VSBUF=IRcode;
* y# z3 b1 n: q' C1 Ewhile(!TI); //等待一个字节发送完毕
3 r4 m* D" X0 t# A( LTI=0;
+ @9 A6 t v5 @+ a9 j) O9 W}- H8 ~! O; a, I3 f! t! K
3 J5 H7 z: n( j# ?/ wDelay();
5 ?) v/ X, o9 J6 f d} //end else% q1 Q Q% _: w' v- [$ V6 s
} //END for
/ _ |2 @0 {4 ^EA = 1;: m# r# V5 S3 [0 }+ \
}$ R6 R/ }2 A6 y9 b2 o1 A
$ G! R% ~: j3 l/***********************串口初始化程序*********************/
, B# G# t: c) ^void initUART(void)8 [ U( ?* j. q
{
) E% g8 D1 f! o# nTMOD |= 0x20; //8 m9 L- P7 F0 z0 A B
SCON = 0x50; //0 l! C9 t! i p
PCON |= 0x80; //
9 `6 ^% c0 g6 c% zTH1 = 250; // 9600 bps @ 11.0592MHz1 R& x3 @* I1 g! a0 l% _
TL1 = 250;$ o) a# ~. C; l! ?; ^3 w
TR1 = 1;
, e& A9 e% k4 H$ F% S}8 ?& \7 r) z0 V8 |( P/ ^
) f7 m5 ]3 Z: H6 L
/**************************主程序*************************/* }- K. J$ O" h Y" D3 K/ L C, ~
void main() b- P. f" w$ T9 g, X
{
6 S, t3 A" z- r! Z4 [* _//P0=0XFF;
+ S6 Z7 D- Y p* E! p' a( {- ^/ xinitUart();
6 r" ^% L. d5 K+ F5 T/ t4 }: cIT0 = 1; //INT0为负边沿触发, (1:负边沿触发,0:低电平触发)
9 \: ]# @$ J- @6 s2 L- u% C1 PEX0 = 1; //外部中断INT0开, (1:开, 0:关 )+ c; v/ o, r, R5 R
EA = 1; //开所有中断
) |; U$ e$ x4 |( d7 F. C5 s/ m& l$ p6 W: [0 E
CodeTemp = 0; //初始化红外编码字节缓存变量! h1 H- l/ R% H) k3 K
Delay();# L) L& i( b% ?1 i, k
while(1)
5 ]6 x5 w; ]8 h8 D# }3 Z{& c: e$ J, U8 w3 q% J
5 w6 h3 M6 s( d: s7 }}- y' a6 v% x! l( |
}) u5 o; O8 q4 l% v1 R5 x& m6 w
+ U/ b2 f) E8 I7 k. T
3 q! ^9 O1 \/ |6 y' u* p: \
% t8 m6 `6 u3 K* Z) z/ X; h2 H* `+ M' W4 `) u" ^6 d, J7 L1 P
" V! s' v3 B A& x7 x9 Q
# i( }6 q4 P( l二、红外遥控发射, {2 W, w% i! U* I; M8 o: Z0 }
$ T, D/ j* \3 S7 p( m# l* w网上的程序是http://gudeng614.blog.163.com/blog/static/818017420101545648734/
+ |8 G* e! ~; J
0 }( h5 l" c1 F. _: M+ c做发射程序费了很大波折,因为网上的程序不好用。
1 g9 t4 ], ]0 M) ~5 U( O# o" `
- R; @; Q7 Y+ G! X后来不得不用计算机的并口采集了发射数据,发现数据有异常,终于找到了问题所在。) Q- g8 S0 k; M4 ?' K$ P
! V' ~+ S2 E. m3 C; I5 R原因是count变量是int的,对其赋值或比较时,汇编语句一句完不成,会被中断服务程序中断,造成count变量赋值或比较出现问题。# |+ @% M) r, c
解决方法是必须在操作时屏蔽中断。而flag变量是bit的,一句汇编即可完成赋值,故不会有问题。
6 M a$ `7 u3 m' s0 W3 t
0 q: x; x; c) d; e' I其间还发现别的遥控器会在起始码前加一个前脉冲,以为是这个问题,其实不是。7 v C3 m+ e# @2 O& @
2 L( R3 k i$ T; X
注意:由于13us会中断一次,这里是采用1T的单片机。如果采用普通的51单片机,由于是12T的,不知道能不能成功。
4 Y/ I# t0 c; j& Z) b: q" p* Y: }% z1 p! }6 A4 k1 G" i' U
//程序从网上修改而来9 Q0 X$ J; h% V+ J& b
//由于中断需要13us中断一次,即中断要在几us处理完,因此需要单片机速度比较快,用24MHZ晶振才能保证正常
$ ?. H+ ]( t/ A9 h) K( p c k6 M$ \//但24MHZ晶振,用串口不方便
6 n, v) H% i3 Q; A+ f' Z" S" Y//这里采用1T周期的STC12C5A60S2单片机,11.0592MHZ,可以兼顾。4 Y( C; j' I7 d: D$ h; V4 Y# @
//STC12C5A60S2 引脚可灌入20mA电流,直接从正电源→红外LED→串1K电阻→P0.0脚。
/ E: p8 f5 W3 o1 m//串口1默认选T1作为波特率发生器9 k0 e7 ~2 Z+ D
//TO用于中断
C0 s/ q4 W9 v: W4 x, b//发送时,低比特位优先
3 y6 l0 M8 N% S1 ~
" D) J% O: @6 {#include <STC\STC12C5A60S2.H>9 v$ R/ g# J! }3 X& o
#include <INTRINS.h>0 v" c! u1 Q/ }2 u3 W1 ?4 Q
4 H( M* h6 |& ?% X/ {8 r1 b* y9 N4 R
sbit P0_0 = P0^0;
) a) Y6 C% P& y3 O: R" p, ^) F
) K0 t2 H" `# D$ u" d( W, J: B& sstatic bit g_OP; //红外发射管的亮灭6 p0 ^. @# J: A4 J/ x" Z# b3 m$ U
static unsigned int g_count; //延时计数器
) y0 `( ]4 f' N- x- W1 P: Istatic unsigned int g_endcount; //终止延时计数
4 W; T- ~& ]. g9 _: [4 Ystatic bit g_flag; //红外发送标志
3 v7 j) b3 |: u$ `unsigned char g_iraddr1; //十六位地址的第一个字节4 B/ w& d( m$ T0 Q
unsigned char g_iraddr2; //十六位地址的第二个字节5 q4 ]7 h: O" V4 R, n* |8 Q
' H9 Z; \% K7 ]- O) j
2 ~4 s: j" w7 f& r0 z3 |" p//定时器0中断处理
% h2 M2 n7 q9 N% w* N9 O/ rvoid tIMEInt(void) interrupt 1% s( c" I7 H8 |7 w
{* p" H% U4 j9 r2 ^6 ]+ o5 t
g_count++;! m& x) U) y4 q, t
if (g_flag) g_OP=~g_OP;
7 i$ y) C; D2 S% a else g_OP = 1; //LED不点亮
( D$ m$ b( L. R5 N# z7 M v P0_0 = g_OP;( ?# o8 M; m7 ^$ h" u
}
% C% x3 m! X* Q. p' Z) ?
) H" Y4 L v. b+ F: v2 C' d6 ^
/////////////////////////////////////////////////////8 X( z3 a; ?2 `- Z9 e
void SendIrDAta_38KHZ(unsigned int temp1, bit temp2)
" l; R2 i$ H# T2 Y4 `4 a{3 l; b" ^ V. ^7 a0 `# X! s
g_endcount=temp1;1 d: ^! u7 Z) r' w
g_flag=temp2;
% ^/ f3 k: d6 {0 U4 M9 j EA=0; g_count=0; EA=1; //避免中断影响count置数: c4 M. q$ N: U# f& ?+ X6 U b! M' Y
while(1)6 `) G) P7 v2 O5 I
{
9 i+ B+ d& v; m* X( p1 C EA=0;
3 u) s4 o7 m8 Y+ l if( g_count < g_endcount ) EA=1; //避免中断影响count比较
7 L: R: q' R+ T. H+ X else
q( }% Q0 }. x) ]; M- f1 u {
- _, _7 r3 v; I( y P& L EA=1;
% G) r% M3 @2 p# }7 ?% x: } break;- {6 e7 b8 i- J. j
}
/ K/ z6 q: d/ R: Q, X2 W } $ e/ _" d/ c# A2 Q6 h8 B; G
}
2 }+ c3 I D5 f: H/ [; O8 a9 a/ p Z
8 L# a* J; Z8 [7 O/////////////////////////////////////////////////////& b! l, G. B; p& D9 b& @% n
void SendIRdata_BYTE(unsigned char irdata)9 ^7 G" G( |! u8 Q Q/ m2 P
{
/ }7 p: d( o/ G5 ` unsigned char i;" y) c# x1 w8 k" B( z) R' u8 W
for(i=0;i<8;i++)
5 I4 T6 Z; N( o {
* y9 l; m5 [3 j0 e3 S- v //先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)
( x9 \( u0 A* J S; |+ TSendIRdata_38KHZ(43, 1); //13.02*43=0.56ms
# F& ~9 m; s+ Y8 }' ^
1 {1 s8 r+ x+ O2 t //停止发送红外信号(即编码中的低电平)
# [, T$ k+ `, Q7 u$ H4 D5 d if(irdata & 1) //判断最低位为1还是0。 低位先发送!!1 D4 ?9 m- T+ \, H+ J/ L" k
SendIRdata_38KHZ(130, 0); //1为宽电平,13.02*130=1.693ms
1 j- F- R) _% D2 Y& A9 R else SendIRdata_38KHZ(43, 0); //0为窄电平,13.02*43=0.560ms
! O. R) I7 X' I
, _+ B8 J2 N L% p1 M irdata=irdata>>1;
- @, @7 W) G: h: }1 ?0 P }
9 f, v* d, c/ j2 J}
9 [2 h7 q3 @' b. Y8 k" z4 h- Y
6 |! a* K/ X; b1 I6 }8 @/////////////////////////////////////////////////////
- r3 }, I& E$ l5 g0 ^' k; Vvoid SendIRdata(unsigned char p_irdata)% R4 C4 c: R+ w3 p
{$ R, v5 Y: ~' s8 e
//有的遥控器会发一个前脉冲,如果不灵,可试试加上前脉冲
% j8 b6 D* n2 A5 ?5 }; e0 P* Q //发送起始码前脉冲,高电平有38KHZ载波
' @# J9 N2 c' t //SendIRdata_38KHZ(18, 1);
/ s! f5 Q, v) D+ I! y' {4 q5 t //发送起始码前脉冲,低电平无38KHZ载波3 U/ Q4 S1 k% b/ l& T% R9 G
//SendIRdata_38KHZ(18, 0);5 I" S9 P% j& i
/ {- ~ H% ~& K/ N+ J //发送9ms的起始码,高电平有38KHZ载波
# `% l. f" U4 R" } SendIRdata_38KHZ(692, 1); //13.02*692=9.010ms
0 z! B" m/ Y& F. S3 A% k% m; Y' J/ S6 B$ c$ k7 U D) r
//发送4.5ms的结果码,低电平无38KHZ载波
- [7 C/ v9 W- o' g& A7 T; t SendIRdata_38KHZ(346, 0); //13.02*346=4.505ms
, M3 j; |7 T$ L1 @9 P& \- O; _) x5 o1 [& D( v
//发送十六位地址的前八位( b7 H1 j/ [8 A5 {" l- y, \* Z
SendIRdata_BYTE(g_iraddr1);
: [& O8 G, T1 V6 A$ Q4 s( m7 @2 s' m
//发送十六位地址的后八位5 w0 y/ |3 j9 S) `
SendIRdata_BYTE(g_iraddr2);
9 O( A7 v# @% k2 [* g4 V$ K: {3 G7 H% Q3 j/ K/ ?
//发送八位数据0 L7 K3 L4 {; C% `1 B7 p! H7 m: C
SendIRdata_BYTE(p_irdata);1 p; p& x( W( a5 W. k- N
2 I J$ k' u3 o2 o1 U2 `
//发送八位数据的反码
7 [+ m' c$ f9 O: p3 M1 N4 h SendIRdata_BYTE(~p_irdata);
' b1 [! e( f( G; G+ b6 p! M3 p- g7 p* V$ @- a7 p
//发送总的结束位1bit/ J+ ?1 n" L3 g0 F* K% w8 h8 @1 D; d
SendIRdata_38KHZ(43, 1); //13.02*43=0.56ms3 ^$ ^" z# Z% v @8 s
+ R8 k" M8 e$ a/ H3 D5 ]( U
7 s* C7 ~5 ?# G1 X
/* //后面这些可以不用发. C4 m9 t7 a+ {# a# e; S
g_endcount=1766;
+ E0 w8 v3 c7 f: g' m3 P g_flag=0;
8 [5 K h6 q" L; _# Q& O EA=0; g_count=0; EA=1;
# z m5 n; {+ @ while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } } % c6 ~& \: Y' P/ h
. Y$ l1 N4 Z* a. v P, A8 J! }0 ^# {: z4 b
//发送9ms的起始码,高电平有38KHZ载波
& G/ G) ~" }: d9 _# b. w, k g_endcount=692; //13.02*692=9.010ms
/ _+ c- `& F+ j9 s g_flag=1;
# N" Q7 t2 j/ |$ ]+ O8 b EA=0; g_count=0; EA=1;4 v6 \0 c, O" ]' ?7 r/ j
while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } }
, S# L7 n5 \9 |+ G+ \. x, r7 k3 ~: h ]* h3 _" }1 ^: W
//发送4.5ms的结果码,低电平无38KHZ载波
% ]9 @* {4 k& G# h Y5 c g_endcount=346; //13.02*346=4.505ms
% P }! U2 h( M6 N3 l2 j: n8 j9 U g_flag=0;
! a% y0 C9 Q/ g% p* K' H EA=0; g_count=0; EA=1;
8 u/ N% U9 ]3 M while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } } ; E) U: A5 N. D1 X' v! Q, T! f
/ Y( i2 I. e# L2 [/ q//发送总的结束位1bit: z. n9 A9 m! H2 }2 K
g_endcount=43; //13.02*43=0.56ms
, F( h" \) P3 _ C2 A g_flag=1;9 y' b. g7 w+ t. t0 j' c- g6 Q: B/ [
EA=0; g_count=0; EA=1;8 o) x/ B1 P8 s* C6 [
while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } } 1 W( [. P$ ~7 `+ w
0 \. }8 d, w0 u! U*/& Y# ?" W" C4 @- w/ V6 ^3 D( |; B
: F, L, s8 Q7 t/ B
g_flag=0;% d. t: B p' U& e; V6 t
$ ^8 q" p- |. c! W! c
, `8 ]+ ?' k, H& ~) z) L
}# x9 g6 p1 j6 [
- g g- ^; f% I1 a. E! @/ A2 I0 U3 o$ t1 d
, u, Z0 n3 `% ` b
///////////////////////////////////////////////////////////4 L, H! h5 @ f' L$ o( v* u/ d% M
void main(void)
# y* [4 | i9 R/ }2 g* Z0 H9 B{8 d- d) e$ i6 X+ F+ W3 o2 u
unsigned char com_data; //数据字节- b2 A6 x$ _' ?; I4 _
) l! D/ z# S; ?% f( R1 _4 ~& ^ B
g_count = 0;( B5 T& U) J5 S+ ^. S: W0 H! T
g_flag = 0;
3 V7 ]6 e9 i4 }# S( p( e8 w h g_OP = 1;
1 K# D, K* I# E: S P0_0 = g_OP; //LED接电源正极,不点亮
" v0 T/ q2 f2 ?" m8 c
# y: R+ J1 l: M$ g6 ^SCON=0x50; //串口方式1 01 0 1 0 0 00 模式1,非多机,允许接收,无数据位8,清中断标识TI和RI/ N+ ^7 ^: D S7 ~3 R. @0 l
4 ^* u1 u/ C$ t x
TMOD = 0x22; //(定时器0和1:方式2,自动重装,8位)
3 X& ^3 y: n) G$ PTH1=253; //11.0592MHZ,9600bps。没有设置SMOD,故波特率没有加倍。即:11.0592/12/3/32=9600bps# s: t; S7 }+ m. B, S
TL1=253;0 x$ Z2 e d$ L* ^
TR1=1; //启动定时器$ K; m, U6 M8 f
. ^0 H6 n( A( l& p# p
TH0 = 244;
' f* _& A& w, q7 R4 h" v TL0 = 244; //(WXL:即计数12次中断一次,即11.0592MHZ晶振,机器周期是1.085us,12次*1.085=13.02us,这样达38KHZ。 13us一次中断,时间太短了,所以单片机要快)/ f; t2 u+ _* _3 P
ET0 = 1; //定时器0中断允许0 ]- n B0 D# |9 N$ @: M! x) P
EA = 1; //允许CPU中断
1 w6 p# J* [( d, U5 `1 i" B4 L TR0 = 1; //开始计数
, O+ N! s8 \: s- e$ t
: C: \* `, i( j% i* I g_iraddr1=0; //地址码 L1 }9 j( d$ c1 d4 K* [
g_iraddr2=255; //地址反码$ b% J( K' V! u! \
& u. y( X( t8 W8 l8 wRI=0;
& N+ T; p& a- h: P$ j# hwhile(1)0 l/ S. e( p$ g5 J" h
{! t9 D% D/ |& y' R; i4 c0 l% w
if(RI==1)' ?4 l& q. {& t) T& o
{
# z0 l* ~+ Z1 ^com_data =SBUF;
; N% p$ a* g w) ~0 J0 ~RI=0; //要人工清RI4 I- ?% E$ X! }$ _6 `
SendIRdata(com_data); //发送红外数据& w) h4 j. Y4 m. A
TI=0;
, h9 n- V. A) z% o- hSBUF = com_data; //输出字符8 J- S4 ?; r" ]; y$ x9 s3 c
while(!TI) ; //空语句判断字符是否发完,TI=1表示发完
0 ]+ `4 U. G7 H( ]- f* y: R" GTI = 0; //要人工清TI2 k! P0 N/ z: V, U! V5 r5 o+ p
}) b, _% ?( L1 }! F
}, S! T/ |$ }# `
: D' b @- k& d} |
|