我有红外遥控器的程序。
你自己可以改改:
/-----------------------------------------------
名称:遥控器红外解码液晶显示
日期:20095
修改:无
内容:
------------------------------------------------/
#include<reg52h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdioh>
#include<intrinsh>
#define TURE 1
#define FALSE 0
sbit IR=P3^2; //红外接口标志
sbit RS = P2^4;//Pin4
sbit RW = P2^5;//Pin5
sbit E = P2^6;//Pin6
#define Data P0//数据端口
unsigned int hour,minute,second,count;char code Tab[16]="0123456789ABCDEF";
char data TimeNum[]=" ";char data Test1[]=" ";
//
/ 变量声明 /
//
unsigned char irtime;//红外用全局变量
bit irpro_ok,irok;
unsigned char IRcord[4]; //处理后的红外码,分别是 客户码,客户码,数据码,数据码反码
unsigned char irdata[33]; //33个高低电平的时间数据
//
/ 函数声明 /
//
void Ir_work(void);
void Ircordpro(void);
void ShowString (unsigned char line,char ptr);
//
/ 定时器0中断服务函数 /
//
void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数
{
irtime++; //用于计数2个下降沿之间的时间
}
//
/ 外部中断0函数 /
//
void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+45ms
i=0;
irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{irtime=0;startflag=1;}
}
//
/ 定时器0初始化 /
//
void TIM0init(void)//定时器0初始化
{
TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1; //开中断
TR0=1;
}
//
/ 外部中断初始化 /
//
void EX0init(void)
{
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P32)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
//
/ 红外键值处理 /
//
void Ir_work(void) //红外键值散转程序
{
TimeNum[5] = Tab[IRcord[0]/16]; //处理客户码并显示
TimeNum[6] = Tab[IRcord[0]%16];
TimeNum[8] = Tab[IRcord[1]/16]; //处理客户码并显示
TimeNum[9] = Tab[IRcord[1]%16];
TimeNum[11] = Tab[IRcord[2]/16]; //处理数据码并显示
TimeNum[12] = Tab[IRcord[2]%16];
TimeNum[14] = Tab[IRcord[3]/16]; //处理数据反码并显示
TimeNum[15] = Tab[IRcord[3]%16];
ShowString(1,TimeNum);//显示处理过后的码值
irpro_ok=0; //处理完成后清楚标志位
}
//
/ 红外解码函数处理 /
//
void Ircordpro(void)//红外码值处理函数
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
{
value=value|0x80;
}
else
{
value=value;
}
if(j<8)
{
value=value>>1;
}
k++;
}
IRcord[i]=value;
value=0;
} irpro_ok=1;//处理完毕标志位置1
}
//
/ 微秒延时函数 /
//
void DelayUs(unsigned char us)//delay us
{
unsigned char uscnt;
uscnt=us>>1;/ Crystal frequency in 12MHz/
while(--uscnt);
}
//
/ 毫秒函数声明 /
//
void DelayMs(unsigned char ms)//delay Ms
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
//
/ 写入命令函数 /
//
void WriteCommand(unsigned char c)
{
DelayMs(5);// *** 作前短暂延时,保证信号稳定
E=0;
RS=0;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
}
//
/ 写入数据函数 /
//
void WriteData(unsigned char c)
{
DelayMs(5); // *** 作前短暂延时,保证信号稳定
E=0;
RS=1;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
RS=0;
}
//
/ 写入字节函数 /
//
void ShowChar(unsigned char pos,unsigned char c)
{
unsigned char p;
if (pos>=0x10)
p=pos+0xb0; //是第二行则命令代码高4位为0xc
else
p=pos+0x80; //是第二行则命令代码高4位为0x8
WriteCommand (p);//写命令
WriteData (c); //写数据
}
//
/ 写入字符串函数 /
//
void ShowString (unsigned char line,char ptr)
{
unsigned char l,i;
l=line<<4;
for (i=0;i<16;i++)
ShowChar (l++,(ptr+i));//循环显示16个字符
}
//
/ 初始化函数 /
//
void InitLcd()
{
DelayMs(15);
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x06); //显示光标移动位置
WriteCommand(0x0c); //显示开及光标设置
WriteCommand(0x01); //显示清屏
}
//
/ 主函数 /
//
void main(void)
{
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
InitLcd(); //初始化液晶 DelayMs(15);
sprintf(Test1," haixiang MCU "); //显示第一行固定信息 ShowString(0,Test1);
sprintf(TimeNum,"Code ");//显示第二行固定信息 ShowString(1,TimeNum);
while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ir_work();
}
}
}
给你一段430单片机遥控器解码的程序吧,也就是接收部分
毕竟世界太现实只能这么帮你
#ifndef _IR_
#define _IR_
char t0,t1,t2;
uchar IR;
void DelayIR()
{
uint i=130;
while(i--);
}
void init_port2(void)
{
P2DIR&=~BIT0;
P2SEL&=~BIT0;
P2IES|=BIT0;
P2IE|=BIT0;
}
#pragma vector=PORT2_VECTOR
__interrupt void PORT2_ISR(void)
{
char CounterIR;
P2IES&=~BIT0;
if(P2IFG&BIT0)
{
P2IFG&=~BIT0;
}
CounterIR=0;
while(!(P2IN&BIT0))
{
DelayIR();
CounterIR++;
}
if(CounterIR>85)
{
if(CounterIR<95)
{
t1++;
for(char k=0;k<17;k++)
{
CounterIR=0;
while((P2IN&BIT0)&&(CounterIR<50))
{
DelayIR();
CounterIR++;
}
CounterIR=0;
while((!(P2IN&BIT0))&&(CounterIR<10))
{
DelayIR();
CounterIR++;
}
}
for(char j=0;j<8;j++)
{
CounterIR=0;
while((P2IN&BIT0)&&(CounterIR<25))
{
DelayIR();
CounterIR++;
}
IR<<=1;
if(CounterIR>11)
IR|=BIT0;
CounterIR=0;
while((!(P2IN&BIT0))&&(CounterIR<10))
{
DelayIR();
CounterIR++;
}
}
if((IR!=0xff)&&(IR!=0x00))
{
if(!(flag&dataflag))
{
if(IR==0x22)
{
flag|=runflag;
}
else
{
Tar[0]=Tar[1];
Tar[1]=Tar[2];
Tar[2]=Tar[3];
Tar[3]=Tar[4];
switch (IR)
{
//case 0x22 : flag|=runflag;break;
case 0x68 : Tar[4]=0;flag|=dataflag;break;
case 0x30 : Tar[4]=1;flag|=dataflag;break;
case 0x18 : Tar[4]=2;flag|=dataflag;t2++;break;
case 0x7a : Tar[4]=3;flag|=dataflag;break;
case 0x10 : Tar[4]=4;flag|=dataflag;break;
case 0x38 : Tar[4]=5;flag|=dataflag;break;
case 0x5a : Tar[4]=6;flag|=dataflag;break;
case 0x42 : Tar[4]=7;flag|=dataflag;break;
case 0x4a : Tar[4]=8;flag|=dataflag;break;
case 0x52 : Tar[4]=9;flag|=dataflag;break;
default : break;
}
}
}
}
IR=0;
}
}
for(int m=0;m<250;m++)
DelayIR();
P2IES|=BIT0;
}
#endif
你的思路是正确的。
不过你贴的程序看不到引导码的处理过程,或者说没法知道startflag怎么置1的。最好也贴出来。
如果你这个接收程序的中断处理部分完整的话,可以确定所用的单片机不具有修改触发边沿的功能。只能根据第一个下降沿(引导码)和第一个用户码之间的时间来处理(减去0电平的时间)。
从程序上看,
if(startflag)
只是判断可能是起始标记。
if(irtime>32&&irtime<63) //引导码 8-16ms间
bitnum=0;
这个判断是否为引导码。如果是,则将数组键置0,准备开始存储数据。即:
irdata[bitnum]=irtime;
irtime=0;//这个就不说了
bitnum++;//这个本来也不该说的,不过结合前面的引导码判断,就有问题了:
1、如果遥控器发射过程中红外线被挡住,irtime会很长···还需要继续存储么?
2、如果接收被干扰,会插入高电平,irtime 不确定···
3·······
简单说,判断过于简单,没法实用的。
话说,你自己有能力写个好的,为嘛还参考别人的?
单片机红外电视遥控器C51程序代码单片机程序
//
//名称:单片机红外电视遥控器C51程序代码()
/--------------------------------------------------------------
描述:
一般红外电视遥控器的输出都是用编码后串行数据对38~40kHz的方波进行
脉冲幅度调制而产生的当发射器按键按下后,即有遥控码发出,所按的键
不同遥控编码也不同。这种遥控码具有以下特征:
采用脉宽调制的串行码,以脉宽为0565ms、间隔056ms、周期为1125ms的
组合表示二进制的“0”;以脉宽为0565ms、间隔1685ms、周期为225ms
的组合表示二进制的“1”。上述“0”和“1”组成的32位二进制码经38kHz
的载频进行二次调制,然后再通过红外发射二极管产生红外线向空间发射。
一般电视遥控器的遥控编码是连续的32位二进制码组,其中前16位为用户识
别码,能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。后16位
为8位的 *** 作码和8位的 *** 作反码,用于核对数据是否接收准确。
根据红外编码的格式,发送数据前需要先发送9ms的起始码和45ms的结果码。
接收方一般使用TL0038一体化红外线接收器进行接收解码,当TL0038接收到
38kHz红外信号时,输出端输出低电平,否则为高电平。
所以红外遥控器发送红外信号时,参考上面遥控串行数据编码波形图,在低
电平处发送38kHz红外信号,高电平处则不发送红外信号。
----------------------------------------------------------------/
//编辑:
//日期:
//
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
#include <reg51h> //包括一个51标准内核的头文件
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)
else
P3_4 = OP;
}
//
void SendIRdata(char p_irdata)
{
int i;
char irdata=p_irdata;
//发送9ms的起始码
endcount=223;
flag=1;
count=0;
do{}while(count)
//发送45ms的结果码
endcount=117;
flag=0;
count=0;
do{}while(count)
//----------------------发送十六位地址的前八位-------------------
irdata=iraddr1;
for(i=0;i<8;i++)
{
//先发送056ms的38KHZ红外波
endcount=10; //(即编码中056ms的低电平)
flag=1;
count=0;
do{}while(count)
//停止发送红外信号(即编码中的高电平)
if(irdata-(irdata/2)2) //判断二进制数个位为1还是0
{ endcount=41; //1为宽的高电平
}
else
{ endcount=15; //0为窄的高电平
}
flag=0;
count=0;
do{}while(count)
irdata=irdata>>1;
}
//-----------------------发送十六位地址的后八位-------------------
irdata=iraddr2;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count)
if(irdata-(irdata/2)2)
else
flag=0;
count=0;
do{}while(count)
irdata=irdata>>1;
}
//-----------------------发送八位数据------------------------------
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count)
if(irdata-(irdata/2)2)
else
flag=0;
count=0;
do{}while(count)
irdata=irdata>>1;
}
//-------------------------发送八位数据的反码----------------------
irdata=~p_irdata;
for(i=0;i<8;i++)
{
endcount=10;
flag=1;
count=0;
do{}while(count)
if(irdata-(irdata/2)2)
else
flag=0;
count=0;
do{}while(count)
irdata=irdata>>1;
}
endcount=10;
flag=1;
count=0;
do{}while(count) flag=0;
}
//
void delay()
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++) ;
}
}
以上就是关于求一个程序,单片机接收红外传感器发出的信号,然后再控制步进电机动作!全部的内容,包括:求一个程序,单片机接收红外传感器发出的信号,然后再控制步进电机动作!、用C语言编写一个红外发送和接收的程序、单片机红外接收程序的中断函数为什么先要加个if判断等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)