这是一个红外发码解码的原理,利用一个普通的红外发射管,利用一个IO口,发射38KHz的载波与按键。这个原理图中没有按键,所以程序中就发了固定的红外码值,如果需要加入按键的话直接加入按键扫描的程序即可。本程序是的开发语言是mini C(为了适用特别的编译器),基本上是和C语言一样的,只是个别关键字不一样而已。
电路原理图如下:
单片机源程序如下:
//发射源码
#include "extern.h"
.RAMADR 0
WORD zero;
WORD count;
WORD set_count;
WORD cnt0;
BYTE FLAG_1;
//WORD cnt1;
//BYTE cnt2;
//BYTE cnt3;
//BYTE irdata;
BYTE ircode;
//.RAMADR SYSTEM
BIT ir : PA.3;
BIT ir_flag : FLAG_1.0;
void INIT(void)
{
PA=0XFF; //IO
PAC=0B_1111_1111; //输入设置 1为输出 PA4输入
PAPH=0X00; //无上拉
$ PADIER 0B_0000_0000; //使能数字输入及唤醒功能,0数字,1模拟
// disgint ;
inten.2=1; //tm16溢出中断
intrq=0;
t16m=0B_001_00_000; //SYSCLK_4m,1分频,8位中断,1/(4M/1) = 0.25us
integs=0B_0000_0000;
WORD t_count=215;
stt16 t_count; //tm16置初值,定时0.25*(256-204)=13us
engint; //使能中断
}
void delay_ms(void)//24ms
{
while(1)
{
cnt0++;
if(cnt0>=8000)
{
cnt0=0;
break;
}
}
}
void delay_s(void)
{
BYTE i = 2;//2
do
{
delay_ms();
}while(i--);
}
void ir_sendbyte(void)
{
BYTE i = 8;
do
{
i--;
set_count = 43;//发送560us高电平
ir_flag = 1;//启动红外发射
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;//关闭定时器
if(ircode.0) set_count = 130;//判断红外编码最低位,若为1则为1.69ms低电平
else set_count = 43;//否则为560us低电平
ir_flag = 0;//低电平不发射
count = 0;
set1 t16m.5;
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;
ircode = ircode>>1;
}while(i);
}
void ir_send1(void)
{
set_count = 782;//692发送编码中的引导码(9ms+4.5ms)
ir_flag = 1;//启动红外
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;//关闭定时器
set_count = 346;//发送编码中的4.5ms低电平
ir_flag = 0;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;//关闭定时器
ircode = 0x00;//用户码前8位
ir_sendbyte();
ircode = 0xff;//用户码后8位
ir_sendbyte();
ircode = 0x56;//8位数据码0x56 测试0x45 反0xba
ir_sendbyte();
ircode = 0xa9;//数据码反码0xa9
ir_sendbyte();
set_count = 43;//发送编码中的560us高电平
ir_flag = 1;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;//关闭定时器
ir = 1;
delay_ms();//23ms
set_count = 782;//发送引导码
ir_flag = 1;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;
set_count = 346;//发送编码中的4.5ms低电平
ir_flag = 0;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;
set_count = 43;
ir_flag = 1;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;
ir = 1;
}
void ir_send2(void)
{
set_count = 782;//692发送编码中的引导码(9ms+4.5ms)
ir_flag = 1;//启动红外
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;//关闭定时器
set_count = 346;//发送编码中的4.5ms低电平
ir_flag = 0;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;//关闭定时器
ircode = 0x00;//用户码前8位
ir_sendbyte();
ircode = 0xff;//用户码后8位
ir_sendbyte();
ircode = 0x34;//8位数据码0x34 测试0x47 反0xb8
ir_sendbyte();
ircode = 0xcb;//数据码反码0xcb
ir_sendbyte();
set_count = 43;//发送编码中的560us高电平
ir_flag = 1;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;//关闭定时器
ir = 1;
delay_ms();//23ms
set_count = 782;//发送引导码
ir_flag = 1;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;
set_count = 346;//发送编码中的4.5ms低电平
ir_flag = 0;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;
set_count = 43;
ir_flag = 1;
count = 0;
set1 t16m.5;//开启定时器
while(1)
{
if(count > set_count) break;
}
set0 t16m.5;
ir = 1;
}
void FPPA0 (void)
{
.ADJUST_IC SYSCLK=IHRC/4 // SYSCLK=IHRC/2
// Insert Initial Code
//清除RAM
Zero = _SYS(RAM_SIZE)-1;
a = 0;
do
{
*Zero = a;
}while(--Zero$0);
count = 0;
ir_flag = 0;
INIT();
while (1)
{
ir_send1();
delay_s();
ir_send2();
delay_s();
// wdreset;
}
}
|