|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
4 j& E# }9 f# _( L9 @) z
采用STC的51单片机,STC12C5A60S2,可以直接串口编程,而且是1T的,非常方便。4 b( E9 A k. L1 i/ n' g! m
4 n f4 A) @' n; ~% f* G% U一、红外遥控器读码) k8 d% Z6 e) g* P
读码程序没怎么修改就成功了。
" t% F$ y) G" X$ u5 W# D注意:这里的延时程序是STC12C5A60S2的,如果用别的单片机,需要修改。
# q- p# f; s, b" B" u1 h3 x4 r/ S, K6 y9 ?4 m1 q1 T
#include <STC\STC12C5A60S2.H>* f m5 p D+ B. T
#include <INTRINS.h>; d/ L: y: G1 N& L/ K0 C1 F4 T: V
8 g V4 a) X5 U/ A8 X//采用1T周期的STC12C5A60S2单片机,11.0592MHZ+ |2 i+ M( ]2 t% A. S% q1 R5 L
//WXL:一体化接收头默认是输出高电平,有信号时输出低电平;接P3.2脚。 @% e# P* z) o3 Y- h% f
//WXL:这里按“低位在先”
# U: r5 d5 l# S$ k
+ @9 c3 d L& t6 p$ W' o; \/******************************************************************/9 P4 L0 Q% O/ }3 k3 B
/* 本程序的蓝本从网上搜集,经修改并注释,万能遥控器解码成功 */
9 W2 p& u. s/ a! D/* 晶振:11.0592MHz */
& B3 @5 _& e. G8 ]: J! F1 e5 O9 T0 h/* 整理与测试:单片机教程网 胡琴 2012.5.15 */
' f* h: c5 g' n Y% r/************************* 说 明 *********************************/: T) q/ V/ I0 ?- |- J
/* 以一个9ms的低电平和4.5ms的高电平为引导码,后跟32位二进制代码 */: g: `. R9 U7 d+ V2 H
/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码 */! q8 Y% x. A1 C
/* 以脉宽为低电平0.565ms、间隔高电平0.56ms、周期为1.125ms的组合表示"0"; *// }" I6 H" ~" u
/* 以脉宽为低电平0.565ms、间隔高电平1.685ms、周期为2.25ms的组合表示"1"。 */
5 j$ E" k6 E5 N- G2 U* t/* 注意:接收码的脉宽与间隔是对发射码取反的,即间隔是0.565ms */
; _+ k" F4 I2 p' L# c/* 解码后共有四个十六进制码,本程序取第三个作为识别码 */ V5 u! S, k3 V
/*******************************************************************/! l4 K$ x/ @! D& k
& N8 z- D5 C' ^' N J1 T8 B6 @#define uchar unsigned char
& y4 q* |: M9 ?2 L+ [5 T5 ^uchar data IRcode[4]; //定义一个4字节的数组用来存储代码2 ^) `4 J; W( z9 _
uchar CodeTemp; //编码字节缓存变量
6 |' `9 e$ j; M: X9 @uchar i,j,k; //延时用的循环变量
0 R/ N! e! l, F+ isbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)
; _, ]8 H4 G( {, r9 K8 xsbit P0_0=P0^0; //P0连接到 LED 上
I) q2 ]" D3 [6 ysbit P0_1=P0^1;7 _7 ]! i% n4 R5 D, b0 a1 B
sbit P0_2=P0^2;
8 v b) L! h8 c4 V* Q# m ]: M- Q, o3 ?; s' l
- K! b6 l) e+ |$ ~9 w: q
5 H( I! ` n* R( e6 G& z; S/**************************延时0.6ms子程序**********************/
9 {: l! l1 T, ^' t, Xvoid Delay0_6ms(void) //@11.0592MHz9 s) q/ J! C1 {$ O' Z
{8 @1 z: g7 D; ^! p: p; B2 E0 b
unsigned char i, j;
- ~9 J0 v7 h8 E k4 E4 `
. |" M9 U6 ~3 K. n1 ]+ K_nop_();
6 h' q r& H- V$ T* __nop_();! s* V( {3 m9 V2 I
i = 7;
( K f, g" A! F9 h9 b c2 Nj = 112;, F: h( n6 v7 Q& K+ {
do
/ B) U M) ?& p9 A% X! p1 M3 H4 [! z{
+ w* K) c0 J, [7 Gwhile (--j);# h: K# ]5 N3 v2 @" f% m1 [
} while (--i);1 x" e. ?9 G6 W
. x8 S2 M) @3 J0 f6 Y}
& T8 Y! k0 @' Q+ n; V: |- I* V8 D; N$ z1 x# D, v6 A E) b
; H! l+ d8 q9 Q3 G) |) {. R& ?; r/**************************延时0.9ms子程序**********************/& d( e1 l6 m; g7 ?' t
void Delay0_9ms(void) //@11.0592MHz
* F) V8 q& g1 z{
$ z X- J: t# x) {unsigned char i, j;9 ~0 }- u7 S- J7 V6 j9 ?, f
_nop_();
: x$ T9 V) l0 v$ L# E_nop_();4 k! y6 ^0 G& S" U+ S: o8 m: X
_nop_();
; X0 E% d3 d- a h3 p9 qi = 10;
- ?1 a! b, v" z5 Z$ d: Q$ \j = 170;
! y' l! ]6 F5 i: vdo# B) C/ T0 u8 N8 }( d
{% m% R0 |6 p8 Z3 T: G
while (--j);
6 A9 x7 M! u3 m& I+ s$ ?- s+ k} while (--i);5 f9 Q( n k) |6 b3 p% H7 ?
}: a& A- j) u+ Q& k7 w, a
, n5 l$ d3 w1 D# g- A7 W
7 [$ [3 B" h' g/ e
, i9 q9 Z1 n- M1 b7 _
& e2 p4 y& H6 @) G& K/***************************延时1ms子程序**********************/; a# Q( v: ~/ S7 L# @# ^) ]4 e
void Delay1ms(void)
3 u& Q! b" |$ O l; t- r3 y. a% @{
; p& ^; p+ x8 w3 @& Yunsigned char i, j;# ` [; F/ `4 o. E0 M- w
: Y& L0 v8 r) m% y, S
_nop_();
) A& v/ g6 ~2 di = 11;
- F+ o: c' V) N, ?! k+ b/ zj = 190;
! J9 L! x5 `( ?7 Z/ Pdo, k4 j- r: F* P8 N: }+ H8 O
{8 o2 @" g) m: [- R$ e
while (--j);
8 e$ v/ B4 I3 Y/ _* H} while (--i);& v% F$ p' d9 O/ X! _
}
0 @# f, B! ]6 I% ]0 K2 L5 m' R( w* u* u3 V- [0 |3 Y) n) Q+ h4 N; Z
/***************************延时4ms子程序**********************/
' `1 c+ B1 q( G" t# zvoid Delay4ms(void)5 H- D" O5 j3 X
{
- o: i1 F [) v( Kunsigned char i, j;) p0 N) s& v5 L9 u" q
4 \. Y M' v% T' u_nop_();! i( s% ?- L S* X0 P$ W; ]. u' l
_nop_();
5 \% V' c3 d" z9 d) L* n2 o/ o) O_nop_();3 ^" k/ T4 O3 J, F0 g
i = 44;' S/ Y7 R( H# ~' g
j = 3;6 e x1 c, P" z, t+ K, j
do
* H, l! p) f8 h# q9 H{( W, _9 L# ^7 U- \' e2 Q4 P; G
while (--j);' {- ^% J: R9 v) L: o3 r) K
} while (--i);
^6 X$ Y* S1 P/ n* I/ \}/ I8 j4 l6 I3 k: W
& |* t( l7 o. w1 Q- x/**************************** 延时子程序 ************************/' m" H, }; c1 L5 Q, S0 S1 N
void Delay(void)& D7 |3 m7 C; q
{
/ k7 f* g/ x$ @( Auchar i,j,k;
: |1 o( ~4 s# L8 C3 p. `for(i=200;i>0;i--)
5 B1 X) V7 k' j& Y3 Ffor(j=200;j>0;j--)8 O: s; h3 V7 r2 Y3 A$ {
for(k=3;k>0;k--) ;
; D, u6 {0 `; N \ V}+ m8 L: M* _* P' V
8 l+ R) ?1 x; |* m9 Z+ S- o5 C' E
/******************** 中断0解码服务子程序 ********************/
& U8 ?: W0 X/ S6 T8 nvoid int0(void) interrupt 0 using 2
4 R: T! |- s9 H3 j{9 F- t5 h4 q) b9 [ c
EA = 0; //??? 可以这样,跳入中断,但仍可对P3.2(INT0)进行电平变化的读取
N5 ^1 c8 h1 w+ u$ M( ~for(k=0;k<10;k++)
9 q1 p" {3 n$ C{, A# O. q4 O& P" ^) V! W1 V
Delay0_9ms();4 k k* }5 c1 I' a) y6 F7 Z
if (IRsignal==1) //如果0.9ms后IRsignal=1,说明不是引导码,退出中断
+ _( ^0 [* I7 D$ B( I{( H' n( h4 y/ C( _
k=10;
n$ _% ]2 ~8 ~; e$ C2 E# cbreak;. g. @( B* n3 p4 V
}+ E: J( l7 O: @7 L A
; B7 g1 `. Y i" T5 d I: ?0 _ j' \else if(k==9) //如果 持续了10×0.9ms=9ms的低电平,说明是引导码。WXL:一定是从引导码开始
6 a3 S y/ Y6 n! n{
* Q. j" g% e1 x+ v. L" Uwhile(IRsignal==0); // WXL:因为红外头默认输出是高电平,故用while(IRsignal==0)很安全,而用while(IRsignal==1)则可能会进入死循环; R' Y- ?6 Y$ t* s0 F
Delay4ms(); //跳过持续4.5ms的高电平 WXL:要超过4.5ms更好
: i4 U: \8 u0 E8 YDelay0_6ms();8 ?$ J& }" G# B! @. F+ D
! z7 Z8 k$ M& @. U
for(i=0;i<4;i++) //分别读取4个字节
3 ~$ p+ _; J+ x% c4 ^( ]* n$ P{9 R$ y v" E4 k, V
for(j=1;j<=8;j++) //每个字节8个bit的判断1 q6 v1 x' N& |1 ~: R
{; y4 F/ a5 y" Q5 z4 [
while(IRsignal==0); //等待上升沿,此处用得很好:因为0.56ms的低电平(接收时)是代码0与1的相同部分
0 i0 A" J8 `! H: {4 KDelay0_9ms(); //从上升沿那一时刻开始延时0.9ms(因为0.9介于0.56(=1.125-0.56)与1.69(=2.25-0.56)之间),再判断IRsignal
6 Y2 {4 s2 J2 P* o" w0 uif(IRsignal==1) // 如果IRsignal是"1",高位置"1",并向右移一位 C5 H: N- F1 E! D w# f4 a- ^: ?
{* P0 y3 l( |4 r" w8 u
Delay1ms(); //为什么要延时1ms呢?因为要使IRsignal跳至低电平(即0.56ms的0与1相同部分上)
- ]/ j3 O; d" y0 LCodeTemp=CodeTemp | 0x80; //此处的算法很好
* o @ A6 ]5 r& V6 M' l! aif(j<8) CodeTemp=CodeTemp>>1;
[; T) j- {' C/ F: U; @}
1 k& V# l1 p2 D; y, gelse // 如果IRsignal是"0",高位置"0",并向右移一位
" W# [. K$ Y3 D8 |1 }if(j<8) CodeTemp=CodeTemp>>1; //如果IRsignal是"0",则直接向右移一位,自动补"0"
+ J- }! N/ ^" u7 _ \}
# t6 L% D0 ^, x% N1 m. N, fIRcode=CodeTemp;
# U' I/ Z- W8 gCodeTemp=0;
* O3 F7 S; o+ |' s7 r1 ^' \' Z$ U} //end for) ]; {1 x4 l( w4 J) n# P% v
: V- ? f: @1 a% u) T/ y
for(i=0;i<4;i++) //通过串口将代码发出
+ U9 w6 p# f, G+ [$ ^5 s{
7 l# B- h1 N5 j5 C. C" A* vSBUF=IRcode; j4 Z; o+ J) b, V) T' k! @' b4 ^
while(!TI); //等待一个字节发送完毕" P! _5 V0 v5 a! ~1 z! O
TI=0;
- U6 |' l) S( i8 o4 {% w9 y}: f- l: c# d5 _
/ r) F, [+ ?! ]- eDelay();
: h, H: ]7 H0 D! J" ~' h} //end else
! ?& Y* c' S1 q+ }3 |5 L; \- O} //END for
! f! R$ \5 }- c0 k; O$ Y4 xEA = 1;- l+ m- r6 J& u9 l8 J8 i7 X
}0 X6 u4 o$ O5 k! s, a8 i( r7 c
. q1 q9 L7 c" q0 o( z8 A- R
/***********************串口初始化程序*********************/
% P: Z( _6 Q3 a3 s/ B% \void initUART(void)
/ @7 o6 Q+ R1 h! [{
8 J! |( l" F' t" W" x& |TMOD |= 0x20; //
# Y9 q# N4 w1 M& w) s0 lSCON = 0x50; //
F* D) r' N; [, XPCON |= 0x80; //
+ _: ~# Y( R3 l# y) _TH1 = 250; // 9600 bps @ 11.0592MHz. A6 [5 E# E, I& u6 {+ d
TL1 = 250;
& f% J( T: o% V D6 }TR1 = 1;
+ `0 G" C5 a6 e}
" n) N2 A0 H( k5 p
9 m6 n& e9 L/ V/**************************主程序*************************// a- ]7 @# f F
void main()* Z' C/ w# o( V3 q' I( j
{
! x4 b. M1 D- Y: m6 m% D6 \1 o//P0=0XFF;
* j+ F" _) G* `$ O3 `% QinitUart();
$ t+ ^! A" k5 J. n j1 {8 Y* z( J5 IIT0 = 1; //INT0为负边沿触发, (1:负边沿触发,0:低电平触发)" v1 e% v" L* g- w
EX0 = 1; //外部中断INT0开, (1:开, 0:关 )
" T, O3 G* v3 R" I9 KEA = 1; //开所有中断
8 w7 S" K1 x5 b; n% ^+ D) M8 X" `3 E& {* i
CodeTemp = 0; //初始化红外编码字节缓存变量
' D& s7 B$ O% P$ L3 F) yDelay();5 ^& `5 _- ?+ `! o
while(1)
: V5 \, L. V7 W4 n( B! E{) g" M* _5 ~* I
) x7 }8 ?4 d/ M% A- L9 c7 ^ x1 }}
9 I6 B: X4 a" L3 S5 U- Q}- }6 `2 E R3 r( ?7 R+ C
( R, L7 k/ j& q' ?7 Y" V0 S1 S# z/ j g: `, n
$ b4 }( a$ K# ^+ C% t% |- R) F$ q0 P3 e7 ?5 m! ?
. d/ V7 h3 Y7 ^* X5 Q5 J8 n" E$ }! m* P8 _; S. ?
二、红外遥控发射
# C( H3 W- o! h- F* f4 G6 Q/ ]
h9 M$ I4 s5 q& z9 L& H7 o( _+ [网上的程序是http://gudeng614.blog.163.com/blog/static/818017420101545648734/; y u5 Q" l( f, `( C
) ]8 w) Z2 P9 G9 U( t3 z
做发射程序费了很大波折,因为网上的程序不好用。
& a/ H: n2 {, [" b% R' J" c( v$ H* I8 u/ O' L' J8 I* E. E
后来不得不用计算机的并口采集了发射数据,发现数据有异常,终于找到了问题所在。
" V1 F% X" [( o9 J+ R7 a1 b. l, ~- k. E6 C( F# m I1 k8 |
原因是count变量是int的,对其赋值或比较时,汇编语句一句完不成,会被中断服务程序中断,造成count变量赋值或比较出现问题。, m/ P; D1 N) ^( l6 u9 Z* \
解决方法是必须在操作时屏蔽中断。而flag变量是bit的,一句汇编即可完成赋值,故不会有问题。
/ q5 @- `- Y$ ^1 ^
' h' \) k! |% F3 C! [( ]其间还发现别的遥控器会在起始码前加一个前脉冲,以为是这个问题,其实不是。
+ I' I) ]2 f3 w; o& p* D% S! e0 i5 ?! ~- R3 z/ _6 L
注意:由于13us会中断一次,这里是采用1T的单片机。如果采用普通的51单片机,由于是12T的,不知道能不能成功。
9 S+ u+ Q0 r5 H6 ?3 e; D9 u! m. S( A# `9 j! x% B
//程序从网上修改而来# L) m$ Z7 I! N. m0 O5 T
//由于中断需要13us中断一次,即中断要在几us处理完,因此需要单片机速度比较快,用24MHZ晶振才能保证正常
: |/ ]- I0 H" Y; F7 O8 y//但24MHZ晶振,用串口不方便9 b% p$ p' s4 L+ f0 b% f
//这里采用1T周期的STC12C5A60S2单片机,11.0592MHZ,可以兼顾。0 y$ g, Q% _& |! u' I# g
//STC12C5A60S2 引脚可灌入20mA电流,直接从正电源→红外LED→串1K电阻→P0.0脚。: l# s4 D; O, V2 n7 C V
//串口1默认选T1作为波特率发生器6 x8 v6 [* k- }' U' M
//TO用于中断9 ]7 }* o/ d+ S& v1 p# J. b1 u
//发送时,低比特位优先. q% N" }. ]& t, N* M
# Z% Z( s7 X4 t) P
#include <STC\STC12C5A60S2.H>+ n+ }# ^5 ^- i# {
#include <INTRINS.h>
. K3 j1 x1 S, J9 J1 z+ ~7 k& A; H" K( p, @% s9 G4 \' B @
sbit P0_0 = P0^0;
5 W* y& U8 D/ i7 q! p8 \/ W, O4 m- |( l2 ]0 @
static bit g_OP; //红外发射管的亮灭' |% a9 \: ^9 x
static unsigned int g_count; //延时计数器1 D3 I2 R; j. J7 h
static unsigned int g_endcount; //终止延时计数, D+ ?5 a6 `1 u# x( V, X6 X
static bit g_flag; //红外发送标志
9 J; N. B* h% i: `6 t" }! I8 ?unsigned char g_iraddr1; //十六位地址的第一个字节, Y" w6 ]6 _/ N& v9 }, Z3 k0 e
unsigned char g_iraddr2; //十六位地址的第二个字节
. R9 w0 l- f. ~. t7 \6 p/ ^) s2 ~( j
& K* H/ i- |3 j7 Z
//定时器0中断处理/ F/ ?5 v$ J2 t. _9 v/ S; ^
void tIMEInt(void) interrupt 1
0 o, R w; Y- d3 s{
' b- d; W: V" H' k9 Z8 r: t% i& N g_count++;6 [3 O/ o, `, S9 y4 f, A
if (g_flag) g_OP=~g_OP;
0 M+ Z# C# Z" F" Q else g_OP = 1; //LED不点亮
9 m0 }8 H' l, Z2 K: N6 { P0_0 = g_OP;
" S& g! s3 O: r/ ~. O6 o% W} N1 ~3 \* R2 F
* D$ @+ O4 z+ v: G* `8 p
) c) g' O1 m! ]2 ~/////////////////////////////////////////////////////. [% n) L* o/ ?% [. k
void SendIrDAta_38KHZ(unsigned int temp1, bit temp2)
+ y0 l* l+ b6 A6 R% x d% v& a" z{4 o; B; d0 ^, b3 p
g_endcount=temp1;) w& F; R4 Z! Y2 ^' ?) s- \
g_flag=temp2;
1 Z# B) r% g. F. e5 S5 ] EA=0; g_count=0; EA=1; //避免中断影响count置数
3 V% F2 y* E% E0 w while(1)
! G; J4 g$ w- ]8 V$ R {
, Y) P) g! @# d3 g! J EA=0;- o l' i+ f' a: J" R) x% b2 D4 O
if( g_count < g_endcount ) EA=1; //避免中断影响count比较# R3 |7 s4 J* ^3 v
else9 h! ?- ~" b% U( \! B* J
{* ~* B$ d2 P" F; G
EA=1;: C4 X, h9 N5 z
break;+ i3 O! A, k5 \% K/ G
} ( C" F t$ r; X+ T
} 1 ?) U" B1 t2 p; ]! ~& `5 [
}% k- f% X) g i! N
7 k0 @, q1 w# j* ^2 M3 a
/////////////////////////////////////////////////////5 S6 l D. J1 C- W! g+ [
void SendIRdata_BYTE(unsigned char irdata), Q8 B( i# o. U. U# F/ c Q
{
/ `# ^. Z: ^' u unsigned char i;
+ F3 ]4 D" q3 L( @% k for(i=0;i<8;i++)
2 f6 u$ {/ h0 S% d/ {; B) e {
6 h9 ]5 ^# N; L; J3 r' w% `, c //先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)
% i2 x" Q" k6 g; b3 `0 f. lSendIRdata_38KHZ(43, 1); //13.02*43=0.56ms' B& t8 ^# F5 w
u% P$ k7 }( T) T7 C( F8 |
//停止发送红外信号(即编码中的低电平)2 N/ t6 Q2 }# t
if(irdata & 1) //判断最低位为1还是0。 低位先发送!!! f6 g; V) P4 V& j
SendIRdata_38KHZ(130, 0); //1为宽电平,13.02*130=1.693ms
- h) X' ~$ Z) U3 ]. z/ T else SendIRdata_38KHZ(43, 0); //0为窄电平,13.02*43=0.560ms$ `8 }3 E1 {- d) Y. M
3 h3 I) @% k7 o irdata=irdata>>1;
3 }( w7 V% q! V2 U }8 j4 z1 X5 Y' m: h- c$ O1 d
}
- g- m, s5 P1 U+ w; p8 g/ d m7 ^! b- _0 e+ d O+ E) t
/////////////////////////////////////////////////////* I7 b3 P' G) d, B+ V/ F% ?
void SendIRdata(unsigned char p_irdata)
2 L4 I3 N X' `. C{& N. Y/ I- I, H7 @
//有的遥控器会发一个前脉冲,如果不灵,可试试加上前脉冲) Y6 l# Q* l4 O1 L) t
//发送起始码前脉冲,高电平有38KHZ载波* n; H( r( E# q+ D/ H
//SendIRdata_38KHZ(18, 1);
& D' S) D @1 N# ~# l2 b, h$ t; [ //发送起始码前脉冲,低电平无38KHZ载波
$ l/ c4 k6 P( u8 r- F0 A //SendIRdata_38KHZ(18, 0);6 [* T+ l1 I8 d5 S, X% r
' M9 D6 J7 S: p; X //发送9ms的起始码,高电平有38KHZ载波, E$ t6 W+ ?0 I% @( _
SendIRdata_38KHZ(692, 1); //13.02*692=9.010ms" z0 c7 r. y; |( T+ }
) |$ X0 u7 M4 X; a5 l5 c4 e
//发送4.5ms的结果码,低电平无38KHZ载波
) Y# q" b- t* K' V3 i, C SendIRdata_38KHZ(346, 0); //13.02*346=4.505ms
1 T9 _" B9 Z# R# u
. e, q+ f4 a5 g. E1 t. Y! x //发送十六位地址的前八位
2 q2 Z m) M* s SendIRdata_BYTE(g_iraddr1);0 Z( O! f- f# x9 V$ ~6 V# {
0 Z2 S+ w8 j( t4 v //发送十六位地址的后八位$ }, H% Y$ c1 B# f( J+ \
SendIRdata_BYTE(g_iraddr2);' [) Q3 Z4 g/ u
) d8 _9 k* Y! T/ m: G+ Q+ T //发送八位数据
0 y2 S- y. W2 a; a" V) E SendIRdata_BYTE(p_irdata);
5 d! R; ?+ s6 D. y+ D% d, N/ E
7 u9 W1 `9 }3 N3 e //发送八位数据的反码
. X, @( e/ i( S* {7 _- Q, i# @ SendIRdata_BYTE(~p_irdata); + u- M2 S- G4 `- R1 _, \
! L3 ~. M/ F' }2 @" p7 k //发送总的结束位1bit. B3 d' T) M2 Z* i2 l
SendIRdata_38KHZ(43, 1); //13.02*43=0.56ms3 o3 E# [3 L- i, S
3 v0 s# o8 P! t9 r! u. ], w
( W+ m6 t( m3 P: C( r/* //后面这些可以不用发0 f% v: s d) \% y1 J' p+ V
g_endcount=1766;
/ B9 C1 N4 _) k7 b g_flag=0;* ]* ~/ N! j8 K4 i4 M
EA=0; g_count=0; EA=1;
7 b E/ u7 {. M6 B5 b6 N while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } }
" ^9 q/ E7 M7 W+ h/ Y+ ~5 ^0 G. B% S6 X/ ]
//发送9ms的起始码,高电平有38KHZ载波
# E% J; O7 J% H' o0 T/ }/ X g_endcount=692; //13.02*692=9.010ms
; v# ~7 P6 T) `# l0 ?9 ? g_flag=1;
x9 J6 I7 s" j# f+ A# E" K8 D$ b EA=0; g_count=0; EA=1;
, I' d0 s u4 @ while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } }
: P: W {% _$ G2 ^/ {% @) ]1 Y
//发送4.5ms的结果码,低电平无38KHZ载波
! j& j: l& {0 h" u3 m g_endcount=346; //13.02*346=4.505ms
- k8 y9 m$ @; B! ?- M2 W5 B- | g_flag=0;
, i" Q$ c8 V8 G EA=0; g_count=0; EA=1;8 X7 L9 b; q3 J/ e, K f
while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } }
3 N* g+ {" X" v0 P1 ?
( e. P/ y& G* l" B; A9 {//发送总的结束位1bit- R: r7 @3 M( g
g_endcount=43; //13.02*43=0.56ms
2 m! G) R+ x+ O: p+ f9 D1 c% N1 N g_flag=1;
: p6 @8 L; A$ s4 m* h, k3 H EA=0; g_count=0; EA=1;2 v" V" {8 J# L3 y4 O+ l
while(1){EA=0; if(g_count<g_endcount) EA=1; else { EA=1; break; } } 5 p) j4 |/ E r3 \8 G+ u
$ U; D8 c' q& |
*/
2 L, ]/ n: V" {
$ h) p# [# ~2 l! |7 h+ f g_flag=0;
! M$ m4 K2 _5 b/ W$ a2 `" Z; A
& q$ b- w1 n; ~5 ?& W9 [* q" {$ q$ w; @# o8 h( O
}
, I! O' U. E1 c& u9 p" b8 x5 m$ b8 b2 g9 P! _
$ L* X; S( I) m2 F2 I- z! a" c2 A3 b0 i& Z$ _- K# s/ Z
///////////////////////////////////////////////////////////
- h9 I0 o! N4 n fvoid main(void)7 t- |8 w4 J- Z7 k& q! D3 ?/ ^
{4 N- p& o6 |5 K% \. U; B
unsigned char com_data; //数据字节
7 G! D: E' J* n% W S- g
: s5 @3 S# Z' j5 N2 y! }( b# J$ x g_count = 0;4 }) t6 L3 l; P) T7 O; W
g_flag = 0;
$ ]3 `# J, J' l: h( t- ]) U g_OP = 1;2 f+ v% `! L+ ~* r7 S; A
P0_0 = g_OP; //LED接电源正极,不点亮
8 l5 x9 V. j8 |+ Z: n6 n F2 `& e1 i* a* V
SCON=0x50; //串口方式1 01 0 1 0 0 00 模式1,非多机,允许接收,无数据位8,清中断标识TI和RI/ @) s" Y: }; j: a! t: [9 |' j! z
) A! a6 g l: d: U9 t" s TMOD = 0x22; //(定时器0和1:方式2,自动重装,8位)1 \; T/ h' ~2 S( K0 ]
TH1=253; //11.0592MHZ,9600bps。没有设置SMOD,故波特率没有加倍。即:11.0592/12/3/32=9600bps; b& N0 U( e8 o% {, r6 X( z
TL1=253;4 E0 Q8 z" ^2 K. f; |6 Y& u
TR1=1; //启动定时器* v3 @2 y8 y Y/ |: q) y. D
1 {0 H y( E9 _. I/ X" Q( F: S TH0 = 244;
; F O% O, w' d6 y# d$ I K TL0 = 244; //(WXL:即计数12次中断一次,即11.0592MHZ晶振,机器周期是1.085us,12次*1.085=13.02us,这样达38KHZ。 13us一次中断,时间太短了,所以单片机要快)
G* T( j9 D# J ET0 = 1; //定时器0中断允许6 V6 U0 S9 p/ |7 w
EA = 1; //允许CPU中断8 P" l) r8 n, U) N) n/ s, x
TR0 = 1; //开始计数
- m/ {* z5 d8 H! {
4 W2 h7 P) `0 j7 b, L! B g_iraddr1=0; //地址码0 A( `' ^: B; C; o. g
g_iraddr2=255; //地址反码9 Q! v/ H/ x2 q W
% v" I; e Z" U4 W2 R e9 U9 TRI=0;0 g5 u; F, V9 w" B) h( \
while(1). L* j& [% D+ i0 K. [
{" l! _, ?- e) w: i! |3 R
if(RI==1): Y$ c) ^1 L# d7 K( P
{
8 r- A% Q+ x* xcom_data =SBUF;
! e' f9 L2 j* J, y6 S D- YRI=0; //要人工清RI( Z( x! ^6 G1 W( t
SendIRdata(com_data); //发送红外数据
0 w; i( x- \. D4 T5 v- v) |TI=0;
: L d- N9 v$ L' v- kSBUF = com_data; //输出字符
# f8 |: v& A' ~: I1 dwhile(!TI) ; //空语句判断字符是否发完,TI=1表示发完5 W) o L; Q! { p! f
TI = 0; //要人工清TI4 ]& {. X2 G' K7 }/ w; T
}
/ m# W* ?' Z0 {2 ]5 U) @' Y}# ?7 \1 R( \# X- ]7 B( ]$ b5 U
# h r9 H6 k: l) b" e, [
} |
|