标题:
单片机电子秤的仿真设计
[打印本页]
作者:
Y_1111
时间:
2018-4-19 17:14
标题:
单片机电子秤的仿真设计
电子秤的仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
(23.88 KB, 下载次数: 50)
下载附件
2018-4-20 02:47 上传
0.jpg
(36.77 KB, 下载次数: 38)
下载附件
2018-4-20 02:48 上传
单片机源程序如下:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define PLEN 7
#define WLEN 4
#define MLEN 4
#define SUMLEN 10
#define BEEP() P1^=(1<<0);//蜂鸣器
#define Key_NO (P2&0x0F)
#define delay4us() {_nop_(); _nop_(); _nop_(); _nop_();}
#define Key_Pressed (P2&(1<<4)) //DA(P1^4)为高电平时表示有键按下
//#define Key_NO (P2&0x0F) /、//解码器输出线连接在P1低四位
sbit RS=P1^1; //寄存器选择引脚,搞电平选择数据寄存器,低电平选择指令寄存器
sbit RW=P1^2; //读写操作使能引脚,高电平使能读操作,低电平使能写操作
sbit E=P1^3; //总使能引脚
sbit FMQ=P1^0; //蜂鸣器
sbit CS=P3^5;
sbit CLK=P3^6;
sbit DIO=P3^7;
volatile int AD_Result,Pre_Result=0,Pressure_Value=0,Pressure_Value1=0,AD_Result1=0;
code char KEY_CHAR_TABLE[]="0123456789.BCDEF"; //键盘字符表
//----------------------AD转换程序--------------//
uchar GET_CHx_AD_Value(uchar ch)
{
uchar i,dat1=0,dat2=0;
CS=0;CLK=0;
DIO=1;
_nop_(); _nop_();
CLK=1;
_nop_(); _nop_();
CLK=0;DIO=1;
//_nop_(); _nop_();
_nop_(); _nop_();
CLK=1; _nop_(); _nop_();
CLK=0;DIO=ch;
_nop_(); _nop_();
CLK=1;
_nop_(); _nop_();
CLK=0;DIO=1;
_nop_(); _nop_();
for(i=0;i<8;i++)
{
CLK=1; _nop_(); _nop_();
CLK=0; _nop_(); _nop_();
dat1=(dat1<<1)|DIO;
}
for(i=0;i<8;i++)
{
dat2=dat2|((uchar)DIO<<i);
CLK=1; _nop_(); _nop_();
CLK=0; _nop_(); _nop_();
}
CS=1;
return (dat1==dat2)?dat1:0x00;
}
//--------------------延时子函数--------//
void delay(uchar x)
{
uchar t;while(x--) for(t=0;t<120;t++) ;
}
/*//-----------------------单键扫描子函数-------------//
unsigned char JP()
{
unsigned char x=0x00;
bit i=0;
x=P2; //扫描Y坐标
FMQ=0; //响起蜂鸣器
delay(125); //延时去抖动
P2=0x0f;
delay(2);
x+=P2; //扫描X坐标
switch(x)
{
case 0xee:x=0x30;break; //按下0
case 0xed:x=0x31;break; //按下1
case 0xeb:x=0x34;break; //按下4
case 0xe7:x=0x37;break; //按下7
case 0xde:x=0x46;break; //按下F
case 0xdd:x=0x32;break; //按下2
case 0xdb:x=0x35;break; //按下5
case 0xd7:x=0x38;break; //按下8
case 0xbe:x=0x45;break; //按下E
case 0xbd:x=0x33;break; //按下3
case 0xbb:x=0x36;break; //按下6
case 0xb7:x=0x39;break; //按下9
case 0x7e:x=0x44;break; //按下D
case 0x7d:x=0x43;break; //按下C
case 0x7b:x=0x42;break; //按下B
case 0x77:x=0x41;break; //按下A
default:x=0xff;break;
}
//FMQ=1; //关闭蜂鸣器
while(i==0) //等待按键松开
{
P2=0xf0;
delay(150);
if(P2==0xf0)
{
i=1;
}
else{i=0;}
}
return x; //返回x(ASCII码)
}*/
//------------------测忙-----------------//
bit Read_LCD_Busy_Flag()
{
uchar result;
P0=0xFF;
RS=0;RW=1;
E=1;delay4us(); result=P0; E=0;
return(result & 0x80)?1:0;
}
//------------------写指令-------------------------//
void write_com(uchar com)
{
while(Read_LCD_Busy_Flag());
RS=0;RW=0;
E=0;_nop_(); _nop_(); P0=com;
delay4us();E=1;delay4us();E=0;
}
//------------------写数据-------------------------//
void write_dat(uchar dat)
{
while(Read_LCD_Busy_Flag());
RS=1;RW=0;
E=0;P0=dat;delay4us();
E=1;delay4us();E=0;
}
//----------------------显示-----------------------------//
void LCD_Show_String(uchar r,uchar c,char *s )
{
uchar i=0;
uchar code DDRAM[]={0x80,0xC0};
write_com(DDRAM[r]|c);
while(s[i]&&i<16) write_dat(s[i++]);
}
//---------------1602初始化-----------------//
void initinal()
{
write_com(0x38);delay(1);
write_com(0x0C);delay(1);
write_com(0x06);delay(1);
write_com(0x01);delay(1);
}
//LCD显示输出缓冲(单价,重量,总价)
char disp_buffer_P[PLEN];
char disp_buffer_W[WLEN];
char disp_buffer_SUM[SUMLEN];
uchar NumberPtr=0; //价格输入缓冲的索引
////----------蜂鸣器输出------------//
void Sounder()
{
uchar i,j;
for(i=0;i<200;i++)
{
BEEP();
j=70;
while(--j);
}
}
//------------处理运算并显示余额 -----------//
void Compute_and_show_sum()
{
float p,w;
if(strlen(disp_buffer_P)==0)p=0;else
p=strtod(disp_buffer_P,'\0'); //价格未输入时,将p设为0,否则转换为float类型
w=strtod(disp_buffer_W,'\0'); //将重量字符串转换成float类型
sprintf(disp_buffer_SUM,"%.2f",p*w); //计算金额并生成字符串
LCD_Show_String(1,7,(char *)" " ); //清除金额,然后显示最新金额
LCD_Show_String(1,7,disp_buffer_SUM );
}
//处理键盘操作
void KeyBoard_Handle()
{
char KeyChar;
static uchar havedot=0; //是否已经输入的价格p的小数点
static uchar dtnum=PLEN; //在没有输入小数点时可继续输入的字符的个数(dtnum初始值为7)
if(Key_Pressed)
{
Sounder(); //按键提示音
KeyChar=KEY_CHAR_TABLE[Key_NO]; //获取按键字符
//如果输入的是数字字符或小数点并且此前没有输入过小数点
if(isdigit(KeyChar)||(KeyChar=='.'&&!havedot))
{
if(strlen(disp_buffer_P)==3&&(KeyChar!='.'&&!havedot)) //限制整数部分最高为三位数,及整数部分最大为999
return;
//将输入的字符存入缓冲
if(NumberPtr<dtnum)
{
// 如果输入的第一个字符是‘0’或者‘.’,就相当于直接输入了‘0.’
if(NumberPtr==0&&(KeyChar=='0'||KeyChar=='.'))
{
disp_buffer_P[NumberPtr++]='0';
KeyChar=='.';
disp_buffer_P[NumberPtr++]='.';
}
else
{
disp_buffer_P[NumberPtr++]=KeyChar;
}
disp_buffer_P[NumberPtr]='\0'; //加字符串结束标志
LCD_Show_String(0,3,disp_buffer_P ); //刷新显示总价
}
//输入字符为‘.’,且此前未输入过小数点,开始限定可输入的小数位数
if(KeyChar=='.'&&!havedot)
{
dtnum=NumberPtr+2;havedot=1;
}
}
if(KeyChar=='B') //清零操作
{
NumberPtr=0;
havedot=0;
dtnum=PLEN-2;
disp_buffer_P[0]='\0';
disp_buffer_SUM[0]='\0';
LCD_Show_String(0,3,(char *)" " ); //清除单价
LCD_Show_String(1,7,(char *)" " ); //清除总价
}
if(KeyChar=='C') //删除操作(可用于单价输入错误时)
{
write_com(0x80+NumberPtr+2); //确定删除对象
write_dat(' '); //显示空格即为删除
disp_buffer_P[--NumberPtr]=0; //删除后数据清零
write_com(0x80+NumberPtr); //为下次输入数据时写好位置,必须是在最后一个后面
}
if (Key_Pressed) Compute_and_show_sum();
while(Key_Pressed); //等待按键释放
}
}
//--------------------主函数-------------//
void main()
{
initinal();
LCD_Show_String(0,0,(char*)"P: W:");
LCD_Show_String(1,0,(char*)"SUM($):");
while(1)
{
AD_Result=GET_CHx_AD_Value(0) ;
Pressure_Value=(int)((AD_Result*5.0*2/511.0/5.1-0.04)/0.00369-3.45);
KeyBoard_Handle();
//M_Value=(int)(Pressure_Value*0.0101972);
if(Pressure_Value>=230) //超重报警
{ write_com(0x01);
LCD_Show_String(0,0,"ERROR!");
Sounder();
}
sprintf(disp_buffer_W,"%-3d",Pressure_Value);
LCD_Show_String(0,13,disp_buffer_W);
//KeyBoard_Handle();
//压力变化就计算金额
if(Pre_Result!=AD_Result)
{
Compute_and_show_sum();
Pre_Result=AD_Result;
Sounder();
}
delay(50);
}
}
复制代码
所有资料51hei提供下载:
最终版.zip
(102.99 KB, 下载次数: 111)
2018-4-19 17:13 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
飞洒area
时间:
2020-4-18 20:18
运行不了
作者:
sphns
时间:
2020-4-21 17:29
运行不了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1