【毕业设计】19-基于单片机的物件计数控制系统设计(原理图工程+源代码工程+仿真工程+答辩论文)


typora-root-url: ./

【毕业设计】19-基于单片机的物件计数控制系统设计(原理图工程+源代码工程+仿真工程+答辩论文)

任务书

本设计是基于单片机的物件计数系统设计,依据相关传感器对经过的物件进行计数,以实现对流水线上的产品进行实时的、有效率的、精确计数。

1、利用相关的传感器完成物品的接近检测和技术。

2、单片机利用传感器输出的信号进行计数并显示该计数值

3、设计相关的硬件电路

4、自行设计软件编程
资料链接
原理图工程文件
原理图截图
仿真模型工程文件
仿真截图
答辩论文低重复率文档,25714字
英文文献及翻译
visio流程图

设计说明书

摘要

基于单片机的物件计数控制系统。采用STC89C52单片机控制系统的整体运行状态,红外发射和接收传感器负责监测当前是否有物体经过传感器,有无物体经过,传感器输出相应的跳变信号,经脉冲整形电路处理后,转换成标准的方波信号传送给单片机,单片机通过对脉冲的跳变沿进行计数,从而得知当前经过传感器物件的个数,完成基本的计数功能。为丰富系统的功能,该系统能实时显示当前物品的个数,也支持按键设定系统的上限计数功能,装箱计数功能等操作,当计数达到设定值时,系统自动给出报警提示。

设计框架架构

前 言… 1

第一章 绪论… 2

第一节 研究背景… 2

第二节 国内外研究情况… 3

第三节 本文的主要研究内容… 5

第四节 本章小结… 6

第二章 系统方案设计… 7

第一节 系统实现功能分析… 7

第二节 系统主要元器件方案选择… 7

一、单片机方案选择… 7

二、显示器方案选择… 8

第三节 系统各个功能模块原理介绍… 8

第四节 系统结构总框图… 9

第五节 本章小结… 10

第三章 系统硬件电路设计… 11

第一节 主控系统硬件设计… 11

一、单片机介绍… 11

二、单片机最小系统电路设计… 13

第二节 电源模块电路设计… 14

第三节 按键电路模块电路设计… 14

第四节 光学报警模块电路设计… 15

第五节 显示模块电路设计… 15

一、LCD1602介绍… 15

二、LCD1602的工作原理… 17

三、LCD1602模块电路设计… 18

第六节 声学报警模块电路设计… 19

第七节 物件检测模块电路设计… 19

第八节 系统总电路图… 20

第九节 本章小结… 21

第四章 系统的软件设计… 22

第一节 Keil软件介绍… 22

第二节 软件总设计流程… 23

第三节 按键模块程序设计… 24

第四节 显示模块程序设计… 25

第五节 物件检测模块程序设计… 26

第六节 报警模块程序设计… 26

第七节 本章小结… 27

第五章 系统的仿真实现… 28

第一节 仿真软件介绍… 28

第二节 系统仿真调试… 28

第三节 系统功能测试… 29

第四节 本章小结… 32

总 结… 33

致 谢… 34

参考文献… 35

附 录… 36

一、英文原文… 36

二、英文翻译… 43

三、工程图纸… 48

四、程序源码… 49

设计说明书及设计文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

源码展示

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "intrins.h"											   
#define     u8  			unsigned char
#define     u16   		unsigned int
#define     uchar  			unsigned char
#define     uint   		unsigned int
uchar yushe_jishu=70,c=70;				//预设值
uint jishu; 								//值全局变量
//运行模式  
uchar Mode=0;				 				//=1是设置阀值  =2是设置阀值	=0是正常监控模式
//管脚声明
sbit Led_Gre
=P2^2;				 //绿灯
sbit Led_Yellow  =P2^4;				 //黄灯
sbit Buzzer    	 =P2^0;				 //蜂鸣器
sbit Fan    	 	 =P3^3;				 //
sbit irlink      =P1^1;        //
/********************************************************************
* 名称 : delay_1ms()
* 功能 : 延时1ms函数
* 输入 : q
* 输出 : 无
***********************************************************************/
void delay_ms(uint q)
{
	uint i,j;
	for(i=0;i<q;i++)
		for(j=0;j<110;j++);
}
/***********************************************************************************************************
LCD1602相关函数
***********************************************************************************************************/
//LCD管脚声明 (RW引脚实物直接接地,因为本设计只用到液晶的写操作,RW引脚一直是低电平)
sbit LCDRS = P2^7;
sbit LCDEN = P2^6;
sbit D0		 = P0^0;
sbit D1		 = P0^1;
sbit D2		 = P0^2;
sbit D3		 = P0^3;
sbit D4		 = P0^4;
sbit D5		 = P0^5;
sbit D6		 = P0^6;
sbit D7		 = P0^7;
//LCD延时
void LCDdelay(uint z)		  //该延时大约100us(不精确,液晶操作的延时不要求很精确)
{
  uint x,y;
  for(x=z;x>0;x--)
    for(y=10;y>0;y--);
}
void LCD_WriteData(u8 dat)	  
{
	if(dat&0x01)D0=1;else D0=0;
	if(dat&0x02)D1=1;else D1=0;
	if(dat&0x04)D2=1;else D2=0;
	if(dat&0x08)D3=1;else D3=0;
	if(dat&0x10)D4=1;else D4=0;
	if(dat&0x20)D5=1;else D5=0;
	if(dat&0x40)D6=1;else D6=0;
	if(dat&0x80)D7=1;else D7=0;
}
//写命令
void write_com(uchar com)
{
  LCDRS=0;				  
	LCD_WriteData(com);
//  DAT=com;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}
//写数据
void write_data(uchar date)
{
  LCDRS=1;
	LCD_WriteData(date);
//  DAT=date;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}
/*------------------------------------------------
              选择写入位置
------------------------------------------------*/
void SelectPosition(unsigned char x,unsigned char y) 
{     
	if (x == 0) 
	{     
		write_com(0x80 + y);     //表示第一行
	}
	else 
	{      
		write_com(0xC0 + y);      //表示第二行
	}        
}
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
{     
	SelectPosition(x,y) ;
	while (*s) 
	{     
		write_data( *s);     
		s ++;     
	}
}
//========================================================================
// 函数: void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
// 应用: LCD_Write_Char(0,1,366,4) ;
// 描述: 在第0行第一个字节位置显示366的后4位,显示结果为 0366
// 参数: x:行,y:列,s:要显示的字,l:显示的位数
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注: 最大显示65535
//========================================================================
void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l) 
{     
	SelectPosition(x,y) ;
	if(l>=5)
		write_data(0x30+s/10000%10);	//万位
	if(l>=4)
		write_data(0x30+s/1000%10);		//千位
	if(l>=3)
		write_data(0x30+s/100%10);		//百位
	if(l>=2)
		write_data(0x30+s/10%10);			//十位
	if(l>=1)
		write_data(0x30+s%10);		//个位

}
/*1602指令简介
  write_com(0x38);//屏幕初始化
  write_com(0x0c);//打开显示 无光标 无光标闪烁
  write_com(0x0d);//打开显示 阴影闪烁
  write_com(0x0d);//打开显示 阴影闪烁
*/
//1602初始化
void Init1602()
{
  uchar i=0;
  write_com(0x38);//屏幕初始化
  write_com(0x0c);//打开显示 无光标 无光标闪烁
  write_com(0x06);//当读或写一个字符是指针后一一位
  write_com(0x01);//清屏
	
}

//红外检测//
int irlink_de(void)
{
	if(irlink==0)
	{
				delay_ms(10);//去抖动 
		if(irlink==0)
		{
		c++;
		}
	}
	return c;	
}
void Display_1602(yushe_jishu,c)
{
	//显示预设
	LCD_Write_Char(1,4,yushe_jishu,3) ;
	

	
	//时时
	LCD_Write_Char(1,13,c,3) ;
}
/***********************************************************************************************************
按键检测相关函数
***********************************************************************************************************/
//按键
sbit Key1=P1^6;				 //设置键
sbit Key2=P1^7;				 //加按键
sbit Key3=P3^2;				 //减按键
#define KEY_SET 		1		//设置
#define KEY_ADD			2		//加
#define KEY_MINUS		3		//减
//========================================================================
// 函数: u8 Key_Scan()
// 应用: temp=u8 Key_Scan();
// 描述: 按键扫描并返回按下的键值
// 参数: NONE
// 返回: 按下的键值
// 版本: VER1.0
// 日期: 2015-05-29
// 备注: 该函数带松手检测,按下键返回一次键值后返回0,直至第二次按键按下
//========================================================================
u8 Key_Scan()
{	 
	static u8 key_up=1;//按键按松开标志
	if(key_up&&(Key1==0||Key2==0||Key3==0))
	{
		delay_ms(10);//去抖动 
		key_up=0;
		if(Key1==0)			return 1;
		else if(Key2==0)return 2;
		else if(Key3==0)return 3;
	}
	else if(Key1==1&&Key2==1&&Key3==1)
		key_up=1; 	    
 	return 0;// 无按键按下
}
void main (void)
{
	u8 key;
 
	Init1602();			  //调用初始化显
  LCD_Write_String(0,0,"Counting System");  //开机界面
	LCD_Write_String(1,0,"SET:000  NOW:000"); 
    jishu=irlink_de(); 
	delay_ms(1000);
	while (1)        					//主循环
	{
		key=Key_Scan();					//按键扫描
    jishu=irlink_de();		
		if(key==KEY_SET)
		{
			Mode++;
		}
		
		switch(Mode)						//判断模式的值
		{
			case 0:								//监控模式
			{
				Display_1602(yushe_jishu,jishu);  //显示预设,预设,值,值
				
				if(jishu>=(yushe_jishu))	  //大于等于预设值时(为什么是大于预设值*10:因为我们要显示的是有小数点后一位,是一个3位数,25.9°C时实际读的数是259,所以判断预设值时将预设值*10)
				{		
					Buzzer=0;			  			//打开蜂鸣器报警
					Led_Yellow=1;		  			//打开报警灯
					Led_Gre   =0;           //关闭未报警指示灯
				}
				else					  					//值小于预设值时
				{
					Led_Yellow=0;		  			//关闭报警灯
					Led_Gre   =1;           //打开未报警指示灯
				}
				if((jishu<(yushe_jishu)))	  //当小于预设值并且也小于预设值时 (&&:逻辑与,左右两边的表达式都成立(都为真,也就是1)时,该if语句才成立)
				{
					Buzzer=1;			  			//停止报警
				}
				break;
			}
			case 1://预设模式
			{
				SelectPosition(1,3) ;					//指定位置
	   		write_com(0x0d);							//阴影闪烁
				if(key==KEY_ADD)							//加键按下
				{
					yushe_jishu++;					    //预设值(阀值)加1
					if(yushe_jishu>=99)			 		//当阀值加到大于等于99时
					yushe_jishu=99;					 		//阀值固定为99
					LCD_Write_Char(1,4,yushe_jishu,3) ;//显示预设
				}
				if(key==KEY_MINUS)				 		//减键按下
				{
					if(yushe_jishu<=1)					//当上限值减小到1时
					yushe_jishu=1;          		//固定为1
					yushe_jishu--;							//预设值减一,最小为0
					LCD_Write_Char(1,4,yushe_jishu,3) ;//显示预设
				}
				break;			  								//执行后跳出switch
			}			
			default	:	
			{
				write_com(0x38);//屏幕初始化
				write_com(0x0c);//打开显示 无光标 无光标闪烁
				Mode=0;			//恢复正常模式
				break;
			}
		}
		
	}
}


猜你喜欢

转载自blog.csdn.net/qq_22592979/article/details/128108652