【设计题目】:基于单片机的电子秤设计【设计要求】:(1)设计一款电子秤,用LCD液晶显示器显示被称物体的质量(2)可以设定该秤所称的上限(3)当物体超重时,能自动报警【设计过程】1.【方案设计】1.1电子秤的组成1.1.1电子秤的基本结构电子秤是利用物体的重力作用来确定物体质量(重量)的测量仪器,也可用来确定与质量相关的其它量大小、参数、或特性。
不管根据什么原理制成的电了秤均由以下三部分组成:(1)承重、传力复位系统它是被称物体与转换元件之间的机械、传力复位系统,又称电子秤的秤体,一般包括接受被称物体载荷的承载器、秤桥结构、吊挂连接部件和限位减振机构等。
(2) 称重传感器即由非电量(质量或重量)转换成电量的转换元件,它是把支承力变换成电的或其它形式的适合于计量求值的信号所用的一种辅助手段。
(3) 测量显示和数据输出的载荷测量装置即处理称重传感器信号的电子线路(包括放人器、模数转换、电流源或电压源、调节器、补尝元件、保护线路等)和指示部件(如显示、打印、数据传输和存贮器件等)。
1.1.2电子秤的工作原理当被称物体放置在秤体的秤台上时,其重量便通过秤体传递到称重传感器,传感器随之产生力一电效应,将物体的重量转换成与被称物体重量成一定函数关系(一般成正比关系)的电信号(电压或电流等)。
此信号由放大电路进行放大、经滤波后再由模/数( A/D)器进行转换,数字信号再送到微处器的CPU处理,CPU不断扫描键盘和各功能开关,根据键盘输入容和各种功能开关的状态进行必要的判断、分析、由仪表的软件来控制各种运算。
运算结果送到存贮器,需要显示时,CPU发出指令,从存贮器中读出送到显示器显示,或送打印机打印。
1.2本设计思路本设计的主要思路是:利用压力传感器采集因压力变化产生的电压信号,经过电压放大电路放大,然后再经过模数转换器转换为数字信号,最后把数字信号送入单片机。
单片机经过相应的处理后,得出当前所称物品的重量,然后显示出来。
主要技术指标为:称量围0~600g,分度值1kg,精度等级III级,电源AC220V。
2.【器件选择】按照本设计功能的要求,系统由5个部分组成:控制器部分、测量部分、数据显示部分、键盘部分、语音提示部分和电路电源部分,系统设计总体方案框图如图1所示。
图1设计思路框图测量部分是利用称重传感器检测压力信号,得到微弱的电信号(本设计为电压信号),而后经处理电路(如滤波电路,差动放大电路,)处理后,送单片机中的A/D 转换器,将模拟量转化为数字量输出,控制器接受来自A/D 转换器输出的数字信号,经过复杂的运算,将数宁信号转换为物体的实际重量信号,并将其送到显示单元中。
2.1控制器部分本设计使用单片机作为系统的主控制器。
根据总体方案设计的分析,设计这样一个简单的的系统,可以选用带A/D 转换器的单片机,由于应用程序不大,应用程序直接存储存片,不用在外部扩展存储器,这样电路也可简化。
在这里选用STC 生产的STC12C5A60S2单片机。
STC12C5A60S2与MCS-51相比有如下优势:第一, 指令集与MCS-51系列单片机完全兼容。
第二, 片存储器采用闪速存储器,并且支持SPI-ISP 在线编程,使程序写入更加方便,提高了调试效率,缩短了开发周期。
第三,提供了更小尺寸的芯片,使整个硬件电路体积更小。
第四,单指令周期,运行速度高。
第五,自带上电复位电路,可减低单片机外围电路的复杂程度。
第六,置8路10位高速A/D转换,转换速度25万次/秒。
STC12C5A60S2部带有60KB的程序存储器,并且带有8路10位精度的A/D转换器,基本上已经能够满足我们的需要。
STC12C5A60S2单片机的引脚图如图2所示。
图2 STC12C5A60S2单片机的引脚图2.2数据采集部分电子秤的数据采集部分主要包括称重传感器、处理电路电路,因此对于这部分的论证主要分两方面。
2.2.1传感器的选择传感器量程的选择可依据秤的最大称量值、选用传感器的个数、秤体的自重、可能产生的最人偏载及动载等因素综合评价来确定。
一般来说,传感器的量程越接近分配到每个传感器的载荷,其称量的准确度就越高。
根据设计需要,确定传感器的额定载荷为1Kg,允许过载为150%F.S,精度为0.05%,最大量程时误差±0.1kg,可以满足本系统的精度要求。
综合考虑,本设计采用SP20C-G501电阻应变式传感器,其最人量程为1Kg.该传感器测量精度高、温度特性好、工作稳定等优点,广泛用于各种结构的动、静态测量及各种电子秆的一次仪表。
该称重传感器主要由弹性体、电阻应变片电缆线等组成,其工作原理如图3所示。
图3 称重传感器原理图2.2.2放大电路选择由称重传感器的称量原理可知,采用转换电路,把应变计的△R/R变化转换成电压或电流变化,但是这个电压或电流信号很小,需要增加增益放大电路来把这个电压或电流信号转换成可以被A/D转换器接收的信号。
在前级处理电路部分,我们考虑可以采用以下几种方案:方案一:利用普通低温漂运算放大器构成前级处理电路;普通低温漂运算放大器构成多级放大器会引入大量噪声。
由于A/D转换器需要很高的精度,所以几毫伏的干扰信号就会直接影响最后的测量精度。
所以,此种方案不宜采用。
方案二:主要由高精度低漂移运算放大器构成差动放大器,而构成的前级处理电路;差动放人器具有高输入阻抗,增益高的特点,可以利用普通运放(如OP07)做成一个差动放大器。
一般说来,集成化仪用放大器具有很高的共模抑制比和输入阻抗,因而在传统的电路设计中都是把集成化仪器放人器作为前置放人器。
然而,绝人多数的集成化仪器放大器,特别是集成化仪器放大器,它们的共模抑制比与增益相关:增益越高,共模抑制比越大。
为了实现信号的放人,其设计电路如图4所示:图4 利用高精度低漂移运放设计的差动放大器前级采用运放Al和A2组成并联型差动放大器,使其输入阻抗为无穷大,共模抑制比也为无穷大。
阻容耦合电路放存由并联型差动放大器构成的前级放大器和由仪器放大器构成的后级放大器之间,这样可为后级仪器放大器提高增益,进而提高电路的共模抑制比提供了条件。
后级电路采用廉价的仪器放大器,将双端信号转换为单端信号输出。
由于阻容耦合电路的隔直作用,后级的仪器放大器可以做到很高的增益,进而得到很高的共模抑制比。
3.【系统电路设计】3.1 主控制器电路主控制器是STC12C5A60S2单片机,其外围电路简单,只需要加上晶振电路和电源就可以工作。
主控制器电路如图5所示。
图5 主控制系统3.2 传感器放大电路传感器放大电路由两级组成,前级由两个同相比例运算电路组成,后级是一个差动比例运算电路。
传感器信号首先进过前级进行初步放大,接着进入后级。
由于前级的对称性直接影响后级的共模抑制比,考虑到元件阻值的误差,R2,R4选用多圈精密可调电阻。
为了提高后级对共模信号的抑制,反馈电阻R3也采用精密多圈可调电阻。
传感器放大电路如图6所示。
图6 传感器放大电路3.3显示电路1602液晶模块的引脚连线如图7。
其中,第1、2脚为液晶的驱动电源;第三脚VL为液晶的对比度调节,通过在VCC和GND之间接一个10K多圈可调电阻,中间抽头接VL,可实现液晶对比度的调节;液晶的控制线RS、R/W、E 分别接单片机的P0.5、P0.6、P0.7;数据口接在单片机的P2口;BL+、BL-为液晶背光电源。
图7 1602液晶模块的接线图3.4报警电路的设计当电路检测到称重的物体超过仪器的测量限制时,将产生一个信号给报警电路。
使报警电路报警从而提醒工作人员注意,超限报警电路如图8所示。
图8 报警电路图它是由89S52的P2.6口来控制的,当超过设置的重量时(5Kg),通过程序使P2.6口值为高电平,从而使三极管导通,接通报警电路,使蜂鸣器SPEAKER 发出警报声,同时使报警灯LED发光。
4.【软件设计】程序设计是一个复杂的工作,为了把复杂的工作条理化,就要有相应的步骤和方法。
其步骤可概括为以下三点:(1)分析系统控制要求,确定算法:对复杂的问题进行具体的分析,找出合理的计算方法及适当的数据结构,从而确定编写程序的步骤。
(2)根据算法画流程图:画流程图可以把算法和解题步骤逐步具体化,以减少出错的可能性。
(3)编写程序:根据程序图所表示的算法和步骤,选用适当的指令排列起来,构成一个有机的整体,即程序。
4.1主程序的设计主程序的功能是系统初始化,管理和调用各个子程序。
本设计的程序流程图如图9所示。
图9主程序流程4.2子程序设计4.2.1A/D 转换启动及数据读取程序A/D 转换子程序主要是指在系统开始运行时,把称重传感器传递过来的模拟信号转换成数字信号并传递到单片机的程序设计。
设计流程图如图10所示。
Y图10 A/D转换启动及数据读取程序流程图4.2.2显示子程序设计显示子程序主要是来判断是否需要显示,以及如何去显示。
设计显示子程序的流程图如图11所示:图11显示子程序流程图4.2.3报警子程序的设计由于要求有报警电路,可以将设定的阀值与实时显示的值进行比较,如果设定值小于实时显示的值,则将P1.0置为1,就报警。
程序流程图如图12所示。
Y Y图12 报警子程序框图5.【结果分析】实验中在称重物时,电子秤能够测量出物体的重量,当物体重量大于600克时,会发出警报。
综上所述,设计出的电子秤能够正常的进行工作。
6.【设计总结】(1)设计中出现的问题及解决方案始用C语言编写代码时,出现很多小错误。
比如变量还没定义就直接使用了;书写不规,不该用分号的地方用了,括号不配对等;没有注意大小写的区别。
这些都是根据提示找到出错的语句直接改正就可以。
在重量调整子程序中,设置了一个上限量程,在重量超过了上限时直接使用beep()函数,但是这时并不报警,才发现还没定义这个函数,接下来在下面定义了报警函数,还是不行,原来必行在调用之前定义或是先声明了才能在调用之后定义这个函数。
(2)个人体会通过本次课程设计,加深了对单片机的理解,并且更加熟悉了单片机的整个设计流程。
经过对电子称的设计,加深了对传感器的理解以及更加了解到日常生活中传感器与我们实际生活的联系。
在设计过程中出现了许多错误,导致一些程序无法运行,但经过不断的努力,终于克服了困难,完成了设计的任务及要求。
由于设计时间有限,只能在以后的学习过程中做更进一步的改进和提高。
7.【参考文献】[1]茂泰智能仪器原理及应用[M].:电子工业2009.4[2]马忠梅单片机的C语言应用程序设计[M].:航空航天大学.2009.8[3]瑞新单片机原理及应用教程[M].机械工业.2011.7[4]王东峰单片机C语言应用100例[M].:电子工业.2009.5[5]平等单片机入门与开发[M].:机械工业.2010.1[6]毅刚MCS-51单片机应用设计[M].:工业大学.2011.9附录:#include "config.h"//---------------------------------------------------------------------// SPEED1 SPEED0 A/D转换所需时间#define AD_SPEED 0x60 // 0110,0000 1 1 90 个时钟周期转换一次,// CPU工作频率21MHz时A/D转换速度约300KHz//#define AD_SPEED 0x40 //0100,0000 1 0 140 个时钟周期转换一次//#define AD_SPEED 0x20 //0010,0000 0 1 280 个时钟周期转换一次//#define AD_SPEED 0x00 //0000,0000 0 0 420 个时钟周期转换一次//---------------------------------------------------------------------unsigned int get_AD_result(unsigned char channel){unsigned char AD_finished=0; //存储A/D 转换标志ADC_RES = 0; //A/D 转换结果高8位ADC_RESL = 0; //A/D 转换结果低2位channel &= 0x07; //0000,0111 清0高5位ADC_CONTR = AD_SPEED;_nop_();ADC_CONTR|=0xE0; //1110,0000清ADC_FLAG,ADC_START位和低三位ADC_CONTR |= channel; //选择A/D 当前通道_nop_();ADC_CONTR |= 0x80; //启动A/D 电源delay(1); //使输入电压达到稳定ADC_CONTR |= 0x08; //0000,1000 令ADCS = 1, 启动A/D转换AD_finished = 0;while (AD_finished == 0 ) //等待A/D转换结束{AD_finished = (ADC_CONTR & 0x10); //0001,0000 测试A/D转换结束否}ADC_CONTR &= 0xE7; //1111,0111 清ADC_FLAG 位, 关闭A/D转换return (ADC_RES<<2|ADC_RESL);//返回转换后的结果}void WriteDataLCD(unsigned char WDLCD){ReadStatusLCD(); //检测忙LCD_Data = WDLCD;LCD_RS = 1;LCD_RW = 0;LCD_E = 0; //若晶振速度太高可以在这后加小的延时LCD_E = 0;LCD_E = 0; //延时LCD_E = 1;}void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCD(); //根据需要检测忙LCD_Data = WCLCD;LCD_RS = 0;LCD_RW = 0;LCD_E = 0;LCD_E = 0;LCD_E = 0;LCD_E = 1;}unsigned char ReadDataLCD(void){LCD_RS = 1;LCD_RW = 1;LCD_E = 0;LCD_E = 0;LCD_E = 0;LCD_E = 1;return(LCD_Data);}unsigned char ReadStatusLCD(void){LCD_Data = 0xFF;LCD_RS = 0;LCD_RW = 1;LCD_E = 0;LCD_E = 0;LCD_E = 0;LCD_E = 1;delay_18B20(200);// Delay5Ms(); //检测忙信号proteus仿真时,延迟5MS,关闭while循环while (LCD_Data&Busy) //硬件使用时,不延迟,打开while循环return(LCD_Data);}void LCDInit(void){LCD_Data = 0;WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); // 显示光标移动设置WriteCommandLCD(0x0C,1); // 显示开及光标设置}void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码WriteDataLCD(DData);}void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData){unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]!='\0') //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}void Delay5Ms(void){unsigned int TempCyc = 5552;while(TempCyc--);}void Delay400Ms(void){unsigned char TempCycA = 5;unsigned int TempCycB;while(TempCycA--){TempCycB=7269;while(TempCycB--);}}。