目前共有7篇帖子。
【本人原創程序】教你用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

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2024 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。