最近由于学习使用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); } }
|