求一个程序,单片机接收红外传感器发出的信号,然后再控制步进电机动作!
#include
#define uchar unsigned char
#define uint unsigned int
sbit KEY1 = P3^2; //步进电机逆时针方向转
sbit KEY2 = P3^3; //步进电机顺时针方向转
sbit KEY3 = P3^4; //步进电机调速
uchar step = 0;
bit AB_flag = 0;
unsigned char code A_Rotation[8]={0x08,0x18,0x10,0x30,0x20,0x60,0x40,0x48}; //顺时针转表格
unsigned char code B_Rotation[8]={0x48,0x40,0x60,0x20,0x30,0x10,0x18,0x08}; //逆时针转表格
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay(uint i)
{
uchar x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
void KEY(void)
{
if(KEY1 == 0) //按P3.2,实现步进电机的逆时针转动
{
Delay(15);
if(KEY1 == 0)
{
while(1)
{
if(KEY1 == 1)
{
Delay(15);
if(KEY1 == 1)
{
AB_flag = 0;
break;
}
}
}
}
}
if(KEY2 == 0) //按P3.3,实现步进电机的顺时针转动
{
Delay(15);
if(KEY2 == 0)
{
while(1)
{
if(KEY2 == 1)
{
Delay(15);
if(KEY2 == 1)
{
AB_flag = 1;
break;
}
}
}
}
}
if(KEY3 == 0) //按P3.4,实现步进电机的调速
{
Delay(15);
if(KEY3 == 0)
{
while(1)
{
if(KEY3 == 1)
{
Delay(15);
if(KEY3 == 1)
{
step++;
if(step == 3)
{
step = 0;
}
break;
}
}
}
}
}
}
main()
{
uchar i;
while(1)
{
KEY(); //按键处理函数
for(i=0;i<8;i++) //因为有8路的控制时序
{
if(AB_flag == 0)
{
P1 = A_Rotation[i]; //逆时针转动
}
else
{
P1 = B_Rotation[i]; //顺时针转动
}
Delay(2+step); //改变这个参数可以调整电机转速
}
}
}
压力传感器有模拟输出和数字输出的,如果是数字输出的话可以直接接到单片机上,模拟输出的需要转化为数字信号,然后再接到单片机上,然后再把程序写进单片机,再用单片机输出信号给步进电机控制器控制步进电机!
我有红外遥控器的程序。你自己可以改改:
/*-----------------------------------------------
名称:遥控器红外解码液晶显示
日期:2009.5
修改:无
内容:
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include<intrins.h>
#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+4.5ms
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 (P3.2)
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();
}
}
}
单片机中红外传感器是如何测距的
呵呵,红外光,传播起来是光速,1us传播300m。利用波速来计算距离,测量出几个纳秒的时间差,使用单片机则是不可能的。利用电磁波来测距、测速,是利用了变频、差频的原理,前端的电路和器件,都是使用模拟电路中高频电子线路的理论和电路器件。单片机之类的数字电路根本跟不上这个速度,只能做后期的低速...
51单片机智能小车制作,求通俗易懂的讲解
系统的单片机程序:include"reg52.h"definedet_Dist2.55\/\/ 单个脉冲对应的小车行走距离,其值为车轮周长 \/4#defineRD9\/\/ 小车对角轴长度。definePI3.1415926 defineANG_9090 defineANG_90_T102 defineANG_180189\/ 全局变量定义区。\/sbitP10=P1^0;\/\/ 控制继电器的开闭sbitP11=P1^1;\/\/ 控制金属...
红外传感器得到的信息如何传给电脑
简单的思路是这样的,因为你传感器出来的是模拟信号,而计算机只能处理数字信号,所以先把模拟转换成数字信号,这叫模数转换(A\/D)。然后利用单片机的各种接口,把数据传送到电脑上面去。例如串口,单片机和电脑都带串口(如果电脑不带串口的可以利用USB转串口模块)。然后再是电脑的应用程序对数据进行处理。
红外对管在proteus中怎么找
1、打开Proteus软件,点击左上角的“PickDevice”按钮。2、在“PickDevice”对话框中,输入“infraredsensor”或“红外传感器”,然后点击“Search”按钮。3、在搜索结果中找到“红外接收器”或“infraredreceiver”,然后点击“OK”按钮,将元器件添加到工作区中。4、将红外对管的OUT引脚连接到单片机的IO口...
热释电红外传感器该如何与51单片机链接?
在设计电路时,热释电红外传感器与51单片机的连接方式取决于传感器的输出接口类型。通常,传感器可能配备数字输出接口。通过单片机的读取协议,可以获取传感器数据。为了确保连接的正确性,首先需了解传感器输出的具体方式。可能包括普通I\/O口输出,也可能采用其他接口类型。数据手册详细描述了传感器的接口配置,...
关于单片机与红外传感器模块连接问题
调节一下控制灵敏度的电阻试试。另外需要注意的是屋子里最好不要开空调,开空调时屋子里的冷热空气扰动比较剧烈,会让红外模块一直处于触发状态。也不要让阳光直射到某个窗户或者某面墙。这些都会对红外模块造成干扰。
在测量距离内,红外传感器是一直在发射和接收的吗?还是不是连续的,而...
如果是传感器头,那么只要通电,就一直在发射接收的。然后对于红外探测传感器,一般带有单片机处理单元,并且很多都是电池提供电源的,这种一般会设置脉冲形式,间歇性发射和接受,以及定时通讯校准。
光幕传感器工作原理
1. 图示展现了一个安全光幕系统,其工作原理是通过一系列红外发射管和接收管的配合。2. 在这个系统中,发射管和接收管以等间隔安装,且一一对应,确保每束发出的红外光都能被对应的接收管捕捉。3. 当没有障碍物存在于发射管和接收管之间的直线上时,红外光能顺利通过,此时接收管内部电路输出低电平。
基于51单片机的转速测量设计,程序编写!电路仿真图
测量转速,使用光电传感器,被测电机带动纸片旋转,我们在纸片上开了10小孔,电机每旋转一周就会产生10个脉冲,产生12个脉冲,要求将转速值(转\/分)显示在数码管上。实验程序如下:include <REG52.H> define uchar unsigned char define uint unsigned int define ulong unsigned long define LED_DAT P1...
在被动测速系统中,单片机(52\/51)是如何完成速度计算的?单片机高手近来...
所以,速度就是距离除以用时了。比如,距离是10米。用时为10秒。那么,速度就是10米\/10秒=1米每秒。在程序中,进行数学运算,一米一秒,那么1分钟就是60米。一小时就是3600米。最后,就会得到速度值为3.6千米每小时了。所以,程序的运行就是这样的。接收到第一个传感器的信号后,开始计时。接收到...