51单片机红外遥控程序是什么?

51单片机红外遥控程序是什么?,第1张

#include\x0d\x0a#include\x0d\x0a#define uchar unsigned char\x0d\x0a#define uint unsigned int\x0d\x0asbit lcden = P2^7\x0d\x0asbit lcdrs = P2^6\x0d\x0asbit lcdwr = P2^5\x0d\x0asbit IR = P3^2\x0d\x0auchar IRCOM[6]//数组,用于存储红外编码\x0d\x0auchar code table1[] = "remote control"\x0d\x0auchar code table2[] = "CODE:"\x0d\x0avoid delayms(uchar x)// 延时x*0.14ms\x0d\x0a{\x0d\x0auchar i\x0d\x0awhile(x--)\x0d\x0afor(i=0i//延时xms\x0d\x0a{\x0d\x0auchar i,j\x0d\x0afor(i=xi>0i--)\x0d\x0afor(j=110j>0j--)\x0d\x0a}\x0d\x0a/****************************LCD部分***********************************************/\x0d\x0avoid write_com(uchar com)\x0d\x0a{\x0d\x0alcden = 0\x0d\x0alcdrs = 0\x0d\x0alcdwr = 0\x0d\x0aP0 = com\x0d\x0adelay(5)\x0d\x0alcden = 1\x0d\x0adelay(5)\x0d\x0alcden = 0//别忘了lcden拉低\x0d\x0a}\x0d\x0avoid write_date(uchar date)\x0d\x0a{\x0d\x0alcden = 0\x0d\x0alcdrs = 1\x0d\x0alcdwr = 0\x0d\x0aP0 = date\x0d\x0adelay(5)\x0d\x0alcden = 1\x0d\x0adelay(5)\x0d\x0alcden = 0\x0d\x0a}\x0d\x0avoid lcd_init(void)\x0d\x0a{\x0d\x0alcden = 0\x0d\x0alcdrs = 0\x0d\x0alcdwr = 0\x0d\x0adelay(5)\x0d\x0awrite_com(0x38)\x0d\x0awrite_com(0x0c)\x0d\x0awrite_com(0x06)\x0d\x0awrite_com(0x01)\x0d\x0a}\x0d\x0a/*****************main()************************/\x0d\x0avoid main(void)\x0d\x0a{\x0d\x0auchar count=0\x0d\x0aIR = 1\x0d\x0alcd_init()\x0d\x0awrite_com(0x80)\x0d\x0awhile(table1[count]!='\0')\x0d\x0a{\x0d\x0awrite_date(table1[count])\x0d\x0acount++\x0d\x0adelay(5)\x0d\x0a}\x0d\x0acount = 0\x0d\x0awrite_com(0x80+0x40)\x0d\x0awhile(table2[count]!='\0')\x0d\x0a{\x0d\x0awrite_date(table2[count])\x0d\x0acount++\x0d\x0adelay(5)\x0d\x0a}\x0d\x0a\x0d\x0aIE = 0x81//开中断\x0d\x0aTCON = 0x01//脉冲负边沿触发\x0d\x0awhile(1)\x0d\x0a\x0d\x0a}\x0d\x0a/*********************红外中断**************************/\x0d\x0avoid IR_time() interrupt 0 \x0d\x0a{\x0d\x0auchar i,j,TimeNum=0//TimeNum用来计IR高电平次数 从而判断是0还是1\x0d\x0aEX0 = 0//关闭中断\x0d\x0adelayms(5)\x0d\x0aif(1 == IR)\x0d\x0a{\x0d\x0aEX0 = 1\x0d\x0areturn\x0d\x0a}\x0d\x0awhile(!IR) //跳过9ms前导低电平\x0d\x0adelayms(1)\x0d\x0afor(i=0i{\x0d\x0afor(j=0j{\x0d\x0awhile(IR) //跳过4.5ms的前导高电平\x0d\x0adelayms(1)\x0d\x0awhile(!IR) //跳过0.56ms的低电平\x0d\x0adelayms(1)\x0d\x0a\x0d\x0awhile(IR) \x0d\x0a{\x0d\x0aTimeNum++//计时高电平时间从而判断读取的是0还是1\x0d\x0adelayms(1)\x0d\x0a}\x0d\x0aif(TimeNum>=30)//按键按下时间过长 跳过\x0d\x0a{\x0d\x0aEX0 = 1\x0d\x0areturn\x0d\x0a}\x0d\x0aIRCOM[i] = IRCOM[i]>>1\x0d\x0aif(TimeNum >= 8) //8*0.14ms 这时读取的是1;\x0d\x0a{\x0d\x0aIRCOM[i] = IRCOM[i]|0x80\x0d\x0a}\x0d\x0aTimeNum = 0\x0d\x0a}\x0d\x0a}\x0d\x0aif(IRCOM[2]!=~IRCOM[3])//判断八位数据和八位数据反码是否相等\x0d\x0a{\x0d\x0aEX0 = 1\x0d\x0areturn\x0d\x0a}\x0d\x0aIRCOM[4] = IRCOM[2]&0x0f//取低四位\x0d\x0aIRCOM[5] = IRCOM[2]>>4//IRCOM[5]取IRCOM[2]高四位\x0d\x0aif(IRCOM[4] >9) //转换成字符\x0d\x0a{\x0d\x0aIRCOM[4] = IRCOM[4] + 0x37\x0d\x0a}\x0d\x0aelse\x0d\x0aIRCOM[4] = IRCOM[4] + 0x30\x0d\x0aif(IRCOM[5] >9)\x0d\x0a{\x0d\x0aIRCOM[5] = IRCOM[5] + 0x37\x0d\x0a}\x0d\x0aelse\x0d\x0aIRCOM[5] = IRCOM[5] + 0x30\x0d\x0adelay(5)\x0d\x0awrite_com(0x80 + 0x40 + 5)\x0d\x0awrite_date(IRCOM[5])\x0d\x0awrite_date(IRCOM[4])\x0d\x0aEX0 = 1//重新开启外部中断\x0d\x0a}

给你一个PIC写的接收红外遥控器的程序。

//******************************************************

//mcu: PIC16F883

//author:

//data:

//ver: 1.0

//********************************************************

#include <pic.h>

#include <pic16f887.h>

#include "main.h"

// 函数声明部份

void interrupt IRQ_TEST(void)

void fun_intset(void)

void set_port(void)

void fun_timerset(void)

void delay_10us(void)

void delay_130us(void)

void test_remote(void)

// 主函数

void main()

{

set_port()

fun_timerset()

fun_intset()

delay_10ms()

ram_ini()

GIE=1

while(1)

{

asm("clrwd")

test_remote()

}

}

//端口I/O定义子程序

void set_port()

{

ANSEL =0X00//porta io port

ANSELH=0X00 //portb io port

//TRISX BIT=1, PORTX AS INPUT

TRISA = 0x0F//RA0-RA3 INPUT ,RA4-RA5 OUTPUT

TRISB = 0x07//RB0 PASS0, RB1-RB2 INPUT ,RB3-RB6 OUTPUT

TRISC = 0x0F

// TRISC = 0x03//RC0-RC1 INPUT,RC5-RC6 OUTPUT , RC3 RC4 EEPROM SCL SDA

PORTC=0

PORTA=0XFF

// WPUB=0XFF

PORTB=0X07

}

//中断子程序

void interrupt IRQ_TEST(void)

{

if(T0IF) //Timer0中断服务子程序

{

TMR0=0xce

T0IF=0

timer_100us++ //100us

}

if(INTF==1)

{

INTF=0

timer_rec=timer_100us

timer_100us=0

flag_rec_remote=1

}

}

//定时器0初始化设置子程序

void fun_timerset()

{

//Timer0初始化设置

PSA=0//Timer0 使用预分频器

//Timer0选择分频率为1:2

PS0=0PS1=0PS2=0

//内部时钟定时方式,定时时间:200uS,误差:0uS

T0CS=0

// TMR0=0x9b

TMR0=0xce//100us

}

/*

//定时器2初始化设置子程序

void fun_timer2set()

{

//Timer2初始化设置

//timer2使用预分频率1:1

T2CKPS0=0T2CKPS1=0

//timer2使用后分频率1:1

TOUTPS0=0

TOUTPS1=0

TOUTPS2=0

TOUTPS3=0

//定时器2定时时间为:200uS,误差:0uS

TMR2=0x38

TMR2ON=1

}

*/

//中断允许设置子程序

void fun_intset()

{

T0IE=1//Tiemr0中断允许

INTEDG=0//RB0 FALLAGE INTERRUPT

INTE=1

INTF=0

}

void ram_ini(void)

{

}

//------------------------------------------------------------

//*****************************************************************************

void delay_10us(void)

{

NOP

NOP

NOP

NOP

NOP

NOP

}

void delay_130us(void)

{

uchar i

for(i=0i<13i++)

{

NOP

NOP

NOP

}

}

void delay_10ms(void)

{

unsigned int i

for(i=0i<1000i++)

{

NOP

NOP

NOP

NOP

NOP

}

}

void test_remote(void)

{

uchar rec_ok,i

if(flag_rec_remote==1)

{

flag_rec_remote=0

// remote_buf[rec_byte]=timer_rec //test use

// rec_byte++//test use

// return //test use

if(flag_rec_head==0)

{

if(timer_rec>=90&&timer_rec<=140) //135

{

flag_rec_head=1

rec_byte=0

rec_bit=0

rec_buf=0

return

}

}

else

{

if(timer_rec>=8&&timer_rec<=12) //11.2

{

rec_buf=(rec_buf>>1)

rec_buf=rec_buf&0x7f

}

else if(timer_rec>=18&&timer_rec<=22) //22

{

rec_buf=(rec_buf>>1)

rec_buf=rec_buf|0x80

}

else if(timer_rec>=90&&timer_rec<=140)

{

flag_rec_head=1

rec_byte=0

rec_bit=0

rec_buf=0

return

}

else

{

flag_rec_head=0

rec_byte=0

rec_bit=0

rec_buf=0

return

}

}

if(flag_rec_head==1)

{

rec_bit++

if(rec_bit==8)

{

remote_buf[rec_byte]=rec_buf

rec_byte++

rec_bit=0

if(rec_byte==4)

{

NOP

NOP

NOP

NOP

rec_byte=0

rec_bit=0

rec_buf=0

flag_rec_head=0

}

}

}

}

}

这是采用STC12C5A60S2单片机的红外解码程序及其说明。

采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的"0";

以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的"1

上述"0"和"1"组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,

达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射

遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电器设备,

防止不同机种遥控码互相干扰。该芯片的用户识别码固定为十六进制01H

后16位为8位 *** 作码(功能码)及其反码。

当一个键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码由一个起始码(9ms),

一个结果码(4.5ms),低8位地址码(9ms~18ms),高8位地址码(9ms~18ms),8位数据码(9ms~18ms)

和这8位数据的反码(9ms~18ms)组成。如果键按下超过108ms仍未松开,

接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2.5ms)组成。

解码的关键是如何识别"0"和"1",接收端而言,"0"是0.56ms的高+0.56ms的低。"1"是1.68ms的高+0.56ms的低。

所以可以根据高电平的宽度区别"0"和"1"。当高电平出现时开始延时,0.56ms以后,若读到的电平为低,

说明该位为"0",反之则为"1",为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否则如果该位为"0",

读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右均可。

为了共用引导部分延时程序,这里用0.9ms延时。

-------------红外解码程序---------------------------

EXINT0:

PUSH ACC

PUSH PSW

PUSH 1

PUSH 2

PUSH 6

CLR EA 暂时关闭中断请求

MOV R6,#10

EXINT10:

LCALL DELAY09MS 调用900us延时子程序

JB IRIN,INTOUT1 判断P3.2是否有高电平,如果有就退出解码程序

DJNZ R6,EXINT10 循环10次,检测在900微妙中是否存在高电平。以上完成对遥控信号的9000微秒的初始低电平信号的识别。

JNB IRIN,$ 等待高电平避开9毫秒低电平引导脉冲

LCALL DELAY45MS 延时4.5毫秒

-------------接受32位代码--------------------------

MOVR1,#IRUSERL

MOVR2,#04H

EXINT101:

MOVR6,#08H 每组数据位8位

EXINT102:

JNB IRIN,$ 等待地址码第一组数据的高电平信号

LCALL DELAY09MS 高电平开始后延时判断信号此时的高/低状态

MOVC,IRIN 将P3.2引脚此时的电平状态0或1存入C中

JNCINT1OUT 如果为0跳出

LCALL DELAY1MS

INT1OUT:

MOVA,@R1

RRCA 将C中的数据0/1移入A中最低位

MOV@R1,A 将A中的数据暂存在R1

DJNZ R6,EXINT102 接受完8位代码

INCR1

DJNZ R2,EXINT101 接受完4组32位代码

--------------数据码比较-------------------------------

MOVA,IRDATAL

LCALL SENDRXDAT

MOVA,IRDATAL

CPLA

CJNE A,IRDATAH,INTOUT1 判断数码正误,不等退出

MOVIR_DAT,IRDATAL 相等则保存正确数据

MOV A,IR_DAT

LCALL SENDRXDAT

SETB IRBIT

INTOUT1:

LCALL DELAY45MS

SETB EA 允许中断

POP 6

POP 2

POP 1

POPPSW

POPACC

RETI

*****************11.0592*900=9953******************

DELAY09MS: 6

PUSH 4 4

PUSH 3 4

MOV R4,#20 2

DLY900:

MOV R3,#122 2

DJNZ R3,$ 4

DJNZ R4,DLY900 4

MOV R4,#11 2

DJNZ R4,$ 4

POP 3 3

POP 4 3

RET 4

TOTAL=9952

*****************11.0592*560=6193******************

DELAY056: 6

PUSH 4 4

PUSH 3 4

MOV R4,#12 2

DLY5600:

MOV R3,#122 2

DJNZ R3,$ 4

DJNZ R4,DLY5600 4

MOV R4,#71 2

DJNZ R4,$ 4

POP 3 3

POP 4 3

RET 4

TOTAL=6194

*****************11.0592*4500=49766****************

DELAY45MS: 6

PUSH 4 4

PUSH 3 4

MOV R4,#52 2

DLY45:

MOV R3,#236 2

DJNZ R3,$ 4

DJNZ R4,DLY45 4

MOV R4,#85 2

DJNZ R4,$ 4

POP 3 3

POP 4 3

RET 4

TOTAL=49768

*****************11.0592*1000=11059****************

DELAY1MS: 6

PUSH 4 4

PUSH 3 4

MOV R4,#20 2

DLY1MS:

MOV R3,#136 2

DJNZ R3,$ 4

DJNZ R4,DLY1MS 4

MOV R4,#8 2

DJNZ R4,$ 4

POP 3 3

POP 4 3

RET 4

TOTAL=11060

***************************************************

DELAY100US: 6

PUSH 4 4

MOV R4,#140 2

DJNZ R4,$ 4

MOV R4,#131 2

DJNZ R4,$ 4

POP 4 3

RET 4

TOTAL=1105

***************************************************


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11079702.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存