最近由于学习使用STC89C52做红外发射功能,但是介于自己太懒了,所以就只想CV一下,网上找了很多没有现成的,最终找到一个比较完整的,所以自己手动改了一下,记录一下代码!

来源

原作者写的非常详细,但是无奈我用不上这么多功能,我只需要一段发射红外的代码,如果想要查看完整代码的,请通过以下链接跳转到原作者分享的代码:

stc89c52开发板遥控器解码 红外线发射 内置 eeprom 存储 串口显示编码

代码

这里我把定时器0改成了定时器1,因为我定时器0用来做别的事情去了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

#include <reg52.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define uchar unsigned char
#define uint unsigned int

// 发射延时
#define m9 (65536 - 9000) // 约9mS
#define m4_5 (65536 - 4500) // 约4.5mS
#define m1_6 (65536 - 1630) // 约1.65mS
#define m_65 (65536 - 580) // 约0.65mS
#define m_56 (65536 - 560) // 约0.56mS
#define m40 (65536 - 40000) // 约40mS
#define m56 (65536 - 56000) // 56mS
#define m2_25 (65536 - 2250) // 约2.25mS

sbit LaunchLED = P1 ^ 5;

typedef struct
{
unsigned char custom_height;
unsigned char custom_lower;
unsigned char ir_code;
unsigned char re_ir_code;
} IR_CODE, *pIR_CODE;

void delay(uint xms); // 延时1ms
void IR_launch(IR_CODE);
void IR_launch_time(bit, unsigned int);
void IR_launch_frame(unsigned char);

void delay(uint xms)
{
uint i, j;
for (i = xms; i > 0; i--) // i=xms即延时约xms毫秒
for (j = 112; j > 0; j--)
;
}

void init_IR()
{

// 发射
TMOD |= 0x11; // T0 16位工作方式 【这里为啥是0x11,因为这里我改成了定时器1来计时,如果你是定时器0计时使用 0x01即可】
LaunchLED = 1; // 发射端口常态为高电平
}

// 发射
void IR_launch(IR_CODE ir_code)
{
IR_launch_time(1, m9); // 高电平9mS
IR_launch_time(0, m4_5); // 低电平4.5mS

/*┈ 发送4帧数据┈*/
IR_launch_frame(ir_code.custom_height);
IR_launch_frame(ir_code.custom_lower);
IR_launch_frame(ir_code.ir_code);
IR_launch_frame(ir_code.re_ir_code);

/*┈┈ 结束码 ┈┈*/
IR_launch_time(1, m_65);
IR_launch_time(0, m40);
}

// 发送 1 帧数据
void IR_launch_frame(unsigned char frame)
{
char i = 0;
for (i = 0; i < 8; i++) // 循环8次移位
{
IR_launch_time(1, m_65); // 高电平0.65ms
if (frame >> i & 0x1)
IR_launch_time(0, m1_6); // 发送最低位
else
IR_launch_time(0, m_56);
}
}

// 38KHz脉冲发射 + 延时程序
void IR_launch_time(bit status, unsigned int t)
{
TH1 = t >> 8; // 输入T0初始值
TL1 = t;
TF1 = 0; // 清0
TR1 = 1; // 启动定时器0
if (0 == status)
{
// BT=0时不发射38KHz脉冲只延时;BT=1发射38KHz脉冲且延时;
while (!TF1)
;
}
else
{
while (1)
{
/**
* 38KHz脉冲,占空比5:26
* 以下是逻辑分析仪测试结果
* 3:23us 识别正常
* 6:23us 识别正常
* 10:23us 识别失败
* 12:23us 识别失败
* 16:23us 识别失败
*/
LaunchLED = 0;
if (TF1)
break;
if (TF1)
break;
LaunchLED = 1;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
if (TF1)
break;
}
}
TR1 = 0; // 关闭定时器0
TF1 = 0; // 标志位溢出则清0
LaunchLED = 1; // 脉冲停止后,发射端口常态为高电平
}

IR_CODE global_ir_code;

void main(void)
{
// 设置需要发射的红外编码
global_ir_code.custom_height = 0x00;
global_ir_code.custom_lower = 0xff;
global_ir_code.ir_code = 0x45;
global_ir_code.re_ir_code = 0xba;

init_IR();
while (1)
{
IR_launch(global_ir_code);
delay(1000);
}
}