求一个程序,单片机接收红外传感器发出的信号,然后再控制步进电机动作!

求一个程序,单片机接收红外传感器发出的信号,然后再控制步进电机动作!,第1张

我有红外遥控器的程序。

你自己可以改改:

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

名称:遥控器红外解码液晶显示

日期: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判断等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10060827.html

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

发表评论

登录后才能评论

评论列表(0条)

保存