基于51单片机电子称—串口显示

news2024/10/6 22:33:42

基于51单片机电子称设计

(仿真+程序)

功能介绍

具体功能:

1.矩阵键盘组成按键,输入价格结算、打印;

2.用滑动变阻器和ADC0832模拟称重;

3.LCD1602可以显示重量、单价和总价;

4.接串口可以打印信息;

​演示视频:

基于51单片机电子称—串口显示 

添加图片注释,不超过 140 字(可选)

程序

/****

	     智能电子称系统设计

	第一行显示:  weigh:		 Kg
	第二行显示:  Price:

	按下结算按键:可以计算总价
	总价:
	Sum:

**********************************************/
#include<reg52.h>
#include "lcd.h"
#include"weigh.h"
#define uchar unsigned char
#define uint unsigned int
uint TIM=0;
uchar dis[10],mydata[6];
uchar open=0;
sbit beep=P2^0;
extern unsigned long wei_true;
unsigned long all_in=0,sum;
unsigned char point=0,dis_n=0;
unsigned char end=0;
extern unsigned char wei_h[5];
unsigned char alarm_en=0;
unsigned char down_n,sum_all[6],sum_n=0,sen1[6];
struct key
{
  uchar down; //输入次数
}key={0};
unsigned char code KEYTAB[16] ={0x7e,0xBE,0XBD,0xBB,0xDE,0xDD,0xDB,0xEE,0xED,0xEB,0x7D,0x7B,0x77,0xb7,0xd7,0xe7};
void clear_all();//
/*******************************************
*函数名称:delay(uint t)延时函数
*函数作用:延时1ms左右
*
*********************************************/
void delay(uint t)
{
   uint i,j;
   for(i=0;i<t;i++)
      for(j=0;j<110;j++);
}
void sen(unsigned char  r_byte)
{
  	 SBUF = r_byte;  
     while( TI == 0 );				//查询法
  	 TI = 0;  
}   
void send_print1()
{	 	
         unsigned char i=0;
		 sen('W');
		 sen('e');
		 sen('i');
		 sen('g');
		 sen('h');
		 sen(':');
		 sen(wei_h[0]+48);
		 sen(wei_h[1]+48);
		 sen(wei_h[2]+48);
		 sen(wei_h[3]+48);
		 sen(' ');

		 sen('P');
		 sen('r');
		 sen('i');
		 sen('c');
		 sen('e');
		 sen(':');
		 for(i=0;i<down_n;i++)
		 {
		 	  sen(sen1[i]);
		 
		 }
		 sen('S');
		 sen('u');
		 sen('m');
		 sen(':');
		 for(i=0;i<sum_n;i++)
		 {
		 	  sen(sum_all[sum_n-i-1]);
		 
		 }
}
/*******************************************
*函数名称:keyscan( ) 键盘扫描函数
*函数作用: 1、扫描键盘,获得键值
             2、显示输入键值(*号),并保存
             3、读取功能按键,并执行相应的功能
按键的功能划分如下:
         |  7  |  8  |  9   |  clear	    |
		 ---------------------------------------
		 |  4  |  5  |  6   |  键 |
		 ---------------------------------------
		 |  1  |  2  |  3   |  没有使用       |
		 ---------------------------------------
		 |     |point| 	    |
		 |  0  |	 |   	|  没有使用       |
		 ---------------------------------------
*********************************************/
unsigned char keyscan(void)
{
     unsigned char i=0,j,t;
	 unsigned char s=0,init_n;
	 unsigned char point_wei=0;
	  unsigned char redat;
	  unsigned char keynum=0;
	  P3=0XFF;
      P1=0XF0;
	  redat=P3&0XF0;
	  if(redat!=0xF0)
	  {	  
	  	   delay(12);
		   redat=P3&0XF0;//再次延时检测
		   if(redat!=0xF0)
		   {
		   	 keynum=redat;//获得第四位
			 P1=0XFF;//看来这个地方是必须的
			 P3=0X0F;//开始读取高四位
			 delay(1);
			 redat=P1&0X0F;
			 keynum|=redat;
			 for(i=0;i<16;i++)
			 {
			 	if(keynum==KEYTAB[i])
				{	 
				      //这个地方发送出去
					  if(i<10)
					  {
					     sen1[down_n]=i+48;
						 down_n++;
					  }
					  else if(i==10)
					  {
					  	 sen1[down_n]='.';
						 down_n++;
					  }
   

					  if(i<10) //如果输入键值小于10即0-9
					   {
						    if(key.down==1)
							{
							  if(mydata[0]>0)
							  {
							  	 //这个时候才读取新的数据,否则等待按下小数点
								  mydata[key.down]=i; //	保存按键
							     lcd_pos(key.down+70);	 //
							      lcd_wdat(i+48);
						          key.down++; //按键次数加1 
							  }							
							}
							else
							{
							     if(point==0)
								 {
								    mydata[key.down]=i; //	保存按键
								}
								else
								{
								   mydata[key.down-1]=i; 
								}
							      mydata[key.down]=i; //	保存按键
							      lcd_pos(key.down+70);	 //
							      lcd_wdat(i+48);
						          key.down++; //按键次数加1  						
							}				   	
					    } 					
						else if(i==10)
						{
						    if(key.down>0)
							{
							    if(point==0) //一次运行过程中,只能输入一个小数点
								{
								  	 lcd_pos(key.down+70);	 //
								     lcd_wdat('.');
							         key.down++; //按键次数加1 
									 point=key.down;//保存当前出现位置 							
								}  //记录小数点出现的位置
							
							}
						   
						  
						}
						else if(i==11)
						{
						  end=1;
						  //结算	   					  //得到实际值
						  //先不讨论小数点的问题,最后在分析小数点问题
						  sum=0;
						  if(point>0) key.down=key.down-1;
						  for(j=0;j<key.down;j++)
						  {
						    //计算单价
							sum=sum*10+mydata[j];//						  
						  }
						  all_in=wei_true*sum;	//把这个数据显示出来的
						  lcd_wcmd(0x01);// 清除屏幕	
						  lcd_pos(0);
						  lcd_wdat('S');
						  lcd_pos(1);
						  lcd_wdat('u');
						  lcd_pos(2);
						  lcd_wdat('m');
						  lcd_pos(3);
						  lcd_wdat(':');	
						  for(j=0;j<10;j++)
						  {
						  	 dis[j]=all_in%10;							 
							 all_in=all_in/10;
							 if(all_in==0) 
							 {
							     dis_n=j;
							     break;
							 }
					
						  }

						  if(point==0)
						  {
						  	  point_wei=0;
						  }
						  else
						  {
						    point_wei=key.down-point+1;
						  
						  }
						  //这个地方出现了问题了
						  sum_n=dis_n;
                          for(j=0;j<=dis_n;j++)
						  {
						      if(j==0) sum_n=0;
							  if((j==point_wei)&&(point_wei>0))
							  {
							  	 	lcd_pos(15-j);
						         	lcd_wdat('.');
									sum_all[sum_n]='.';
									sum_n++;
									s=1;									
									lcd_pos(15-(j+s));
							        lcd_wdat(dis[j]+48);
									sum_all[sum_n]=dis[j]+48;
									sum_n++;
						      }
							  else
							  {
							   	lcd_pos(15-(j+s));
							    lcd_wdat(dis[j]+48);
								sum_all[sum_n]=dis[j]+48;
								sum_n++;
							  }							  
						  }						
						}
						else if(i==15)
						{
							  //保存
							  clear_all();	
							  down_n=0;//清除0
													
							  for(t=0;t<6;t++)
							  {
							    mydata[t]=0;							  
							  }
							  key.down=0;
							  end=0;
						 	  point=0; 					
						}
						else if(i==14)
						{
						   send_print1();
						   sum_n=0;
						
						}
					/*****如果按下清除键******/
					
					delay(900);//键盘延时
				}
		     }
		  }	  
	  }
	  return 0;	 
}

/*******************************************
*函数名称:init_timer( )	定时器初始化函数
*函数作用:
          定时器定时时间1ms

*********************************************/	
void init_timer() //
{
    SCON = 0x50;       //REN=1允许串行接受状态,串口工作模式2 
    TMOD|= 0x21;//
   	TH0 = 0xEC;
	TL0 = 0x78;
    ET0=1;
    TH1  = 0xFD;     //baud*2  /* reload value 19200、数据位8、停止位1。效验位无(11.0592)     
  	TL1 = 0xFD; 
	TR1  = 1;        //开启定时器1 
	TR0  = 1; //关闭                                                      
	ES   = 1;        //开串口中断    	
	EA=1;		
   
}

/*******************************************
*函数名称:clear( )	 清除函数
*函数作用:
         只清除按下的次数,以及初始化字符显示
*********************************************/	  
void clear() reentrant
{
  key.down=0;
  init_char();
}
/*******************************************
*函数名称:clear_all( )	  清除所有的标志变量
*函数作用
*********************************************/	
void clear_all()  //所有的变量清零
{
   clear();  
}
void sys_init()
{
    lcd_init();
	init_char();
	init_timer();

}

/*******************************************
*函数名称:main( )	 主函数
*函数作用:
         这个函数必须有的

*********************************************/	
void main()//
{
    beep=1;
   sys_init();
    while(1)
    {
	     keyscan();
		 if(!end) 
		 {
		     get_wei();
		   	 if(alarm_en) 
			 {
			   beep=0;
			 }
			 else
			 {
			   beep=1;
			 }
		  }
		 delay(700);

   }   
}  
 /*******************************************
*函数名称:TI_int1( )	定时器1中断处理函数
*函数作用:
        
*********************************************/	
void T0_int1(void) interrupt 1//定时器中断 
{
    TH0 = (65536-10000)/256;	
	TL0 = (65536-10000)%256;	
	TIM++;
    if(TIM>100)
	{
		TIM=0; 
		open=1;
	}    
}



硬件设计

使用元器件:

单片机:AT89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

添加图片注释,不超过 140 字(可选)

设计资料

01仿真图

本设计使用proteus7.8和proteus8.9两个版本设计!具体如图!

添加图片注释,不超过 140 字(可选)

02程序

本设计使用软件keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

03设计资料

        资料获取请关注同名公众号,全部资料包括程序(含注释)、仿真源文件等。具体内容如下,全网最全!!

 

可以关注下方公众号!

点赞分享一起学习成长。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1871022.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于新零售的一些思考

本文作为2024上半年大量输入之后的核心思考之一。工作到一定阶段之后&#xff0c;思考的重要性越来越高&#xff0c;后续会把自己的个人思考记录在这个新系列《施展爱思考》。背景是上半年面临业务转型从电商到新零售&#xff0c;本文是相关大量输入之后的思考&#xff0c;对新…

vue2中的组件自定义事件

1.绑定事件: <组件 :自定义名称"方法" /> 2.调用 this.$emit(方法,参数) 3.关闭 this.$off(方法) 案例: 1.提前准备好组件 Student组件 <template><div class"student"><h1>学校名称:{{ st…

JAVA每日作业day6.27

ok了家人们&#xff0c;今天学习了内部类&#xff0c;话不多说我们一起看看吧。 一&#xff0c;内部类 1.1 内部类概述 将一个类 A 定义在另一个类 B 里面&#xff0c;里面的那个类 A 就称为 内部 类 &#xff0c; B 则称为 外部类 。 内部类分为成员内部类与局部内部类。 1…

修改 app id - 鸿蒙 HarmonyOS Next

修改项目 app id 后通过真机 build run 的时候抛出了如下异常; 项目中更改后的配置与真机的不匹配; {app: {bundleName: "com.xxxxxx.xxx_harmony",vendor: "xxxxxx",versionCode: 1,versionName: "3.5.00",icon: "$media:app_icon",…

9.二维数组的遍历和存储

二维数组的遍历和存储 二维数组的遍历 二维数组a[3][4],可分解为三个一维数组,其数组名分别为: 这三个一维数组都有4个元素,例如:一维数组a[0]的 元素为a[0][0],a[0][1],a[0][2],a[0][3]。所以遍历二维数组无非就是先取出二维数组中得一维数组, 然后再从一维数组中取出每个元…

Open AI限制来袭?用上这个工具轻松破局!

【导语】近日&#xff0c;AI领域掀起了一场不小的波澜。Open AI宣布&#xff0c;从7月9日起&#xff0c;将对部分地区的开发者实施API调用限制。这一消息对于许多依赖Open AI技术的国内初创团队来说&#xff0c;无疑是一个沉重的打击。 对于这些团队而言&#xff0c;Open AI的A…

Spring相关面试题(三)

29 如何在所有的BeanDefinition注册完成后&#xff0c;进行扩展 Bean工厂的后置处理器&#xff0c;在所有的Bean注册完成后&#xff0c;就被执行。 public class A implements BeanFactoryPostProcessor {private String name "a class";private B b; ​public St…

如何使用ig507金融数据库的股票接口,股票API来获取MACD指标

一、MACD指标简介 MACD&#xff08;Moving Average Convergence Divergence&#xff0c;移动平均收敛/发散&#xff09;是一种趋势跟踪动量指标&#xff0c;用于分析股票或其他金融产品的价格趋势。MACD由两部分组成&#xff1a;差离值&#xff08;DIF&#xff09;和信号线&am…

麒麟系统安装MySQL

搞了一整天&#xff0c;终于搞定了&#xff0c;记录一下。 一、背景 项目的原因&#xff0c;基于JeecgBoot开发的系统需要国产化支持&#xff0c;这就需要在电脑上安装MySQL等支撑软件。 国产化项目的操作系统多是麒麟系统&#xff0c;我的系统如下&#xff1a; arm64架构。…

杀手级AI应用前瞻,一文带你了解8个ai大语言模型

一、大模型解析&#xff08;LLM、MLLM、GLM&#xff09; 基础概念&#xff1a; Transformer&#xff1a;ChatGPT的核心结构是Transformer&#xff0c;这是一种采用自注意力机制的深度学习模型。通过自注意力机制&#xff0c;Transformer能够理解输入文本的上下文信息&#xf…

当中年男人的觉越来越少 他突然半夜买台电脑(30+岁仿真工程师买电脑心得)

仿真工程师的购机分析&#xff0c;游戏本、移动工作站还是台式机&#xff1f; 认清自己的需求。 现状。现在有一个19年买的华为matebook14、i5第八代低压U&#xff0c;8G内存。还好有SSD当虚拟内存&#xff0c;要不开网页估计都得卡住。媳妇还有台i7、16G的matebook&#xff…

劳易测安全技术速递:滑动式输送系统出入口安全防护

汽车总装车间的滑动式输送系统用于搬运可以调整高度和位置的工作平台&#xff0c;大幅提升了汽车装配线的作业效率。但传统的安全解决方案在面对物料尺寸变动时&#xff0c;往往无法精准检测到人员位置&#xff0c;导致安全隐患。 针对滑动式输送系统出入口的安全防护&#xff…

OpenCV使用forEach的方式来遍历像素值

opencv 4.x新增了forEach的方式遍历像素值&#xff0c;比传统方式略快一些。因为它本身是使用多线程并行的方法来遍历的。从opencv源码能看到这句话&#xff1a; parallel_for_(cv::Range(0, LINES), PixelOperationWrapper(reinterpret_cast<Mat_<_Tp>*>(this), …

Spring框架学习笔记(本地印象笔记搬运)(整理中)

1、背景 Spring作为Java Web开发使用最频繁的框架&#xff0c;具有非常高的学习价值&#xff0c;在Spring框架源码中包含了很多设计模式&#xff08;单例、原型、代理、观察者等&#xff09;&#xff0c;读懂这些源码有助于拓宽开发思路&#xff0c;同时也能提高后端排查错误的…

QQ等级评估源码+软件

今天&#xff0c;我将和大家探讨一个与直播、撸礼物相关的主题&#xff0c;它涉及到的是一种特殊的软件及其源码——QQ等级评估工具。在我们的生活中&#xff0c;直播已经成为了一种越来越流行的娱乐方式。不论是音乐会、电子竞技&#xff0c;还是日常生活分享&#xff0c;你都…

使用AI技术实现语言练习

使用人工智能技术实现语言场景练习&#xff0c;可以有效地提高学习者的语言能力&#xff0c;包括口语、听力、阅读和写作。以下是一些常见的应用场景。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 口语练习 虚拟对话伙伴: 利用…

基于最优滑膜控制的永磁同步电机调速系统MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 最优滑模面的选取 假定系统初始位于滑模面上&#xff0c;可得&#xff1a; 通过设计c(t)使如下积分性能指标达到最小: T为到达滑模面的终值时间&#xff0c;求解方程: a为系统初始条件参数。设cmc(0)为c(t)变…

软件协同开发是一种通过团队合作来创建软件的开发方法

软件协同开发是一种通过团队合作来创建软件的开发方法。与传统的瀑布模型相比&#xff0c;软件协同开发强调团队成员之间的合作和沟通&#xff0c;以实现更高效的开发过程和更优质的软件产品。 在软件协同开发中&#xff0c;团队成员通过一系列工具和技术来协同工作。这些工具…

Ubuntu-22.04 安装Confulence

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

昇思25天学习打卡营第4天|onereal

今天学习的内容是&#xff1a;ResNet50迁移学习 以下内容拷贝至教程&#xff0c;实话实话看不懂&#xff0c;迷迷糊糊都运行jupyter里的代码。走完程序&#xff0c;训练生成了一些图片。 ResNet50迁移学习 在实际应用场景中&#xff0c;由于训练数据集不足&#xff0c;所以很少…