1. 單片機c語言編寫紅外遙控控制小車,按下數字2,小車啟動前進,怎麼寫
紅外遙控小車,關鍵是小車上要有一個紅外接收頭,接收紅外遙控器發送的紅外信號。按下數字2,是單片機板上的按鍵吧,這首先必須要對所用按鍵編碼,小車接收後再解碼,這樣小車才能識別按鍵。至於小車啟動,就發送數字2的編碼即可。下圖是紅外接收頭。
2. 知道了紅外遙控的編碼(16位1101 0011 1001 0010)請問怎樣在單片機里解碼
;遙控器讀碼程序(晶振為11.0592),該程序能讀出遙控器的控制碼,並通過LED顯示出來
;OMEN 2005/1/16於TCL
;***************************************************************
A_BIT EQU 20H ;數碼管個位數存放內存位置
B_BIT EQU 21H ;數碼管十位數存放內存位置
NO_OUT EQU 24H ;最終控制號碼存放單元
A_NO EQU 25H ;數碼管個位數對應代碼存放內存位置
B_NO EQU 26H ;數碼管十位數對應代碼存放內存位置
;22H,23H為控制碼及其反碼的存放單元
;*******************<<主程序>>***********************************
ORG 0000H
AJMP 0030H
ORG 0003H ;外部中斷P3.2腳INT0入口地址
AJMP INT ;轉入外部中斷服務子程序(解碼程序)
ORG 0030H
AJMP MAIN ;轉入主程序
;***************************************************************
MAIN: MOV NO_OUT,#0H
SETB EA ;打開CPU總中斷請求
SETB IT0 ;設定INT0的觸發方式為脈沖負邊沿觸發
SETB EX0 ;打開INT0中斷請求
LOOP: MOV A,NO_OUT;將按鍵的鍵值通過P1口的8個LED顯示出來!
CPL A ;由於P1發光二極體顯示的是電平的反狀態,所以取反
MOV P1,A ;發光二極體顯示輸出
LCALL DISPLAY;LED數碼管顯示輸出
AJMP LOOP;循環
;********************<<中斷接受遙控程序>>************************
;以下為進入P3.2腳外部中斷子程序,也就是解碼程序
INT:
PUSH ACC
PUSH PSW ;將PSW和ACC推入堆棧保護
CLR EA ;暫時關閉CPU的所有中斷請求
MOV R6,#10
SB: LCALL DL865;調用865微秒延時子程序
JB P3.2,EXIT;延時865微秒後判斷P3.2腳是否出現高電平如果有就退出解碼程序
DJNZ R6, SB;重復10次,目的是檢測在8650微秒內如果出現高電平就退出解碼程序
;以上完成對遙控信號的9000微秒的初始低電平信號的識別。
JNB P3.2, $ ;等待高電平避開9毫秒低電平引導脈沖
LCALL DL4737 ;延時4.74毫秒避開4.5毫秒的結果碼
MOV R7,#16;忽略前26位系統識別碼
JJJJA:JNB P3.2,$;等待地址碼第一位的高電平信號
LCALL DL865;高電平開始後用865微秒的時間尺去判斷信號此時的高低電平狀態
MOV C,P3.2;將P3.2引腳此時的電平狀態0或1存入C中
JNC UUUA;如果為0就跳轉到UUUA
LCALL DL1000;檢測到高電平1的話延時1毫秒等待脈沖高電平結束
UUUA: DJNZ R7,JJJJA
MOV R1,#22H ;設定22H為起始RAM區
MOV R2,#2;接收從22H到23H的2個內存,用於存放操作碼和操作反碼
PP: MOV R3,#8;每組數據為8位
JJJJ: JNB P3.2,$;等待地址碼第一位的高電平信號
LCALL DL865;高電平開始後用865微秒的時間尺去判斷信號此時的高低電平狀態
MOV C,P3.2;將P3.2引腳此時的電平狀態0或1存入C中
JNC UUU;如果為0就跳轉到UUU
LCALL DL1000;檢測到高電平1的話延時1毫秒等待脈沖高電平結束
UUU: MOV A,@R1;將R1中地址的給A
RRC A;將C中的值0或1移入A中的最低位
MOV @R1,A;將A中的數暫時存放在R1數值的內存中
DJNZ R3,JJJJ;接收滿8位換一個內存
INC R1;對R1中的值加1,換下一個RAM
DJNZ R2,PP ;接收完8位數據碼和8位數據反碼,存放在22H/23H中
MOV A,22H
CPL A;對22H取反後和23H比較
CJNE A,23H,EXIT;如果不等表示接收數據發生錯誤,放棄
MOV A,22H
MOV NO_OUT,A
;LCALL EEPROM_C ;清除以前的保存的碼
;LCALL DL4737
;LCALL EEPROM_W ;把碼存在單片機內部的EEPROM里
;LCALL DL4737
CLR P3.6;蜂鳴器鳴響-嘀嘀嘀-的聲音,表示解碼成功
LCALL DL4737
LCALL DL4737
LCALL DL4737
SETB P3.6;蜂鳴器停止
lcall DL4737
EXIT: SETB EA ;允許中斷
POP PSW
POP ACC ;將PSW和ACC推入堆棧保護
RETI ;退出解碼子程序
;*******************<<LED數碼管顯示子程序>>**********************
DISPLAY:
MOV A,NO_OUT ;將NO_OUT分成個位和16位
ANL A,#0FH ;取低四位放在a_bit
MOV A_BIT,A ;個位
MOV A,NO_OUT ;
RR A
RR A
RR A
RR A ;四次移動,把高四位移到低四位
ANL A,#0FH;取高四位放在B_bit
MOV B_BIT,A ;個位在b
MOV DPTR,#NUMTAB ;指定查表啟始地址
MOV A,A_BIT ;取個位數
MOVC A,@A+DPTR ;查個位數的7段代碼
MOV A_NO,A
MOV A,B_BIT ;取十位數
MOVC A,@A+DPTR ;查十位數的7段代碼
MOV B_NO,A
DPLOP:MOV A,A_NO
MOV P0,A ;送出個位的7段代碼
;SETB P2.1;關閉十位顯示,防止鬼影
CLR P2.0 ;開個位顯示
LCALL DL40 ;顯示4737微秒
SETB P2.0;關閉個位顯示,防止鬼影
MOV A,B_NO
MOV P0,A ;送出十位的7段代碼
CLR P2.1 ;開十位顯示
LCALL DL40 ;顯示4737微秒
SETB P2.1;關閉十位顯示,防止鬼影
RET
;**********************<<延時程序>>******************************
DL865: MOV R4,#12 ; 1.09*(2R5+4)*R4+2延時子程序1,精確延時865微秒
D1: MOV R5,#31
DJNZ R5,$
DJNZ R4,D1
RET
DL4737: MOV R4,#12 ;延時子程序2,精確延時4737微秒
D2: MOV R5,#179
DJNZ R5,$
DJNZ R4,D2
RET
DL1000: MOV R4,#17;延時程序3,精確延時1000微秒
D3: MOV R5,#25
DJNZ R5,$
DJNZ R4,D3
RET
DL40: MOV R4,#1;延時程序4,精確延時40/17微秒
D4: MOV R5,#1
DJNZ R5,$
DJNZ R4,D4
RET
;****************************************************************
;如果是共陽數碼管的顯示代碼 1-F 16個代碼
NUMTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH ;STC新板的
END
3. 51單片機怎麼用紅外線
--你是指紅外遙控解碼吧,給你一點提示,在單片機定義一個I/O口為紅外遙控的輸入埠,(紅外遙控解碼不一定要用到定時器和中斷方式.具體方法有很多的,看場合選取)當然輸入這個埠的信號是經過遙控接收電路處理過的一串數據,如TTL或者CMOS電平。再然後就是對這個輸入信號進行處理,也就是解調出遙控碼值出來,要解這個碼,首先又要知道其波形如何,即是邏輯電平和時序等問題...
建議你還是先熟知一下各種IR的遙控協議,有挺多的,典型的有NEC,飛利浦等。說說NEC的也有兩種,簡單的一種就是有32位數據,前16bit為地址碼,後16bit為遙控碼值的正碼與反碼,地址碼用於區分相同協議下不同的遙控所帶來的干擾等,正碼和反碼用於解調後進行校驗數據。不多說了,主要是找點相關資料研究研究就明白了。圖片是一個32bitNEC的遙控波形,這個波形的地址碼是807F,正碼是0x12,如果看懂了,用MCU解遙控碼就很容易了..
4. 如何用單片機探測到紅外感應信號
如果僅僅是判斷有無信號,設置一個閾值,超過閾值輸出1[或0],此時用比較器即可;熱釋電感測器輸出的信號實際上是連續變化的,也可以用單片機的ADC采樣進行數據採集後再處理.取決於你的用法.
5. 單片機紅外遙控問題,要求:一個單片機發送數字另一個單片機也要能顯示出相應的數字
呵呵,我剛前幾天剛編好的程序,你的圖片太小了,看不清楚
只要單片機原理圖沒用(你這個只是接受用的期間,沒有發射的器件),你的紅外晶元是什麼型號的,要不怎麼知道它的協議是什麼~~~
它的時序還是有要求的,也就是紅外晶元(也就是你要發射的紅外線的晶元),它的型號不一樣,那麼它的協議就不一樣,你先看看你紅外發射晶元的型號,找到datasheet,然後就是找到協議,我這可以給你提供方法,把程序貼出來吧,你自己看看吧
#include"reg52.h"
#include"MacroAndConst.h"
#include"Foot.h"
#include"Delay.h"
#include"intrins.h"
ucharnum;
ucharkey_code=0; //遙控鍵值
ucharnew_code=0; //有無新按鍵
uinttemp_key_code=0; //鍵值暫存
ucharkey_bit_count=0; //鍵值碼脈沖計數
uintcount=0; //定時中斷次數計數
uinttemp_count=0; //定時中斷計數暫存
ucharcommon_code_count=0; //前導碼脈沖計數
ucharir_flag=0; //脈沖接收器所處的狀態,0:無信號,1:系統碼接收區,2:數據碼接收區
//初始化
voidinter_init()
{
ir=1; //紅外埠寫1
TMOD=0X02; //定時器0,模式2,8位自動重裝
TH0=(256-50)/256; //定時50us
TL0=TH0;
ET0=1; //允許定時器0中斷
IT1=1; //INT1下降沿觸發
ET1=1; //允許外部中斷
EA=1; //開總中斷
}
//定時器中斷
voidtimer0() interrupt1
{
count++; //定時器中斷次數累加
}
//外部中斷,紅外解碼程序
voidint1() interrupt2
{
TR0=1;
if(count>12&&count<270) //如果信號合法,則放入buf_count,count清0,對下一個脈沖信號計時
{
temp_count=count;
count=0;
}
delay_10us(10); //延時100us來消除下降沿跳變抖動
if(ir==0) //INT1引腳穩定為低電平,則表明確實是信號,count重新計數,由於上面延時50us,因此要補償一次T0中斷
{
count=2;
}
if(temp_count>12&&temp_count<270) //若收到信號合法,則再次進行信號分析
{
if(ir_flag==0) //如果之前未收到起始碼
{
if(temp_count>21&&temp_count<270) //判斷是否起始碼13.5
{
ir_flag=1; //系統標記
temp_count=0;
}
}
elseif(ir_flag==1) //收到起始碼
{
if(common_code_count>=26) //若收到26個脈沖
{
ir_flag=2; //數據解碼標志
common_code_count=0; //系統碼計算清0
temp_count=0; //中斷計數暫存清0
}
elseif((temp_count>40&&temp_count<70)||(temp_count>12&&temp_count<32))
{
temp_count=0;
common_code_count++; //每收到一個信號自加1
}
}
elseif(ir_flag==2) //進入數據編碼接收
{
if(key_bit_count<8) //收到數據少於8位,則將收到的數據寫入buf_key_code
{
if(temp_count>40&&temp_count<70)
{
temp_count=0;
temp_key_code>>=1;
temp_key_code|=0x80; //收到1
key_bit_count++; //數據脈沖累加
}
elseif(temp_count>12&&temp_count<32)
{
temp_count=0;
temp_key_code>>=1; //收到0
key_bit_count++;
}
}
else //若收到8位數據則做以下處理
{
ir_flag=0; //接收狀態返回到空閑
key_code=temp_key_code;
key_bit_count=0;
temp_key_code=0;
temp_count=0;
TR0=0;
new_code=1;
}
}
}
}
好好看看吧,使用的定時計數器,挺簡單的,重點在於協議,明白了協議就哦了
呵呵,記得給分啊~~
(*^__^*)嘻嘻……
6. 最簡單51單片機紅外編碼獲取問題
這有個帖子,你看了就明白,看看是怎樣實現輸入晶振頻率自適應解碼。
#define CPU_Fosc 12000000L //輸入主頻,自適應解碼(單位:Hz,范圍:6MHz ~ 40MHz)
紅外線解碼程序+遙控器程序+模擬文件(可定義任意I/O作接收腳,支持長/短按,適應6MHz~40MHz)
http://www.ourdev.cn/thread-5155483-1-1.html
7. 單片機 紅外解碼
紅外線遙控是目前使用最廣泛的一種通信和遙控手段。由於紅外線遙控裝置具有體積小、功耗低、功能強、
成本低等特點,因而,繼彩電、錄像機之後,在錄音機、音響設備、空凋機以及玩具等其它小型電器裝置上也紛
紛採用紅外線遙控。工業設備中,在高壓、輻射、有毒氣體、粉塵等環境下,採用紅外線遙控不僅完全可靠而且
能有效地隔離電氣干擾。
1 紅外遙控系統
通用紅外遙控系統由發射和接收兩大部分組成。應用編/解碼專用集成電路晶元來進行控制操作,如圖1 所示。
發射部分包括鍵盤矩陣、編碼調制、LED 紅外發送器;接收部分包括光、電轉換放大器、解調、解碼電路。
遙控發射器及其編碼
遙控發射器專用晶元很多,根據編碼格式可以分成兩大類,這里我們以運用比較廣泛,解碼比較容易的一類
來加以說明,現以日本NEC 的uPD6121G 組成發射電路為例說明編碼原理(一般家庭用的DVD、VCD、音響都使用
這種編碼方式)。當發射器按鍵按下後,即有遙控碼發出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下
特徵:
採用脈寬調制的串列碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms 的組合表示二進制的「0」;以脈
寬為0.565ms、間隔1.685ms、周期為2.25ms 的組合表示二進制的「1」.
上述「0」和「1」組成的32 位二進制碼經38kHz 的載頻進行二次調制以提高發射效率,達到降低電源功耗的
目的。然後再通過紅外發射二極體產生紅外線向空間發射
UPD6121G 產生的遙控編碼是連續的32 位二進制碼組,其中前16 位為用戶識別碼,能區別不同的電器設備,
防止不同機種遙控碼互相干擾。該晶元的用戶識別碼固定為十六進制01H;後16 位為8 位操作碼(功能碼)及其
反碼。UPD6121G 最多額128 種不同組合的編碼。
遙控器在按鍵按下後,周期性地發出同一種32 位二進制碼,周期約為108ms。一組碼本身的持續時間隨它包
含的二進制「0」和「1」的個數不同而不同,大約在45~63ms 之間.
2 遙控發射器及其編碼
遙控發射器專用晶元很多,根據編碼格式可以分成兩大類,這里我們以運用比較廣泛,解碼比較容易的一類
來加以說明,現以日本NEC 的uPD6121G 組成發射電路為例說明編碼原理(一般家庭用的DVD、VCD、音響都使用
這種編碼方式)。當發射器按鍵按下後,即有遙控碼發出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下
特徵:
採用脈寬調制的串列碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms 的組合表示二進制的「0」;以脈
寬為0.565ms、間隔1.685ms、周期為2.25ms 的組合表示二進制的「1」
上述「0」和「1」組成的32 位二進制碼經38kHz 的載頻進行二次調制以提高發射效率,達到降低電源功耗的
目的。然後再通過紅外發射二極體產生紅外線向空間發射。
UPD6121G 產生的遙控編碼是連續的32 位二進制碼組,其中前16 位為用戶識別碼,能區別不同的電器設備,
防止不同機種遙控碼互相干擾。該晶元的用戶識別碼固定為十六進制01H;後16 位為8 位操作碼(功能碼)及其
反碼。UPD6121G 最多額128 種不同組合的編碼。
遙控器在按鍵按下後,周期性地發出同一種32 位二進制碼,周期約為108ms。一組碼本身的持續時間隨它包
含的二進制「0」和「1」的個數不同而不同,大約在45~63ms 之間。
遙控信號接收
接收電路可以使用一種集紅外線接收和放大於一體的一體化紅外線接收器,不需要任何外接元件,就能完成
從紅外線接收到輸出與TTL 電平信號兼容的所有工作,而體積和普通的塑封三極體大小一樣,它適合於各種紅外
線遙控和紅外線數據傳輸。
接收器對外只有3 個引腳:Out、GND、Vcc 與單片機介面非常方便
① 脈沖信號輸出接,直接接單片機的IO 口。
② GND 接系統的地線(0V);
③ Vcc 接系統的電源正極(+5V);
8. 求救!!! 求51單片機用1602液晶顯示紅外解碼的方法!!!要在液晶上顯示遙控器對應的數字!!
你的意思是,遙控器按下什麼數字,液晶就顯示什麼數字??
首先你得將遙控器上的紅外波形記錄下來存在單片機EEPROM里,即單片機判斷並存儲紅外一體化接收頭的高低波形的時長。
然後將接收到的波形的個高低電平的時長參數和已存儲的波形數據進行比較,即可知現在是什麼鍵按下了
9. 單片機紅外編碼
C51程序代碼:
#include <AT89X51.h>
static bit OP; //紅外發射管的亮滅
static unsigned int count; //延時計數器
static unsigned int endcount; //終止延時計數
static unsigned char flag; //紅外發送標志
char iraddr1; //十六位地址的第一個位元組
char iraddr2; //十六位地址的第二個位元組
void SendIRdata(char p_irdata);
void delay();
void main(void)
{
count = 0;
flag = 0;
OP = 0;
P3_4 = 0;
EA = 1; //允許CPU中斷
TMOD = 0x11; //設定時器0和1為16位模式1
ET0 = 1; //定時器0中斷允許
TH0 = 0xFF;
TL0 = 0xE6; //設定時值0為38K 也就是每隔26us中斷一次
TR0 = 1;//開始計數
iraddr1=3;
iraddr2=252;
do{
delay();
SendIRdata(12);
}while(1);
}
//定時器0中斷處理
void timeint(void) interrupt 1
{
TH0=0xFF;
TL0=0xE6; //設定時值為38K 也就是每隔26us中斷一次
count++;
if (flag==1)
{
OP=~OP;
}
else
{
OP = 0;
}
P3_4 = OP;
}
void SendIRdata(char p_irdata)
{
int i;
char irdata=p_irdata;
//發送9ms的起始碼
endcount=223;
flag=1;
count=0;
do{}while(count<endcount);
//發送4.5ms的結果碼
endcount=117
flag=0;
count=0;
do{}while(count<endcount);
//發送十六位地址的前八位
irdata=iraddr1;
for(i=0;i<8;i++)
{
//先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的低電平)
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);
//停止發送紅外信號(即編碼中的高電平)
if(irdata-(irdata/2)*2) //判斷二進制數個位為1還是0
{
endcount=41; //1為寬的高電平
}
else
{
endcount=15; //0為窄的高電平
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//發送十六位地址的後八位
irdata=iraddr2;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//發送八位數據
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//發送八位數據的反碼
irdata=~p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=41;
}
else
{
endcount=15;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
endcount=10;
flag=1;
count=0;
do{}while(count<endcount);
flag=0;
}
void delay()
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}
10. 使用紅外接收裝置VS1383B, 如何連入單片機 通過單片機來識別信號(信號源為940nm的紅外,波形如下)。
不同的遙控器輸出的信號是不同的,一般都有由: 引導頭 8位系統碼 8 位用戶碼 8位系統碼反碼 8 位用戶碼反碼組成, 系統碼區別不同的遙控器,用戶碼區別不同的按鍵
並且不同的遙控器引導碼是不同的,並且代表0和1的高低電平時間不同的,只有知道這些基本數據後,才可用單片機解碼,如果用示波器把這些波型記錄下來,人工就不能分析,你怎麼編程序讓單片機來識別呢?知道這些基本數據後把VS1383B的輸出接入單片機的IO引腳(一般是中斷引腳),單片機根據高低電平的持續時間可以識別出0和1,進而解析出用戶碼和系統碼,再根據需要執行不同的動作