目前共有7篇帖子。 內容轉換:不轉換▼
 
點擊 回復
621 6
【本人原创程序】教你用AVR单片机制作遥控器
一派護法 十九級
1樓 發表于:2013-10-4 21:27

电路图:

一派護法 十九級
2樓 發表于:2013-10-4 21:27

#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

一派護法 十九級
3樓 發表于:2013-10-4 21:28
本程序和电路经过我测试,是完全可以用的,请大家放心使用
一派護法 十九級
4樓 發表于:2013-10-4 21:28
本人从7月底就开始研究红外发射,但直到现在才成功。
一派護法 十九級
5樓 發表于:2013-10-6 14:18
一派護法 十九級
6樓 發表于:2013-11-1 16:23

NPN三极管Q1既可以用9013,也可以用8050,本人试过,都能正常工作。

如果不能正常工作一般都是NE555的38khz调制部分接错线了。

 

今天本人在焊接第二份电路的时候,总是出错(Q1用的是9013,上次写本文时用的是8050),后来才发现NE555集成块上第4引脚右边的1k电阻(因为1k电阻用完了,这次我用两个505欧的电阻串联而成)接到了2引脚上,和他们短路了,!!!!

 

修正后问题就解决了,虽然使用的是市售普通的红外管,但用手圈住蒙上发光管,接收方也能正常接收,就连数据都是完全正确的,没有一个错误,角度也随便旋转,只要不太偏激就行了。用手360度把发光管挡住,都能正常运行。

一派護法 十九級
7樓 發表于:2013-11-1 16:36

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:621 回複數:6
評論數: ?
作者:巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2013-11-1 16:36
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用共享創意姓名標示-相同方式分享 3.0 Unported許可協議進行許可。