一、简介

一个基于51单片机的电子秤,主要涉及到传感器数据的采集、处理和显示。这种电子秤可以用于重量的精确测量,广泛应用于商业、实验室和家庭等场合。通过这样的设计,可以实现一个功能全面、操作简便、测量准确的电子秤。这不仅是一个实用的测量工具,也是一个很好的嵌入式系统设计和编程学习项目。

二、设计思路

一个基于51单片机的电子秤,主要涉及到传感器数据的采集、处理和显示。这种电子秤可以用于重量的精确测量,广泛应用于商业、实验室和家庭等场合。以下是设计这种电子秤的基本组成和工作原理简介:

2.1 基本组成

  1. 51单片机

    • 作为控制核心,负责处理传感器数据、执行测量算法和控制显示输出。
  2. 称重传感器

    • 通常使用应变片式传感器,它能将物体的重量转换为电信号。这个信号随着物体重量的变化而变化。
  3. 模拟数字转换器(ADC)

    • 因为51单片机处理的是数字信号,而传感器输出的是模拟信号,所以需要ADC将模拟信号转换为数字信号。
  4. 显示装置

    • 如LCD或LED显示屏,用于显示测量的重量。
  5. 电源管理

    • 提供稳定的电源供应,确保系统正常工作。
  6. 按键或触摸屏(可选):

    • 用于实现用户界面,如校准、单位切换(克、千克、磅等)。

2.2 工作原理

  1. 数据采集

    • 称重传感器检测到重量变化,将物理变化转换为电信号,通过ADC转换为数字信号。
  2. 数据处理

    • 51单片机接收到数字信号后,根据预设的算法计算出准确的重量。这可能包括滤波、去噪声、线性校正等步骤。
  3. 显示结果

    • 处理后的重量数据通过数字接口发送到显示装置,用户即可读取重量信息。
  4. 用户交互

    • 用户可以通过按键或触摸屏进行如零点校准、单位切换等操作,单片机根据这些输入调整测量和显示逻辑。

2.3 设计要点

  • 精度:选择高精度的传感器和ADC,确保测量结果的准确性。
  • 稳定性:设计稳定的电源和抗干扰电路,保证系统在不同环境下都能稳定工作。
  • 用户友好:设计简洁直观的用户界面,使用户易于操作和读取数据。
  • 节能:优化电源管理,如在无操作时自动进入低功耗模式,延长电池寿命。

    通过这样的设计,可以实现一个功能全面、操作简便、测量准确的电子秤。这不仅是一个实用的测量工具,也是一个很好的嵌入式系统设计和编程学习项目。

三、头文件选择和变量定义:

基于51单片机的电子秤系统,它包含了ADC0832模数转换器的控制、LCD显示控制以及一些变量和常量的定义。下面是对这段代码的详细介绍:

3.1 包含的头文件

  • reg51.h:51单片机的寄存器定义头文件。
  • intrins.h:包含了一些内部函数,如循环移位等。
  • absacc.h:用于直接访问存储器空间,如XBYTE。
  • math.h:数学函数库,可能用于数据处理。

3.2 宏定义

  • #define uchar unsigned char#define uint unsigned int:定义了两个常用的数据类型别名。
  • #define BUSY 0x80:定义了一个常量,可能在LCD控制中用于检查LCD是否忙。
  • #define DATAPORT P0:定义了数据端口,可能是LCD的数据端口。

3.3 ADC0832的引脚定义

  • ADCS, ADDI, ADDO, ADCLK:定义了ADC0832模数转换器的控制引脚。

3.4 LCD的引脚定义

  • LCM_RS, LCM_RW, LCM_EN:定义了LCD的控制引脚。

3.5 变量定义

  • ad_data, key:是ADC转换数据和按键状态。
  • alldata[12], love[14]:是用于存储数据的数组。
  • exit, yes, kind, fu, pfu, position1, position2:是用于控制程序流程的标志变量。
  • data1, data2, data3, ddata:是用于存储采样值的变量。
  • Alarm_led_red, Alarm_led_green:定义了报警LED的控制引脚。
  • press_data, ad_alarm, press_ge, press_shifen, press_baifen, press_qianfen:可能是用于存储重量数据和报警值的变量。

3.6 字符串数组

  • str0[], str2[], str3[]:定义了用于LCD显示的字符串。

3.7 功能说明

这段代码定义了电子秤系统所需的基本元素,包括ADC的控制、LCD的控制、报警LED的控制以及一些用于数据处理和存储的变量。ADC0832用于将重量传感器输出的模拟信号转换为数字信号,然后通过51单片机进行处理,并将结果显示在LCD上。报警LED用于在重量超出预设范围时发出警报。

还需要包含具体的函数实现,如ADC0832的读取函数、LCD的初始化和显示函数、按键处理函数、数据处理函数等。这些函数通常会在主循环或中断服务程序中被调用,以实现电子秤的完整功能。
#include<reg51.h>
#include<intrins.h>
#include <absacc.h>
#include <math.h>

#define uchar unsigned char
#define uint   unsigned int
#define BUSY  0x80          //常量定义
#define DATAPORT P0


//ADC0832的引脚
sbit ADCS =P3^5;  //ADC0832 chip seclect
sbit ADDI =P3^7;  //ADC0832 k in
sbit ADDO =P3^7;  //ADC0832 k out
sbit ADCLK =P3^6;  //ADC0832 clock signal

sbit LCM_RS=P2^0;
sbit LCM_RW=P2^1;
sbit LCM_EN=P2^2;

uchar ad_data,key;
uchar rrr=0xff;
uchar alldata[12]={0};
uchar love[14];
uchar exit=0,yes=0,kind=0,fu=0,pfu=0,position1=0,position2=0;
unsigned long  data1=0,data2=0,data3=0,ddata=0;    //采样值存储
sbit Alarm_led_red =P3^0;                         //超过重量表量程最大值红色led报警定义
sbit Alarm_led_green=P3^1;                        //低于零表量程最小值绿色led报警定义
//adc采样值存储单元
char press_data;                                  //标度变换存储单元
unsigned char ad_alarm;                           //报警值存储单元
unsigned char press_ge=0;                        //显示值百位
unsigned char press_shifen=0;                      //显示值十位
unsigned char press_baifen=0;                       //显示值个位
unsigned char press_qianfen=0;                      //显示值十分位

uchar code str0[]={"Weight:  .   Kg "};
uchar code str2[]={"Price: "};
uchar code str3[]={"Total:          "};

四、函数封装与作用

列出了一系列函数声明,这些函数构成了电子秤系统的核心功能。下面是对这些函数的简要介绍:

4.1 延时函数

  • void delay(uint);:一个简单的延时函数,接受一个无符号整数参数,用于产生指定时间的延时。

4.2 LCD相关函数

  • void lcd_wait(void);:检查LCD是否忙的函数,用于在写入指令或数据前等待LCD准备好。
  • void delay_LCM(uint);:专为LCD操作设计的延时函数,可能用于确保LCD操作的稳定性。
  • void initLCM(void);:初始化LCD的函数,设置LCD的工作模式等。
  • void WriteCommandLCM(uchar WCLCM,uchar BusyC);:向LCD写入指令的函数,接受指令和是否检查忙状态的参数。
  • void WriteDataLCM(uchar WDLCM);:向LCD写入数据的函数。
  • void DisplayOneChar(uchar X,uchar Y,uchar DData);:在LCD指定位置显示单个字符的函数。
  • void DisplayListChar(uchar X,uchar Y,uchar code *DData);:在LCD指定位置显示一串字符的函数。

4.3 错误处理函数

  • void error(void);:处理错误的函数,可能在系统检测到错误时被调用。

4.4 数据处理函数

  • unsigned long shi(uchar k);:可能是一个数据处理函数,接受一个字符参数,返回一个无符号长整数。
  • void out(void);:输出函数,可能用于将数据输出到外部设备或显示。

4.5 按键扫描函数

  • uchar keyscan(void);:扫描按键状态的函数,返回一个字符值,可能代表按键的状态或编码。

4.6 显示相关函数

  • void display(void);void display(uchar);:显示函数,可能用于更新LCD显示。
  • void keydisplay(uchar);:结合按键和显示的函数,可能在按键操作后更新显示。
  • void prodis(void);:可能是一个处理显示的函数,用于更新显示内容。
  • void clear(void);:清除LCD显示的函数。
  • void datapc(void);:可能是一个数据处理函数,用于将数据发送到PC或其他设备。
  • void remove0(void);:可能用于移除数据中的前导零。
  • void data3dis(void);:可能是一个显示函数,用于显示数据。

4.7 ADC0832相关函数

  • uchar Adc0832(unsigned char channel);:读取ADC0832转换结果的函数,接受通道参数。

4.8 报警函数

  • void alarm(void);:报警函数,可能在检测到异常情况时被调用。

4.9 数据处理函数

  • void data_pro(void);:数据处理函数,可能用于处理ADC转换后的数据。
void delay(uint);
void lcd_wait(void);
void delay_LCM(uint);                                 //LCD延时子程序
void initLCM( void);                                   //LCD初始化子程序
void lcd_wait(void);                                  //LCD检测忙子程序
void WriteCommandLCM(uchar WCLCM,uchar BusyC);      //写指令到ICM子函数
void WriteDataLCM(uchar WDLCM);                     //写数据到LCM子函数
void DisplayOneChar(uchar X,uchar Y,uchar DData);        //显示指定坐标的一个字符子函数
void DisplayListChar(uchar X,uchar Y,uchar code *DData); //显示指定坐标的一串字符子函数
void error(void);
unsigned long shi(uchar k);
void out(void);                     
uchar keyscan(void);                   
void display(void); 
void  display(uchar); 
void  keydisplay(uchar);
void  prodis(void);       
void  clear(void);
void  datapc(void);
void remove0(void);
void  data3dis(void);                                       //系统显示子函数
uchar Adc0832(unsigned char channel);                                                            
void alarm(void);
void data_pro(void);
这些函数共同构成了电子秤系统的软件框架,包括了LCD的控制、按键的扫描、数据的采集和处理、以及错误处理和报警功能。每个函数都需要具体的实现代码,这些代码通常会在主循环或中断服务程序中被调用,以实现电子秤的完整功能。

五、主函数设计:

主程序(`main`函数),用于控制电子设备(可能是一个电子秤)。该程序包括系统初始化、显示信息、数据采集、报警、数据处理、显示更新和按键扫描等操作。下面一步步介绍代码中的每个部分:
  1. delay(500); - 调用延时函数,参数是500毫秒(ms)。系统启动时先进行延时,这通常是为了确保电源稳定或其他硬件初始化完成。

  2. ad_data=0; - 初始化变量ad_data为0。ad_data可能被用来存放模数转换后的采样值。

  3. initLCM(); - 调用初始化LCD的函数,该函数用来配置LCD的初始状态和参数。

  4. WriteCommandLCM(0x01,1); - 向LCD发送一个清屏命令,0x01通常是LCD指令集中清除显示并返回首行首列的指令。参数1表示在发送指令前检查LCD是否忙。

  5. DisplayListChar(0,0,str0); - 在LCD上的第一行第一列显示一个字符串str0

  6. 注释掉的WriteCommandLCM(0x01,0); - 这是另一个清屏命令,但被注释掉了,且其参数0表示在发送指令时不检查LCD是否忙,这行代码不会被执行。

  7. DisplayListChar(0,1,str2); - 在LCD的第二行第一列显示另一个字符串str2

  8. while(1) - 主程序的无限循环开始,使得程序可以持续运行,直到设备被关闭。

    • ad_data =Adc0832(0); - 从ADC0832的通道0读取模数转换后的数据并存储到ad_data

    • alarm(); - 调用报警函数,可能基于某些条件(如ad_data的值)来判断是否需要发出警报信号。

    • data_pro(); - 调用数据处理函数,处理采样值,并可能更新全局变量或进行其他操作。

    • display(); - 调用更新显示的函数,可能根据处理后的数据更新LCD显示的内容。

    • key=keyscan(); - 调用按键扫描函数,并将返回的按键状态或编码存储到变量key

    • delay(5); - 在每次循环的末尾调用延时函数,参数是5ms,用来控制循环的速度。

    • if(exit==1) - 检查一个名为exit的条件是否被设置为1,这可能是一个全局变量,用来控制何时退出循环或进行特殊处理。

    • keydisplay(key); - 如果exit条件为真,则调用keydisplay函数,将按键状态或编码显示在LCD或其他显示设备上。

      这个程序构建了一个循环,不断地采集数据、处理数据、更新显示,并检测按键输入。注释和代码结构表明这可能是用于开发目的的测试程序,一个正在运行的嵌入式系统的简化版本。

void main(void)
{ 
    delay(500);                      //系统延时500ms启动
    ad_data=0;                       //采样值存储单元初始化为0
       initLCM( );

       WriteCommandLCM(0x01,1);            //清显示屏
    DisplayListChar(0,0,str0);
//     WriteCommandLCM(0x01,0);     //????????
       DisplayListChar(0,1,str2);

    while(1)
    {
       ad_data =Adc0832(0);       //采样值存储单元初始化为0
       alarm();
       data_pro();
       display();
       key=keyscan();
       delay(5);
       if(exit==1)
          keydisplay(key);     
     }

 }

六、仿真电路设计:

6.1 单片机选择

选择一个适合的单片机作为控制核心。常见的选择包括8051、AVR、PIC或ARM系列的单片机。在Proteus中,你可以找到这些单片机的模型。

6.2 称重传感器

电子秤的核心是称重传感器,它将重量转换为电信号。在Proteus中,你使用一个模拟的传感器模型,或者使用一个电阻应变片模型来模拟传感器的行为。

6.3 ADC(模数转换器)

由于称重传感器输出的是模拟信号,你需要一个ADC来将这个信号转换为数字信号,以便单片机可以处理。ADC0832是一个常见的选择,它是一个8位的串行ADC,可以在Proteus中找到。

6.4. LCD显示

电子秤需要一个LCD来显示重量和其他信息。在Proteus中,你可以添加一个标准的16x2或20x4 LCD模块。

6.5. 电源和稳压电路

确保为整个系统提供稳定的电源。需要一个稳压器来为单片机和LCD提供稳定的电压。

6.6 按键输入

电子秤可能需要一些按键来执行不同的功能,如去皮、单位切换等。在Proteus中,你可以添加简单的按钮或矩阵键盘。

6.7 仿真电路设计步骤

  • 打开Proteus软件,创建一个新的设计。
  • 添加单片机模型到设计中,并配置其引脚。
  • 添加称重传感器模型,并将其输出连接到ADC的输入。
  • 添加ADC0832模型,并将其输出连接到单片机的相应引脚。
  • 添加LCD模型,并将其连接到单片机的I/O引脚。
  • 添加电源和稳压电路,确保所有组件都能获得所需的电压。
  • 添加按键输入,并将其连接到单片机的I/O引脚。
  • 编写或导入单片机的控制代码,并将其加载到单片机模型中。
  • 运行仿真,观察电子秤的行为是否符合预期。

6.8 注意事项

  • 确保所有的连接都是正确的,包括电源、地线、信号线等。
  • 在仿真之前,检查代码是否正确地实现了电子秤的功能。
  • 如果仿真结果不符合预期,检查电路连接和代码逻辑。

    可以在Proteus中设计并仿真一个基于单片机的电子秤电路。请注意,Proteus是一个软件仿真工具,实际的硬件设计和调试可能会有所不同。

    6.9 整体仿真电路设计

    6.10 51单片机部分电路设计

    6.11 矩阵键盘设计

七、运行效果:

7.1 压力数据采集

7.2 数据显示

7.3 按键调试设置

八、总结

编程知识

  1. C语言编程:代码是用C语言编写的,这是一种广泛用于嵌入式系统开发的编程语言。
  2. 单片机编程:代码展示了如何编写控制单片机(可能是8051、AVR、PIC等)的程序,包括初始化、数据采集、显示更新和按键处理。
  3. 函数调用:代码中使用了多个自定义函数,如delayinitLCMWriteCommandLCMDisplayListCharAdc0832alarmdata_prodisplaykeyscan,这展示了如何组织代码和模块化编程。
  4. 无限循环while(1)结构用于创建一个无限循环,这是嵌入式系统中常见的模式,用于持续执行任务。

硬件知识

  1. 单片机系统:了解了单片机在嵌入式系统中的作用,以及如何通过编程控制其行为。
  2. 模数转换器(ADC):ADC0832的使用展示了如何将模拟信号转换为数字信号,这对于处理传感器数据至关重要。
  3. LCD显示:学习了如何在单片机系统中使用LCD来显示信息,包括如何发送命令和数据到LCD。
  4. 传感器接口:了解了如何将称重传感器连接到单片机系统,并如何处理其输出的模拟信号。

仿真知识

  1. Proteus软件:学习了如何使用Proteus进行电路设计和仿真,这是一个流行的电子设计自动化(EDA)工具。
  2. 电路设计:了解了设计电子秤电路所需的关键组件,包括单片机、传感器、ADC、LCD和按键。
  3. 仿真流程:掌握了在Proteus中创建电路、添加组件、连接电路、编写代码和运行仿真的基本流程。

系统集成知识

  1. 系统初始化:学习了如何对单片机系统进行初始化,包括设置初始状态和配置外设。
  2. 数据处理:了解了如何采集数据、处理数据和更新显示,这是嵌入式系统中的常见任务。
  3. 用户交互:学习了如何处理用户输入,如按键扫描,以及如何根据用户输入更新系统行为。

    通过这些知识,你可以更好地理解嵌入式系统的开发过程,包括硬件设计、软件编程和系统集成。这些技能对于从事电子工程、自动化、计算机工程和相关领域的专业人士来说是非常重要的。