#include <iom16v.h>
#include <macros.h>
#define IR_ON PORTB|=BIT(1) //红外发射管接在PB1口上
#define IR_OFF PORTB&=~BIT(1)
#define K1 (PIND&BIT(7)) //K1键PD7
#define LED_0 PORTB&=~BIT(0) //指示灯
#define LED_1 PORTB|=BIT(0)
//延时n毫秒
//51单片机下是115(11.0592M晶振,用51单片机的人自己改吧)
void delay(unsigned int n)
{
unsigned int i;
while (n--)
for (i=0;i<1140;i++); //1ms基准延时
}
//延时0.5ms
void delay500us(void)
{
unsigned int i;
for (i=0;i<570;i++); //1140*0.5=570
}
//延迟0.56ms
void delay560us(void)
{
unsigned int i;
for (i=0;i<638;i++); //1140*0.56=638.4
}
/* 本电路使用了硬件调制38khz而非软件,本人推荐用硬件调制
* 如果用软件来调制的话会使得接收端接收到的时间误差很大
* 比如发射9ms高电平,接收端收到的可能就是10ms的高电平,导致出错
**/
//LED指示灯亮、灭
void led(void)
{
//端口设为输出时也可以用PINB寄存器读端口,但读出的是用PORTB寄存器设置的状态
//外部电平无法改变PORTB寄存器的状态
if (PINB&BIT(0))
LED_0;
else
LED_1;
}
//引导码
void send_first(void)
{
IR_ON;
delay(9); //9ms高电平
IR_OFF;
delay(4); //4.5ms低电平
delay500us();
//与单片机I/O口接的那个三极管最好是使用NPN的
//否则这里的电平就反了,因为PNP三极管是低电平导通,NPN三极管是高电平导通
}
//发送0
void send_0(void)
{
IR_ON;
delay560us();
IR_OFF;
delay560us();
}
//发送1
void send_1(void)
{
IR_ON;
delay560us();
IR_OFF;
delay560us();
delay560us();
delay560us();
}
//发送一个字节
void send_byte(unsigned char Data)
{
unsigned char i;
for (i=0;i<8;i++)
{
if (Data&BIT(i))
send_1();
else
send_0();
}
}
//发送尾码,使接收端能确定最后一位是0还是1
void send_end(void)
{
IR_ON;
delay560us();
IR_OFF;
}
//★发送一个完整的按键码
//usercode为用户码,16位
//keycode为键码,8位
void send(unsigned int usercode, unsigned char keycode)
{
send_first();
send_byte(usercode/256); //用户码高8位
send_byte(usercode%256); //用户码低8位
send_byte(keycode); //键码
send_byte(~keycode); //键码的反码
send_end();
}
//按下按键K1后执行的操作
void execute(void)
{
unsigned char i;
//范例1:下面这条语句可以实现静音功能
//send(0x01fd,0x12); //我的电视的静音键的用户码是0x01fd,键码是0x12
//范例2:下面的程序可以让dvd反复出/入仓
/*while (1)
{
send(0x00ff,0x0c); //我的DVD机的出仓键
delay(2500);
}*/
//范例3:下面的程序可以让电视机显示菜单,并自动地不停地移动光标
/*send(0x01fd,0x50); //显示菜单
while (1)
{
send(0x01fd,0x14); //不停地按“下键”
delay(1000);
}*/
//范例4:下面的程序可以使电视的音量来回加减
while (1)
{
for (i=0;i<10;i++)
{
send(0x01fd,0x55); //加音量
delay(200);
}
delay(500);
for (i=0;i<10;i++)
{
send(0x01fd,0x56); //减音量
delay(200);
}
delay(500);
}
//你们的电视机和dvd的键码肯定跟我的不一样,只需要把用户码和键码改成你们的就行了
//反正我测试了是完全正常运行的
}
void main(void)
{
DDRB=0xff; //PB口全部设置为输出
PORTB=0x00;
DDRD=0x00; //PD口全部设置为输入,尽管我只弄了一个按键在PD7口上
PORTD=0xff;
while (1)
{
//按键K1
if (!K1)
{
delay(15);
if (!K1)
{
led(); //LED亮/灭
execute(); //执行相应的遥控发射操作
//用户一直按住键不松手的程序我就不写了
//具体是:每隔108ms发射9ms高电平和2.25ms低电平再0.56ms高电平再拉低
while (!K1); //要写就写在这里
delay(5); //按键松开后等待,防止抖动
}
}
}
}
//本程序作者:巨大八爪鱼
//QQ:970349094
//2013年10月4日21:26:00