【毕业设计】74-基于单片机的红外遥控步进电机控制系统设计与实现(详细说明书+PPT+原理图+仿真+源代码+全套资料)

基于单片机的红外控制系统的研究意义在于可以通过用红外控制的方式直接对物体进行控制,而不需要人为的操控。在工业的使用环境中,在许多复杂噪音多的环境中同样可以无干扰的进行远程操作。所以对红外控制系统的研究意义深远。
基于单片机的红外控制系统,主要由发射部分及红外遥控器;接收部分红外一体;步进电机控制模块;数码管显示模块这几部分组成。通过红外遥控器发射红外信号,红外一体接收红外信号,通过51单片机外部中断判断遥控器发射的信号,来判断执行控制步进电机和显示数码管。可通过红外遥控器控制步进电机的正反转以及转速,转速一共有十个档位。本论文从一开始构思系统实现的功能,然后设计硬件电路对元器件选型,利用AD软件绘制原理图然后绘制PCB。再对单片机程序进行编写,程序需要不停的调试,在调试过程中寻找最佳的控制点,最后利用PROTEUS软件仿真红外控制系统的功能。
在最后也对整个系统做了详细的测试记录,在不同的工作环境中的工作情况,对此红外控制系统放置在-5℃、常温(25℃)、40℃时的不同转速对应的反应时间、测试距离、噪音、电流、电压、功率、周期、力矩进行了测试分析,已达到此系统的可靠性。最后根据参数来对系统进行改进。最后达到自己想要的设计成果。
资料描述:
详细说明书 2.4737W字
介绍答辩PPT 19页
原理图工程文件
仿真工程文件
原理图截图
实物图照片
仿真截图

资料说明:Proteus仿真源文件、程序。各个功能模块文本资料、仿真截图、参考论文(2.4W字)、PPT。
备注:流程图:Visio绘制 ;仿真软件:Proteus;编程软件:Keil ;论文格式:标准模板。
。购买后不支持退货。
重要提示:本资料仅作为单片机设计类Proteus软件学习、Keil软件单片机编程学习、文章如何写作、答辩的教学资料使用。

目 录

前 言 1
第一章 绪论 2
第一节 研究背景 2
第二节 研究意义 3
第三节 研究现状 3
第四节 本文的主要研究内容 5
第五节 本章小结 6
第二章 基于单片机的红外控制系统原理 7
第一节 单片机的原理 7
一、单片机的简介 7
第二节 红外控制原理 8
一、红外遥控系统 9
二、遥控发射器及其编码 9
第三节 进步电机控制原理 11
一、步进电机的原理 11
二、步进电机的特点 14
三、电机驱动的选择 15
第四节 数码管显示原理 16
一、数码管的工作原理 16
二、数码管驱动方式 16
三、数码管编码 16
第五节 本章小结 17
第三章 系统硬件电路设计 18
第一节 系统硬件总电路构成 18
第二节 单片机最小系统模块设计 19
一、复位电路 19
二、晶振电路 20
三、单片机最小系统模块原理图 21
第三节 电源模块设计 21
第四节 红外控制模块设计 22
第五节 步进电机控制模块设计 23
第六节 数码管显示模块设计 24
第七节 本章小结 25
第四章 基于单片机的红外控制系统的软件设计 26
第一节 基于单片机的红外控制系统软件总设计 26
第二节 红外控制模块软件设计 27
第三节 步进电机控制模块软件设计 29
第四节 数码管显示模块软件设计 30
第五节 本章小结 31
第五章 基于单片机的红外控制系统的测试结果分析 32
第一节 仿真软件的介绍 32
一、功能 32
二、革命性的特点 32
第二节 仿真与验证 33
一、仿真总电路设计 33
二、仿真结果 34
三、结果分析 41
第三节 本章小结 41
第六章 总结与展望 42
致 谢 43
参考文献 44
附 录 46
一、英文原文 46
二、英文翻译 49
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

//数码管位 高位-----低位
//四个按键控制步进电机:正转,反转,加1,减1
//上电时电机启动,数码管上显示速度最小档1,加减档位均能通过数码管显示出来,电机采用单双八拍方式
//电机转速一共10档,通过按键调节转速 
//电机正转时最高位数码管显示0,反转时显示1  
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define led P0//数码管段选
#define haha P2
sbit s1 = P1^0;sbit s2 = P1^1;sbit s3 = P3^0;sbit s4 = P3^1;//按键定义,s1正转,s2反转,s3加1,s4减1
sbit wei3 = P2^3;sbit wei2 = P2^2;sbit wei1 = P2^1;sbit wei0 = P2^0;//数码管位选定义
sbit a = P2^7;sbit b = P2^6;sbit c = P2^5;sbit d = P2^4;//脉冲信号输入端定义

uchar code tab[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//共阳数码管驱动信号0---9,不显示
uchar code time_counter[10][2]={{0xda,0x1c},{0xde,0xe4},{0xe1,0xec},{0xe5,0xd4},{0xe9,0xbc},  //9.7 ----1ms
							    {0xed,0xa4},{0xf1,0x8c},{0xf5,0x74},{0xf9,0x5c},{0xfc,0x18}};
uchar code qudong[8]={0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90};	 
uchar num1 = 0;//控制取励磁信号变量						  
uchar num2 = 8;
int jishu;

//时间计算
#define Imax 14000    //此处为晶振为11.0592时的取值, 
#define Imin 8000    //如用其它频率的晶振时,
#define Inum1 1450    //要改变相应的取值。
#define Inum2 700 
#define Inum3 3000 
//解码变量
unsigned char Im[4]={0x00,0x00,0x00,0x00};

//全局变量
uchar f;
unsigned long m,Tc;
unsigned char IrOK;


char k=0;//加减档位控制,1为最小档
bit flag1 = 0,start=0,mode=0;//初始正转,正反转标志
uchar buf[4]={0,10,0,0};//数码管显示缓存,正转,不显示,不显示,显示0档位,高----低  
//================================定时器0/1初始化函数================================
void T0_T1_init()
{
	TMOD = 0x11;//定时器0/1均工作于方式1,16位计时方式
	TH0 =0;
	TL0 =0;//定时器0
   	TH1 = time_counter[k-1][0];
	TL1 = time_counter[k-1][1];//定时器1,定时10ms用于步进电机转速控制
	TR0 = 0;
	TR1 = 1;
	ET0 = 1;
	IT1=1;//下降沿有效
	EX1=1;//外部中断1开
	ET1= 1;//开定时器中断
	EA = 1;//开总中断
}
//================================ms级延时函数=======================================
void delay1m(uint x)
{
    uint i,j;
    for(i=0;i<x;i++)      //连数x次,约 x ms
  	   for(j=0;j<120;j++);   //数120 次,约1 ms
} 
void display()
{
	wei3=1;wei2=1;wei1=1;wei0=0;led = tab[buf[3]];delay1m(1);led=0xff;
    wei3=1;wei2=1;wei1=0;wei0=1;led = tab[buf[2]];delay1m(1);led=0xff;
    wei3=1;wei2=0;wei1=1;wei0=1;led = tab[buf[1]];delay1m(1);led=0xff;
	wei3=0;wei2=1;wei1=1;wei0=1;led = tab[buf[0]];delay1m(1);led=0xff;
}

//================================主函数=============================================
void main()
{
	T0_T1_init();
	buf[1] = 10;//不显示
	while(1)
	{
		display();
		if(IrOK==1) 
		{
			if(Im[2]==0x40)			//+
			{
				k++;
				if(k > 10 )
				{
					start=0; 
					k = 0;
				}
				if(k!=0&&mode==0)
				start=1; 
				buf[2]= k/10;
				buf[3]= k%10;
//				mode=0;
			}
			else if(Im[2]==0x19)			//-
			{
				k--;
				if(k==0&&mode==0)
				start=0;
				else if(k!=0&&mode==0)
				start=1;		
				if(k < 0)
				{
					start=1;  
					k = 10;
				}
				buf[2]= k/10;
				buf[3]= k%10;
//				mode=0;
			}
			else if(Im[2]==0x07)		   //正转
			{
				flag1 = 0;//正转
				buf[0] = 0;//最高位显示0
			//	haha = 0x00;//停止
			}
			else if(Im[2]==0x09)		   //反转
			{
				flag1 = 1;//反转
				buf[0] = 1;//最高位显示1
			//	haha = 0x00;//停止	
			}
			//1键
			if(Im[2]==0x0c&&k!=0)
			{
			   jishu=509;			   //减速比 1/64  步进角度5.625*1/64	一圈360/步进角度/8	=512	微调-3
			   start=1;
			   mode=1;
			}
			//2键
			else if(Im[2]==0x18&&k!=0)
			{
			   jishu=1018;
			   start=1;
			   mode=1;
			}
			//3键
			else if(Im[2]==0x5e&&k!=0)
			{
			   jishu=1527;
			   start=1;
			   mode=1;
			}
			//4
			else if(Im[2]==0x08&&k!=0)
			{
			   jishu=2036;
			   start=1;
			   mode=1;
			}
			//5
			else if(Im[2]==0x1c&&k!=0)
			{
			   jishu=2545;
			   start=1;
			   mode=1;
			}
			//6
			else if(Im[2]==0x5a&&k!=0)
			{
			   jishu=3054;
			   start=1;
			   mode=1;
			}
			//7键
			else if(Im[2]==0x42&&k!=0)
			{
			   jishu=3563;
			   start=1;
			   mode=1;
			}
			//8
			else if(Im[2]==0x52&&k!=0)
			{
			   jishu=4072;
			   start=1;
			   mode=1;
			}
			//9
			else if(Im[2]==0x4a&&k!=0)
			{
			   jishu=4581;
			   start=1;
			   mode=1;
			}
			else if(Im[2]==0x0d&&k!=0)	//   C
			{
				jishu=0;
			   start=1;
			   mode=!mode;
			}	

			//关机 0
			if(Im[2]==0x16)
			{
			//	jishu=0;
				start=0;
			}   
		   IrOK=0;	  
		}
		if(s1 == 0)
		{
			delay1m(3);
			if(s1 == 0)
			{
				flag1 = 0;//正转

				buf[0] = 0;//最高位显示0
		//		haha = 0x00;//停止
				 
			}
			while(!s1) display();
		}
		if(s2 == 0)
		{
		
			delay1m(3);
			if(s2 == 0)
			{
				flag1 = 1;//反转
				buf[0] = 1;//最高位显示1
		//		haha = 0x00;//停止
			}
			while(!s2) display();
		}
		if(s3 == 0)	   //速度加1档
		{
			delay1m(3);
			if(s3 == 0)
			{
				k++;
				if(k > 10 )
				{
					k = 0;
					start=0;
				}
				if(k!=0)
				start=1;
				buf[2]= k/10;
				buf[3]= k%10;
				mode=0;
			} 
			while(!s3) display();
		}
		if(s4 == 0)	 //速度减1档
		{
			delay1m(3);
			if(s4 == 0)
			{
				k--;
				if(k!=0)
				start=1;
				else if(k==0)
				start=0;
				if(k < 0)
				{
					start=1;
					k = 10;
				}
				buf[2]= k/10;
				buf[3]= k%10;
				mode=0;
			}
			while(!s4) display();
		}
	} 

}
//==================================定时器1中断函数,用于脉冲频率控制=====================================
void time1_interrupt()interrupt 3
{	
	static num1 = 0;
	static num2 = 0;
	TH1 = time_counter[k-1][0];
	TL1 = time_counter[k-1][1];//定时器1,定时1 用于步进电机转速控制
	if(start==1)
	{
		if(flag1 == 0)//正转
		{
			switch(num1)
			{
				case 0:a = 1;b = 0;c = 0;d = 0;break;
				case 1:a = 1;b = 1;c = 0;d = 0;break;
				case 2:a = 0;b = 1;c = 0;d = 0;break;
				case 3:a = 0;b = 1;c = 1;d = 0;break;
				case 4:a = 0;b = 0;c = 1;d = 0;break;
				case 5:a = 0;b = 0;c = 1;d = 1;break;
				case 6:a = 0;b = 0;c = 0;d = 1;break;
				case 7:a = 1;b = 0;c = 0;d = 1;break;
			}
			num1++;
			if(num1 == 8)
			{
				if(mode==1)
				{
					jishu--;
					if(jishu<=0)
					{
						jishu=0;
						start=0;
					}	
				}
				num1 = 0;
			} 
		}
		else		  //反转
		{
			switch(num2)
			{
				case 0:a = 1;b = 0;c = 0;d = 1;break;
				case 1:a = 0;b = 0;c = 0;d = 1;break;
				case 2:a = 0;b = 0;c = 1;d = 1;break;
				case 3:a = 0;b = 0;c = 1;d = 0;break;
				case 4:a = 0;b = 1;c = 1;d = 0;break;
				case 5:a = 0;b = 1;c = 0;d = 0;break;
				case 6:a = 1;b = 1;c = 0;d = 0;break;
				case 7:a = 1;b = 0;c = 0;d = 0;break;
			}
			num2++;
			if(num2 == 8)
			{
				if(mode==1)
				{
					jishu--;
					if(jishu<=0)
					{
						jishu=0;
						start=0;
					}	
				}
				num2 = 0;
			} 	
		}
	}
	else
	{
		a = 0;b = 0;c = 0;d = 0;
	}
}

//外部中断解码程序_外部中断0
void intersvr1(void) interrupt 2 using 1
{
	TR0=1;
	Tc=TH0*256+TL0;//提取中断时间间隔时长
	TH0=0; 
	TL0=0;         //定时中断重新置零
	if((Tc>Imin)&&(Tc<Imax))
	{ 
		m=0;
		f=1;
		return;
	 }       //找到启始码
	 if(f==1)
	{
		if(Tc>Inum1&&Tc<Inum3) 
		{
			Im[m/8]=Im[m/8]>>1|0x80; m++; 
		}
	    if(Tc>Inum2&&Tc<Inum1) 
		{
			Im[m/8]=Im[m/8]>>1; m++; //取码
		}
		if(m==32) 
		{
			m=0;  
			f=0;
			if(Im[2]==~Im[3]) 
			{
				IrOK=1;
				TR0=0; 
			}
			else IrOK=0;   //取码完成后判断读码是否正确
		}	  //准备读下一码   
	}
}


Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐