最近由于学习使用STC89C52做红外发射功能,但是介于自己太懒了,所以就只想CV一下,网上找了很多没有现成的,最终找到一个比较完整的,所以自己手动改了一下,记录一下代码!
来源
原作者写的非常详细,但是无奈我用不上这么多功能,我只需要一段发射红外的代码,如果想要查看完整代码的,请通过以下链接跳转到原作者分享的代码:
stc89c52开发板遥控器解码 红外线发射 内置 eeprom 存储 串口显示编码
代码
这里我把定时器0改成了定时器1,因为我定时器0用来做别的事情去了!
#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);
}
}