红外线遥控器解码C语言程序代码 SM0038接受头

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红外线遥控器解码C语言程序代码 SM0038接受头相关的知识,希望对你有一定的参考价值。

谁有红外线遥控器解码程序代码 SM0038的接受头,最好能把详细的代码和技术文档发给我,QQ:446854846

//////////////////////////////////////
//晶振频率为6MHz 一个机器周期2us //
//实现按键地址码、指令码的数码管显示//
//2010-06-01 //
//////////////////////////////////////
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
bit overflag,dataover;//开始接收数据,数据处理完毕

uchar timedata;//定时器0溢出次数
uchar chubus[33];//33Byte数据 timedata组成的数组
uchar jieguos[4];//地址码,地址反码,数据码,数据反码;

void initial()//初始化

IT0=1;EX0=1;//负边沿触发

TMOD=0x01;ET0=1;TR0=1;//模式1,十六位定时器
TH0=0xff;TL0=0x06;//0.5ms溢出

EA=1; //开总中断


void time0() interrupt 1//定时器0中断
TH0=0xff;TL0=0x06;
timedata++;


void ex0() interrupt 0//外部中断0,接收数据

static bit startflag;//开始接收
static uchar i;

if(startflag)

if(timedata<32&&timedata>=16) i=0;
chubus[i]=timedata;
timedata=0;
i++;
if(i==33)overflag=1;i=0;


else

startflag=1;
timedata=0;



void chulidata()

uchar chubu;//初步数据
uchar jieguo;//结果数据
uchar x,y,z=1;
for(x=0;x<4;x++)//处理四组数据

for(y=1;y<=8;y++)//处理一组数据8Byte

chubu=chubus[z];
jieguo=jieguo>>1;
if(chubu>3) jieguo=jieguo|0x80;//大于1.5mS为1
z++;

jieguos[x]=jieguo;
jieguo=0;

dataover=1;



void delay(uint z)

uint x ,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);


void display()

uchar gao,gao1;
uchar di,di1;

uchar code table[]=
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71;
gao1=table[jieguos[0]/16];
di1=table[jieguos[0]%16];
gao=table[jieguos[2]/16];
di=table[jieguos[2]%16];

dula=1;
P0=gao1;
dula=0;
P0=0xff;
wela=1;
P0=0x7e;
wela=0;
delay(2);

dula=1;
P0=di1;
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(2);//地址码

dula=1;
P0=gao;
dula=0;
P0=0xff;
wela=1;
P0=0x77;
wela=0;
delay(2);

dula=1;
P0=di;
dula=0;
P0=0xff;
wela=1;
P0=0x6f;
wela=0;
delay(2);//指令码



void main()

initial();//初始化
while(1)


if(overflag)//数据接收完毕

chulidata();//处理数据,完成标志dataover
overflag=0;

if(dataover)

display();//数码管显示


参考技术A #include <iom16v.h>
#include <macros.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
/*------------------------------显示-----------------------------------*/
#define LED_DATA PORTB
const uchar tab[]=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;
/*
0 1 2 3 4 5 6 7 8 9 A B C D E F
*/
void delay(void)
uint i;
for(i=0;i<2000;i++);

void dis_int(uint dis_data)
//四位共阴数码管,十六进制显示
LED_DATA=tab[(uchar)((dis_data&0xf000)>>12)]; //显示千位
PORTD=0xf7;
delay(); //延时

LED_DATA=tab[(uchar)((dis_data&0x0f00)>>8)]; //显示百位
PORTD=0xfb;
delay(); //延时

LED_DATA=tab[(uchar)(dis_data&0x00f0)>>4]; //显示十位
PORTD=0xfd;
delay(); //延时

LED_DATA=tab[(uchar)dis_data&0x000f]; //显示个位
PORTD=0xfe;
delay(); //延时

void port_init(void)

PORTA = 0xFF;
DDRA = 0x00;
PORTB = 0xFF;
DDRB = 0xFF;
PORTC = 0xFF;
DDRC = 0xFF;
PORTD = 0xFF;
DDRD = 0x0F;

void timer1_init(void)

TCCR1B = 0x00; //stop
TCNT1H = 0x00; //setup
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x08;
TCCR1A = 0x00;
/*一体化接收头的DATA引脚接到ATmega16的PD6(ICP1)引脚,采用上升沿捕捉的方法解码*/
/*晶振为6M,无分频,用8M太大(分频则太小)*/
TCCR1B = 0x41; //start Timer

uint arr[16];//保存捕捉值
uchar times;//记录捕捉次数
uchar index;//数组索引
uchar ir_code;//红外遥控键码
uchar OK_flag;//解码完毕标志
/*------------------------------------------------------------------------------
模块名称:PD6(ICP1)引脚上升沿捕捉中断程序
影响: 将捕捉值保存在arr[16]中
___ ___
| | | |
___| |_________| |__________
|<-----t----->|
DEC HEX
t=9ms 计数值=54000 0xD2F0
t=4.5ms 计数值=27000 0x6978
t=2.25ms 计数值=13500 0x34BC
t=1.125ms 计数值=6750 0x1A5E

------------------------------------------------------------------------------*/
#pragma interrupt_handler timer1_capt_isr:6
void timer1_capt_isr(void)

uint value;
value=ICR1L;
//CLI();
value|=(uint)(ICR1H << 8);
TCNT1H = 0x00;
TCNT1L = 0x00;
times++;
if(times>18&×<35)
//从第19个上升沿开始保存,直到第34个,短按时共有36个上升沿
arr[index]=value;
index++;

else if(times>=35)
//第35个上升沿到来时,解码完毕
times=0;
index=0;
OK_flag=1;

//SEI();

/*------------------------------解码程序----------------------------------------
结果:得到uchar型的键码ir_code,如果解码出错,则ir_code=0xff
-----------------------------------------------------------------------------*/
void get_code(void)
uchar i,dat,/*键码*/_dat;/*键码反码*/
uint temp=0;
for(i=0;i<16;i++)
if(arr[i]<7000)
//“0”
temp<<=1;

if(arr[i]>13000)
//“1”
temp<<=1;
temp|=1;


_dat=(uchar)(temp&0x00ff);/*键码*/
dat=(uchar)((temp>>8)&0x00ff);/*键码反码*/
/*“键码”与“键码反码相与,如果为0则解码正确*/
if((dat&_dat)==0)
ir_code=dat;

else
TCNT1H = 0x00;
TCNT1L = 0x00;
ir_code=0xff;//解码出错

times=0;
index=0;

void init_devices(void)

CLI();
port_init();
timer1_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x20;
SEI();

void main(void)
uchar i;
init_devices();

while(1)

if (OK_flag)
get_code();//解码
OK_flag=0;

for(i=0;i<200;i++)
dis_int(ir_code);//显示键码





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

楼主程序今测试了下:
主要有两点改动

用M64,T3,晶体7.3728 ,GCC 20040214

1
void timer1_init(void)

TCCR3B = 0x00; //stop
TCNT3H = 0x00; //setup
TCNT3L = 0x00;
ICR3H = 0x00;
ICR3L = 0x08;
TCCR3A = 0x00;
/*一体化接收头的DATA引脚接到ATmega64的PE7(ICP3)引脚,采用上升沿捕捉的方法解码*/
/*晶振为7.3728M,8分频*/
TCCR1B = 0xC2; //start Timer @@@@@@@@@@@@@@@@@@@@@@@@@@@改动

2

SING(XXXXXXXXXXXXXXX)

uint value;
value=ICR3L;
value|=(uint)(ICR3H << 8);
TCNT3H = 0x00;
TCNT3L = 0x00;
times++;
if(times>18)&&(times<35)
//从第19个上升沿开始保存,直到第34个,短按时共有36个上升沿
arr[index]=value;
index++;

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@改动
else if(times>35)@@@@@@@@@@@@@@@@@@@@@@@@@@@@@改动

//else if(times>=35) //用此语句时第二个键值的第一位被上一键值的第36个脉冲复用,

//第35个上升沿到来时,解码完毕
times=0;
index=0;
OK_flag=1;

以上是关于红外线遥控器解码C语言程序代码 SM0038接受头的主要内容,如果未能解决你的问题,请参考以下文章

4.4 51单片机-NEC红外线遥控器解码

ESP328.红外遥控实验(红外遥控解码库)

基于STC12系列单片机的通用红外遥控信号分析程序

结合STM32Arduino理解红外遥控编解码通信原理

IRM3800 红外遥控器解码 linux驱动

Linux驱动开发-编写NEC红外线协议解码驱动