51单片机简易电子称程序

发布者:WanderlustGaze最新更新时间:2020-09-14 来源: 51hei关键字:51单片机  简易电子称 手机看文章 扫描二维码
随时随地手机看文章

这是我的单片机设计,主要是使用压力传感器、HX711模块和51单片机做的,附件里包含了电子称的原理图和源代码
这个简易电子称共有三个模式:
模式1:进行普通的物体测量;
模式2:计价模式;
模式3:累计测量模式;
此外,除了可以用按键进行模式的切换,还可通过上位机发送指令进行模式的切换。
此次课程设计主要是针对51单片机的基础知识的运用,其中主要运用了以下知识点:对矩阵按键、LED灯、蜂鸣器、AD转换、LCD12864、
定时器0、定时器1、外部中断0、外部中断1、串口(使用到定时器2,所以在烧录时芯片请用STC89C52)等。

简易介绍
基于51单片机设计的简易电子称,性能比较简单,共分为3个模式,模式一是用于重物的测量,模式2主要用于物品的计价,不过单价输入只能是整数,由于重物重量精确到小数点后两位,所以单计价后的价格可以是小数的。模式三是重物的累计测量。同时处理按键进行模式切换后,还可以通过上位机发送指令进行模式切换,当上位机发送1时,接收机接到指令后启动模式1,并发送“模式1启动”。其他模式也与此相似,但当上位机发送其他字符时,单片机会返回“模式切换失败,请输入正确序号”类似的字样。
模式说明
模式1
普通测量模式,只进行普通的测量
模式2
计价测量模式,可根据输入的价格和被测物重量计算价格
模式3
累计测量模式,可在按键按下后累计被测物重量,结束键按下后显示总重量
按键说明
数字键
模式2下的价格输入键,只在模式2下有效
功能键A
按下A键进入模式1
功能键B
按下B键进入模式2
功能键C
按下C键进入模式3
功能键D
模式3下按下后被测物体重量被确认,若没按下模式3结束键,继续进行下一被测物体的测量。只在模式3下有效
功能键*
模式2下的价格清除键,按下后价格归0,显示清空。只在模式2下有效
功能键#
模式2下的价格确认键,按下后下个被固定,再按下数字键时价格处于重新输入的状态。模式3下作为模式3结束键,按下按键后显示累计测量的总重量。

界面简介模式1界面

模式2界面

模式3界面

模式3最终界面

程序主流程图

各个模块流程图(略)
单片机源程序如下:

#include "reg52.h"

#include "HX711.h"

#include "lcd12864.h"

#include "module.h"

#include "keyborad.h"


//*************************************************************************

// 定时器0初始化函数

//*************************************************************************

void timer0_init(void)//50ms

{

ET0 = 1; //允许定时器0中断

TMOD = 0x11; //定时器工作方式选择

TL0 = 0xb0;

TH0 = 0x3c; //定时器赋予初值

TR0 = 1; //启动定时器

EA = 1;

}



//*************************************************************************

// 定时器0中断服务函数

// 每秒中刷新5次

//*************************************************************************

bit weight_flag=0; //定时器0的标志位

uchar time0_count=0; //定时器0计数标志

void timer0() interrupt 1

{

TL0 = 0xb0;

TH0 = 0x3c; //定时器赋予初值

time0_count++;

if(time0_count>=4){

time0_count = 0;

weight_flag = 1;

}

}


//*************************************************************************

// 定时器1初始化函数

//*************************************************************************

void timer1_init(void)        //50ms

{

ET1 = 1;

TL1 = 0xB0;        //设置定时初值

TH1 = 0x3C;        //设置定时初值

//        TR1 = 1;        //定时器1开始计时

}


//*************************************************************************

// 定时器0中断服务函数

// 计时3秒钟

//*************************************************************************

bit weight_flag1; //定时器1的标志位

uchar timer1_count;//定时器计1数标志

void timer1(void) interrupt 3

{

TL1 = 0xB0;        //设置定时初值

TH1 = 0x3C;        //设置定时初值

timer1_count++;

if (timer1_count == 60) {

TR1 = 0;

timer1_count = 0;

weight_flag1 = 1;

}

}


//*************************************************************************

// 外部中断0初始化

// 用来调整超重报警值

//*************************************************************************

ulong weight_alarm=200000;

void INIT0_int()

{

EX0 = 1;

IT0 = 1;

}

//*************************************************************************

// 外部中断0服务函数

//*************************************************************************

void INIT0_deal() interrupt 0

{

weight_alarm-=50000;if(weight_alarm<=100000)weight_alarm=450000;

}


//*************************************************************************

// 外部中断1初始化

// 用来调整超重报警值

//*************************************************************************

void INIT1_int()

{

EX1 = 1;

IT1 = 1;

}

//*************************************************************************

// 外部中断1服务函数

//*************************************************************************

void INIT1_deal() interrupt 2

{

weight_alarm+=50000;if(weight_alarm>=450000)weight_alarm=200000;

}


//*************************************************************************

// 串口发送数据函数

//*************************************************************************

void SendData(unsigned char *s)

{

while(*s>0)

{

SBUF = *s;

while(!TI);

TI = 0;

s++;

}

}

//*************************************************************************

// 串口初始化函数

//*************************************************************************

sfr T2MOD = 0x9C;

void USTAR_init()

{

PS = 1;

SCON = 0x50;

T2MOD = 0x01;

T2CON = 0x30;

TH2 = 0xFF;

TL2 = 0xDC;        

RCAP2H = 0XFF;

RCAP2L = 0xDC; //波特率9600

TR2 = 1;

ES = 1;

EA = 1;

}

//*************************************************************************

// 串口中断服务函数

//*************************************************************************

uchar ReceiveData=0;

void USTAR() interrupt 4

{

ReceiveData = SBUF;

while(!RI);

RI = 0;

if(ReceiveData=='1')

{

SendData("模式1启动n");

}

else if(ReceiveData=='2')

{

SendData("模式2启动n");

}

else if(ReceiveData=='3')

{

SendData("模式3启动n");        

}

else

{

SendData("切换失败,");

SendData("非所属模式n");

}

}

//*************************************************************************

// 串口模式切换界面函数

//*************************************************************************

void BoundaryChange()

{

if(ReceiveData==0)return;

if(ReceiveData=='1')

{

module1_flag=1;

module2_flag=0;

module3_flag=0;

ReceiveData=0;

module1_init();

}

else if(ReceiveData=='2')

{

module1_flag=0;

module2_flag=1;

module3_flag=0;

ReceiveData=0;

module2_init();

}

else if(ReceiveData=='3')

{

module1_flag=0;

module2_flag=0;

module3_flag=1;

ReceiveData=0;

module3_init();        

}

}


//*************************************************************************

// 报警函数

//*************************************************************************

sbit beep = P2^7;

sbit led = P0^0;

void beep_alarm()

{

uint i=500;

while(i--){

beep = ~beep;

if(i==1)led =~led;

delay(1);}

}

//*************************************************************************

// 主函数

//*************************************************************************

void main()

{

lcd_init();        //LCD12864初始化

USTAR_init();        //串口中断初始化

timer0_init();        //定时器0初始化

timer1_init();        //定时器1初始化

INIT0_int();        //外部中断0初始化

INIT1_int();        //外部中断1初始化

Get_MaoPi();        

Get_MaoPi();

delay(1000);

Get_MaoPi();

Get_MaoPi();        //获取毛皮重量

while(1)

{

BoundaryChange();

if(weight_flag==1){

Get_Weight();

weight_flag=0;} //每次标志位为1的时候刷新

Key_Deal();        

if(module1_flag==1) module1();

else if(module2_flag==1)module2();

else if(module3_flag==1)module3();

if(weight >= weight_alarm){beep_alarm();}else{led=1;}//超重报警

if(module3_flag != 1){thing_count=1;Totle_weight=0;}//非模式3下的计数量全部清零

}        

}





关键字:51单片机  简易电子称 引用地址:51单片机简易电子称程序

上一篇:基于51单片机PWM调速数码管显示测速
下一篇:单片机+PCF8591实现数字电压表

推荐阅读最新更新时间:2024-11-17 17:36

51单片机上数码管的静态显示和动态显示
一、TX1C数码管介绍 共阴极和共阳极数码管,实验板上是共阴极数码管,6位一体的数码管。 连接原理图如下面两图:连在一起的段线(段选线即abcdefgh)控制数码管亮什么数字,独立的公共端(位选线即共阴极或共阳极)控制哪一位数码管亮。因为段线是连接在一起的,所以显示的数字是一样的,共阴极一端是独立的公共端,所以低六位分别控制哪位数码管亮。用两个锁存器可以控制任意数码管显示任意数字。 一、数码管的静态显示 静态显示就是位选打开的数码管上显示的数字都相同,因为段选是连接在一起的。 1、数码管的前三位显示666 #include reg52.h sbit wela=P2^7; sbit dula=P2^6; void m
[单片机]
<font color='red'>51单片机</font>上数码管的静态显示和动态显示
51单片机】点阵LED的显示实验
前言 今天女朋友生日,除了礼物之外,一时想不到能给她点什么不一样的,并且奈何自己不会写诗,没办法从这方面入手。所以就用我会的方式吧。 既然最近自己琢磨琢磨单片机,也准备玩儿点阵LED的显示实验,这时我灵机一动,不如用LED做一个吧。(????????????老理工男了,怎么有的女朋友?) 好,下面就来看看我是怎么做的吧。 一、环境 环境用的是Keil5编译,这是目前比较主流的单片机编译软件,支持汇编和C。其次,我用到了Proteus8软件仿真,没有自己买单片机,仿真软件的东西很全面。具体的软件操作在我的上一篇文章中有说了,这里就不再赘述。需要看软件操作的小伙伴可以参考我的 这篇文章 (点击阅读)。 二、硬件 这次用到的原件有
[单片机]
【<font color='red'>51单片机</font>】点阵LED的显示实验
51单片机I/O口模拟串行通信实现方法
目前普遍采用的MCS51 和PIC 系列单片机通常只有一个(或没有)UART异步串行通信接口,在应用系统中若需要多个串行接口(例如在多机通信系统中,主机既要和从机通信又要和终端通信)的情况下,通常的方法是扩展一片8251 或 8250 通用同步/异步接收发送芯片(USART),需额外占用单片机I/O 资源。本文介绍一种用单片机普通I/O 口实现串行通信的方法,可在单片机的最小应用系统中实现与两个以上串行接口设备的多机通信。 1.串行接口的基本通信方式 串行接口的有异步和同步两种基本通信方式。异步通信采用用异步传送格式,如图1 所示。数据发送和接收均将起始位和停止位作为开始和结束的标志。在异步通信中,起始位占用一位(
[单片机]
<font color='red'>51单片机</font>I/O口模拟串行通信实现方法
在Linux下51单片机的开发环境搭建详细程序编写详细概述
在Linux下没有像keli那样好用的IDE来开发51单片机,开发环境只能自己搭建了。 第一步:安装交叉编译工具 a) 安装SDCC sudo apt-get install sdcc b)测试SDCC是否可用,这是个网上找的简单的流水灯代码 test.c, 用来测试 #include 8051.h #define uint unsigned int #define uchar unsigned char uchar tab = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; void Delay(uint xms) { uint i,j; for(i=xms;i 0;i--) for(j
[单片机]
基于C51单片机的报警产生器电路原理图
用 P1.0 输出 1KHz 和 500Hz 的音频信号驱动扬声器,作报警信号,要求 1KH z信号响 100ms , 500Hz 信号响 200ms, 交替进行, P1.7 接一开关进行控制,当开关合上响报警信号,当开关断开告警信号停止,编出程序。   ( 1 . 把 “ 单片机系统 ” 区域中的 P1.0 端口用导线连接到 “ 音频放大模块 ”区域中的 SPK IN 端口上;   ( 2 . 在 “ 音频放大模块 ” 区域中的 SPK OUT 端口上接上一个 8欧的或者是16 欧的喇叭;   ( 3 . 把 “ 单片机系统 ” 区域中的 P1.7/RD 端口用导线连接到 “四路拨动开关 ” 区域中的 K1 端口上.
[模拟电子]
基于C<font color='red'>51单片机</font>的报警产生器电路原理图
51单片机常见的7种时钟电路介绍
在MCS-51单片机片内有一个高增益的反相放大器,反相放大器的输入端为XTAL1,输出端为XTAL2,由该放大器构成的振荡电路和时钟电路一起构成了单片机的时钟方式。根据硬件电路的不同,单片机的时钟连接方式可分为内部时钟方式和外部时钟方式,如下图所示。 时钟电路:(a)内部方式时钟电路,(b)外接时钟电路 在内部方式时钟电路中,必须在XTAL1和XTAL2引脚两端跨接石英晶体振荡器和两个微调电容构成振荡电路,通常C1和C2一般取30pF,晶振的频率取值在1.2MHz~12MHz之间。对于外接时钟电路,要求XTAL1接地,XTAL2脚接外部时钟,对于外部时钟信号并无特殊要求,只要保证一定的脉冲宽度,时钟频率低于12MHz
[单片机]
<font color='red'>51单片机</font>常见的7种时钟电路介绍
51基础知识——51单片机小结(一)
概述 51单片机是比较适合新手入门的一款单片机,结构简单,易于学习。本博客为笔者自学完单片机后进行的小总结。 单片机我也是学学放放,中间遇到了很多挫折(当然现在也是),我是自学了C语言之后,在大一下学期开始接触51的,所以,我的51系列blog比较浅显,因为用单片机的时间较少,所以,也并不全面,仅供参考。如有错误,敬请指正。 51单片机的结构(基于MCS-51) 单片机也叫单片微控制器,可以简单的理解为:一种集成在芯片上的微型计算机系统。通用计算机采用冯诺依曼结构(不完全是冯诺依曼结构)而51单片机属于哈佛结构。 为什么51单片机要使用哈佛结构? (这里之说冯诺依曼结构与哈佛结构的差异)冯诺依曼结构认为程序是特殊的数据,所以
[单片机]
51基础知识——<font color='red'>51单片机</font>小结(一)
使用51单片机输出PWM控制舵机
SCU 的电子信息学院的某个社团会每年举办船模大赛。 因为去年的船模比赛时候懒,所以就买了成品的遥控器(天地飞6)来参赛,控制自己制作的遥控船上面的电调和舵机。最近有心情想在今年的船模比赛中自己制作遥控器,先从第一步开始吧:使用单片机来控制舵机(控制电调的原理类似)。 0x01.什么是舵机? 其实舵机就是一种伺服电机,根据要求旋转一定的角度,在我看来,知道这些就够了~~ 0x02.舵机有什么用? 就拿模型来说吧,船要转弯的话,可以采用的一种方式就是改变船后面舵片的角度来改变两侧对水的阻力,以此来让船转向,这个也是舵机一词的由来。 0x03.怎么控制? PWM波,这是什么东西呢?其
[单片机]
使用<font color='red'>51单片机</font>输出PWM控制舵机
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved