电子信息与电气工程系课程设计报告课程设计任务书目录1 摘要: (4)关键字2 方案论证及选择: (5)2.1输入模块 (5)2.2显示模块 (5)3 系统硬件及功能: (5)3.1 单片机控制电路功能及介绍 (5)3.2 A\D转换 (6)3.3 3×4键盘 (7)3.4 LCD显示 (7)4 设计思路及程序流程图: (8)5 结果仿真: (9)6 总结与心得体会: (10)7 参考文献 (10)附录1:摘要现代社会的发展,对称重技术提出了更高的要求。
目前,台式电了秤在商业贸易中的使用已相当普遍,但存在较大的局限性:体积大、成本高、需要工频交流电源供应、携带不便、应用场所受到制约。
现有的便携秤为杆秤或以弹簧压缩、拉伸变形来实现计量的弹簧秤,居民用户使用的是国家已经明令淘汰的丰卜秤。
多年来,人们一直期待测量准确、携带方便、价格低廉的便携式电子秤投放市场。
木文设计了一种便携式电子秤,论述了仪器的工作原理,介绍了仪器的误差来源与误差分配,给出了仪器电路设计与软件流程,探讨了仪器的工程设计技术。
针对电容式称重传感器非线性影响大的问题,提出并建立了电容式称重传感器的非线性影响模型与校正模型,为便携式电子秤的低成本准确称量奠定了理论基础。
便携式电子秤主要由电源、称重传感器、单片机、键盘/开关、LCD显示器等部分构成。
主要技术指标为:称量范围0^- lOkg;分度值O.Olkg; 精度等级m级;电源DC 1.5V。
关键字:电子秤,A T89C51, LCD2:方案论证及选择:2.1: 输入模块方案一:采用独立式按键作为输入模块,其特点:直接用I/O口构成单个按键电路,接口电路配置灵活、软件结构简单,但是当键数较多时,占用I/O口较多;方案二:采用矩阵式键盘作为输入电路,其特点:电路和软件稍复杂,但相比之下,当键数越多时越节约I/O口。
本设计使用键盘输入价格值,若采用独立按键,对数值进行递增递减需频繁按键,为软件设计增加负担,且操作界面不友好。
若采用矩阵式按键,可以方便地输入一个价格值,节约了宝贵的I/O口资源。
通过对比,故采用方案二作为系统输入模块。
2.2:显示模块方案一:用LCD显示,液晶显示屏具有低耗电量,无辐射危险,以及影像不闪烁等优势,可视面积大,画面效果好,分辨率高,抗干扰能力强等特点。
方案二:采用LED数码管并行动态显示,电路简单,同样的功率驱动下,显示亮度不及静态显示,且占用I/O口较多。
综上所述,我们采用方案一使用了1602型号的的LCD进行显示,能显示出更多的重量值以及显示更大的总额从而扩大了称量范围。
3 系统硬件及功能:3.1单片机控制电路功能及介绍本设计中单片机控制电路是由AT89C51组成,它是一个低功耗,高性能CMOS 8位单片机,片内含4k Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。
AT89C51具有如下特点:40个引脚,4k Bytes Flash片内程序存储器,128 bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
图此外,AT89S51设计和配置了振荡频率可为0Hz并可通过软件设置省电模式。
空闲模式下,CPU暂停工作,而RAM定时计数器,串行口,外中断系统可继续工作,掉电模式冻结振荡器而保存RAM的数据,停止芯片其它功能直至外中断激活或硬件复位。
同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
3.2 A/D转换8 位 A/D 精度: 10Kg/1204=2.44g考虑到其他部分所带来的干扰 ,12 位 A/D 无法满足系统精度要求。
所以我们需要选择 14位或者精度更高的A/D。
方案一、逐次逼近型 A/D转换器,如:ADS7805、ADS7804等。
逐次逼近型 A/D转换,一般具有采样/保持功能。
采样频率高,功耗比较低,是理想的高速、高精度、省电型 A/D 转换器件。
高精度逐次逼近型 A/D转换器一般都带有内部基准源和内部时钟,基于89C52构成的系统设计时仅需要外接几个电阻、电容。
但考虑到所转换的信号为一慢变信号,逐次逼近型 A/D转换器的快速的优点不能很好的发挥,且根据系统的要求,14位AD足以满足精度要求,太高的精度就反而浪费了系统资源。
所以此方案并不是理想的选择。
方案二、双积分型 A/D转换器:如:ICL7135、ICL7109 ADC0808等。
双积分型 A/D转换器精度高,但速度较慢(如:ICL7135),具有精确的差分输入,输入阻抗高,可自动调零,超量程信号,全部输出于TTL电平兼容。
双积分型 A/D转换器具有很强的抗干扰能力。
对正负对称的工频干扰信号积分为零,所以对50HZ的工频干扰抑制能力较强,对高于工频干扰(例如噪声电压)已有良好的滤波作用。
只要干扰电压的平均值为零,对输出就不产生影响。
尤其对本系统,缓慢变化的压力信号,很容易受到工频信号的影响。
故而采用双积分型A/D转换器可大大降低对滤波电路的要求。
作为电子秤,系统对 AD的转换速度要求并不高,精度上8位的AD足以满足要求。
另外双积分型A/D转换器较强的抗干扰能力,和精确的差分输入,低廉的价格。
综合的分析其优点和缺点,我们最终选择了ADC0808。
3.3 3×4键盘3×4键盘采用扫描技术进行识别,处值是七个端口都是高电平,对各行进行扫描时,先令第一列全是低电平,若第一列为低电平就表示一行一列为选中即有键按下,若第二行为低电平即二行一列为选中即有键按下,以此类推就可以对所有的见进行编码了。
3.4 LCD显示1602型号的的LCD是能够显示16列2行的液晶显示器,功率小显示面积大。
4 设计思路及程序流程图压力传感器在我设计的系统中,由于只是仿真层面的所有我用力电位器代替,应为单片机只是采集变化的数字量,A\D转换器是将变化的模拟量即电压量,转化为数字量从而可以用电位器改变电压值得到数字量给单片机。
当改变电位器时就会得到相应的数字量,单片机对数字进行运算处理,处理好的数据就是所称的重量,当要输入物品单价时先把键盘的打开键闭合,此时就启动了键盘,然后输入数值,结束时按下确定键,当输入值超出了范围是系统会把最后一位输入同时对系统确定这时:单片机就会对数据处理,最终得到总价。
并且显示会没一步进行显示在对应的位置。
软件流程图5 结果仿真1:当输入不超出位时:开始键盘启动输入单价调节电位器计算总金额结束显示单价及重量显示总金额2:当输入超出位时:6.总结与体会两周的课程设计结束了,虽然不轻松但是我学到是很多知识,尽管单片机我们课堂上学了而且感觉还不错但是在实际应用中会发现很多问题,即使很小的错误都能导致很大的错误,我经常会犯的错误就是重复定义不知为什么但是经过了这个课程设计之后,我会不自觉的注意这个问题,特别当对共阴还是共阳管道应用上,在定义时老会出现反的情况,这样就导致根本就的不到值,还有一个问题是我在写键盘程序时用了死循环,然后在最后把所有模块连接时就出现键盘和称重不能同时进行的情况。
从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高。
参考文献1.《手把手教你学单片机》周兴华著北京航空航天出版社 2005.42.《单片机原理及接口技术》余锡存曹国华著西安电子科技出版社 1999.113.李朝青.单片机原理及接口技术(简明修订版).杭州:北京航空航天大学出版社,19984.李广弟.单片机基础[M].北京:北京航空航天大学出版社,19945.阎石.数字电子技术基础(第三版). 北京:高等教育出版社,19896.廖常初.现场总线概述[J].电工技术,1999.附录:源程序#include <reg52.h>#include "chushi.h"#include"jianpan.h"void main(){ void jianpan();void delay2();OE=0; //定时1开TMOD=0x02;TH1=(65536-400)/256;TL1=(65536-400)%256;TR1=1;ET1=1;EA=1;ST=1;ST=0;Lcd_Init();while(1){if(ctrl==0){set=!set;while(ctrl==0);geat=1;t=0;num5=0;}if(set==1){jianpan();}if(EOC==1&&set==0){OE=1;num1=P3;delay2();OE=0;delay2();ST=1;ST=0;num1=num1*9999/255;count[0]=num1%10000/1000;count[1]=num1%1000/100;count[2]=num1%100/10;count[3]=num1%10;max=num1*up;count[7]=max%10000000/1000000; count[8]=max%1000000/100000; count[9]=max%100000/10000;count[10]=max%10000/1000;count[11]=max%1000/100;count[12]=max%100/10;count[13]=max%10;DisplayOneChar(0,1,'j'); DisplayOneChar(1,1,'g'); DisplayOneChar(2,1,':'); DisplayString(6,1,"max:"); DisplayOneChar(9,1,count[7]+0x30); DisplayOneChar(10,1,count[8]+0x30); DisplayOneChar(11,1,count[9]+0x30); DisplayOneChar(12,1,count[10]+0x30); DisplayOneChar(13,1,count[11]+0x30); DisplayOneChar(14,1,count[12]+0x30); DisplayOneChar(15,1,count[13]+0x30);DisplayString(0,0,"dj:");DisplayOneChar(3,0, count[0]+0x30); DisplayOneChar(4,0,count[1]+0x30); DisplayOneChar(5,0,count[2]+0x30); DisplayOneChar(6,0,count[3]+0x30);}}}void delay2(){unsigned char i,j,k;for(k=2;k>0;k--)for(i=2;i>0;i--)for(j=248;j>0;j--);}void Lcd_Init(void);void Lcd_WriteCmd(unsigned char TempData,unsigned char BuysC); void Lcd_WriteData(unsigned char TempData);void Lcd_ReadStatus(void);//unsigned char Lcd_ReadData(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayString(unsigned char X, unsigned char Y, unsigned char *DData); void Delay(unsigned int delaytime);void Lcd_WriteData(unsigned char TempData){Lcd_ReadStatus();Lcd_Data = TempData;Lcd_RS = 1;Lcd_RW = 0;Lcd_E = 0;Lcd_E = 0;Lcd_E = 1;}//写指令void Lcd_WriteCmd(unsigned char TempData,unsigned char BuysC) {if (BuysC) Lcd_ReadStatus();Lcd_Data = TempData;Lcd_RS = 0;Lcd_RW = 0;Lcd_E = 0;Lcd_E = 0;Lcd_E = 1;}//读数据/*unsigned char Lcd_ReadData(void){Lcd_RS = 1;Lcd_RW = 1;Lcd_E = 0;Lcd_E = 0;Lcd_E = 0;Lcd_E = 0;Lcd_E = 1;return(Lcd_Data);}*/void Lcd_ReadStatus(void){Delay(500);}void Lcd_Init(void) //LCM初始化{Lcd_Data = 0;Lcd_WriteCmd(0x38,0); //三次显示模式设置,不检测忙信号Delay(6000);Lcd_WriteCmd(0x38,0);Delay(6000);Lcd_WriteCmd(0x38,0);Delay(6000);Lcd_WriteCmd(0x38,1); //显示模式设置,开始要求每次检测忙信号Lcd_WriteCmd(0x08,1); //关闭显示Lcd_WriteCmd(0x01,1); //显示清屏Lcd_WriteCmd(0x06,1); // 显示光标移动设置Lcd_WriteCmd(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; //算出指令码Lcd_WriteCmd(X, 0); //这里不检测忙信号,发送地址码Lcd_WriteData(DData);}//按指定位置显示一串字符void DisplayString(unsigned char X, unsigned char Y, unsigned char *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 Delay(unsigned int delaytime){while(delaytime--);}void t1(void) interrupt 3 using 0{clock1=!clock1;TH1=(65536-4000)/256;TL1=(65536-4000)%256;}int count[20],up=0,down=0;unsigned char tab1[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; unsigned char tab2[3]={0x9d,0xfd,0xff};long int num1,max;int wd=25,a=0,b=0;char aa,ab,ac,ad,ae=0,af=0,ag=0;unsigned char num3=0,num4;float num2;sbit L0=P2^0;sbit L1=P2^1;sbit L2=P2^2;sbit L3=P2^3;sbit clock1=P2^4;sbit OE=P2^7;sbit ST=P2^5;sbit EOC=P2^6;sbit hot=P2^0;sbit cold=P2^1;sbit lie1=P1^0;sbit lie2=P1^1; sbit lie3=P1^2;sbit han1=P1^3;sbit han2=P1^4;sbit han3=P1^5;sbit han4=P1^6;sbit ctrl=P1^7;unsigned char temp,i,j,key,set=0,geat,t=0,num5,c,d=1;void Lcd_Init(void);void Lcd_WriteCmd(unsigned char TempData,unsigned char BuysC);void Lcd_WriteData(unsigned char TempData);void Lcd_ReadStatus(void);unsigned char Lcd_ReadData(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayString(unsigned char X, unsigned char Y, unsigned char *DData); void Delay(unsigned int delaytime);sbit Lcd_RW=P2^1;sbit Lcd_RS=P2^0;sbit Lcd_E=P2^2;//sbit KM=P3^7;//sbit led=P3^4;//sbit speak=P3^5;#define Lcd_Data P0#define Busy 0x80void jianpan(){if(geat==1){count[1]=tab1[0];count[2]=tab1[0];count[3]=tab1[0];count[4]=tab1[0];}geat=0;P1=0xff;lie1=0;temp=P1;temp=temp&0xf8;if(temp!=0xf8){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P1;temp=temp&0xf8;if(temp!=0xf8){if(han1==0) key=3;if(han2==0) key=6;if(han3==0) key=9;if(han4==0) {key=11;set=0;}}while(han1==0||han2==0||han3==0||han4==0);if(t==1) { up=key;}if(t==2) { up=up*10+key;}if(t==3) {up=up*10+key;}}P1=0xff;lie2=0;temp=P1;temp=temp&0xf8;if(temp!=0xf8){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P1;temp=temp&0xf8;if(temp!=0xf8){if(han1==0) key=2;if(han2==0) key=5;if(han3==0) key=8;if(han4==0) key=0;}while(han1==0||han2==0||han3==0||han4==0); t++;if(t==1) { up=key;}if(t==2) { up=up*10+key;}if(t==3) {up=up*10+key;}}P1=0xff;lie3=0;temp=P1;temp=temp&0xf8;if(temp!=0xf8){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P1;temp=temp&0xf8;if(temp!=0xf8){if(han1==0) key=1;if(han2==0) key=4;if(han3==0) key=7;if(han4==0) key=10;}while(han1==0||han2==0||han3==0||han4==0);if(t==1) { up=key;}if(t==2) { up=up*10+key;}if(t==3) {up=up*10+key;}if(key==10) {t=0;up=0;}}count[4]=up%1000/100;count[5]=up%100/10;count[6]=up%10; DisplayOneChar(0,1,'j'); DisplayOneChar(1,1,'g'); DisplayOneChar(2,1,':'); DisplayOneChar(3,1,count[4]+0x30); DisplayOneChar(4,1,count[5]+0x30); DisplayOneChar(5,1,count[6]+0x30); }。