标题:
电子秤仿真与单片机代码
[打印本页]
作者:
jarvispipi
时间:
2017-6-8 16:34
标题:
电子秤仿真与单片机代码
没事做了一个电子秤仿真
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
电子秤.PNG
(58.74 KB, 下载次数: 120)
下载附件
2017-6-8 16:34 上传
单片机代码:
#include<reg52.h>
#include<intrins.h>
#include"delay.h"
#define uchar unsigned char
#define uint unsigned int
#define WRITE_ADDR 0x90
#define AD_COMMAND 0x00
#define READ_ADDR 0x91
/*管脚定义*/
sbit SDA = P2^0;
sbit SCL = P2^1;
sbit shumaguan1 = P3^4;
sbit shumaguan2 = P3^5;
sbit shumaguan3 = P3^6;
sbit shumaguan4 = P3^7;
sbit xiaoshudian = P0^7;
sbit alarm = P2^2;
/*共阴极数码管编码*/
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*全局变量*/
uchar adc_data = 0; //记录每一次读取的adc数据
uchar key_value =0; //记录每一次按键值
uchar temp_data[4] = {0}; //记录输入的单价
uchar point_place = 0; //记录小数点位置
uchar wei_shu = 0; //记录总共数据位数
uchar equal_sign = 0; //记录是否按下“=”号
uchar interrupt_flag = 0; //发生中断标记
uint price = 0; //用来记录单价
/*微秒级别延时(5us)*/
void delay_us()
{;;}
/*毫秒级别延时(z微妙)*/
void delay_ms(unsigned int z)
{
unsigned int x,y;
for(x = z;x > 0;x--)
for(y = 120 ;y>0;y--);
}
/*报警*/
void beep_on(void)
{
alarm = 0;
}
void beep_off(void)
{
alarm = 1;
}
/*键盘读取函数*/
uchar keyboard_read()
{
uchar key,temp;
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay_ms(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:
key=7;
break;
case 0xde:
key=8;
break;
case 0xbe:
key=9;
break;
case 0x7e:
key='/';
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay_ms(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:
key=4;
break;
case 0xdd:
key=5;
break;
case 0xbd:
key=6;
break;
case 0x7d:
key='*';
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xfb;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay_ms(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:
key=1;
break;
case 0xdb:
key=2;
break;
case 0xbb:
key=3;
break;
case 0x7b:
key='-';
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay_ms(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:
key='.';
break;
case 0xd7:
key=0;
break;
case 0xb7:
key='=';
break;
case 0x77:
key='+';
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
return key;
}
/*iic开始信号*/
void start()
{
SCL = 1;
_nop_();
SDA = 1;
delay_us();
SDA = 0;
delay_us();
SCL = 0;//拉低时钟线,开始信号以后方便更改SDA 上面的数据来发送
_nop_();
}
/*iic 停止信号*/
void stop()
{
SCL = 1;
_nop_();
SDA = 0;
delay_us();
SDA = 1;
delay_us();
}
/*回复响应信号*/
void respond()
{
SCL = 1;
_nop_();
SDA = 0;
delay_us();
SCL = 0; //凡是在一个小节后拉低SCL 都是为了方便接下来的 数据传输
_nop_();
}
/*不响应*/
void norespond()
{
SCL = 1;
_nop_();
SDA = 1;
delay_us();
}
/*初始化iic总线*/
void init_iic_line()
{
SCL = 1;
_nop_();
SDA = 1;
_nop_();
}
/*往iic设备发送数据,先发送数据的最高位 */
void write_byte(uchar value)
{
uchar i,temp;
temp = value;
for(i = 0;i<8;i++)
{
SCL = 0;
_nop_();
if((temp & 0x80) == 0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
SCL = 1;
_nop_();
temp <<=1;
}
SCL = 0;
_nop_();
}
/*读取iic设备发送过来的数据*/
uchar read_byte()
{
uchar i, return_value = 0;
SDA = 1;//释放数据线,交给从机控制
_nop_();
SCL = 0;
_nop_();
for(i = 0;i<8;i++)
{
SCL = 1;
if(SDA == 1)
{
return_value = return_value |0x01;
}
if(i<7)//这里很重要
{
return_value <<= 1;
}
SCL = 0;
_nop_();
}
return return_value;
}
/*显示一个数码管*/
void display_one(uchar value)
{
P0 = table[value];
}
/*初始化iic设备*/
void init_iic_device()
{
start();
write_byte(WRITE_ADDR);
respond();
write_byte(AD_COMMAND);
respond();
}
/*读取adc数据*/
uchar read_adc_data()
{
uchar adc_data = 0;
start();
write_byte(READ_ADDR);
respond();
adc_data = read_byte();
norespond();
stop();
return adc_data;
}
/*adc数据处理*/
void adc_data_process()
{
long temp_weight;
temp_weight = ((long)adc_data)*1000/51;
temp_data[0] = temp_weight/1000;
temp_data[1] = temp_weight%1000/100;
temp_data[2] = temp_weight%1000%100/10;
temp_data[3] = temp_weight%1000%100%10;
point_place = 1;
wei_shu = 4;
}
/*选择哪个数码管亮*/
void shumaguan_slect_on(uchar num)
{
uchar temp = 4;
temp = temp-(wei_shu -num);
switch(temp)
{
case 0:
shumaguan1 = 0;
break;
case 1:
shumaguan2 = 0;
break;
case 2:
shumaguan3 = 0;
break;
case 3:
shumaguan4 = 0;
break;
default:
break;
}
}
/*选择哪个数码管熄灭*/
void shumaguan_slect_off(uchar num)
{
uchar temp = 4;
temp = temp-(wei_shu -num);
switch(temp)
{
case 0:
shumaguan1 = 1;
break;
case 1:
shumaguan2 = 1;
break;
case 2:
shumaguan3 = 1;
break;
case 3:
shumaguan4 = 1;
break;
default:
break;
}
}
void clear_led(void)
{
shumaguan1 = 1;
shumaguan2 = 1;
shumaguan3 = 1;
shumaguan3 = 1;
}
/*显示子程序,支持显示重量,单价,总价*/
void display()
{
uchar i;
clear_led();
for(i = 0;i < wei_shu;i++)
{
if((i + 1) == point_place)
{
shumaguan_slect_off(i);
display_one(temp_data[i]);
xiaoshudian = 1;
shumaguan_slect_on(i);
delay_ms(5);
shumaguan_slect_off(i);
}
else
{
shumaguan_slect_off(i);
display_one(temp_data[i]);
shumaguan_slect_on(i);
delay_ms(5);
shumaguan_slect_off(i);
}
}
}
/*计算总价并将总价每一位分离*/
void calculate_total_price()
{
int temp_number = 0 ;
unsigned long total_price = 0;
switch(wei_shu -point_place)
{
case 3:
temp_number = 100;
break;
case 2:
temp_number = 10;
break;
case 1:
temp_number = 1;
break;
}
total_price = (unsigned long)price * (unsigned long)adc_data*1000;
total_price = total_price/51/temp_number/1000;
if(total_price <10000&&total_price>999)
{
temp_data[0] = total_price/1000;
temp_data[1] = total_price%1000/100;
temp_data[2] = total_price%1000%100/10;
temp_data[3] = total_price%1000%100%10;
wei_shu = 4;
point_place = 3;
}
else if(total_price <1000&&total_price >99)
{
temp_data[0] = total_price/100;
temp_data[1] = total_price%100/10;
temp_data[2] = total_price%100%10;
wei_shu = 3;
point_place = 2;
}
else if(total_price < 100&&total_price>9)
{
temp_data[0] = total_price/10;
temp_data[1] = total_price%10;
wei_shu = 2;
point_place = 1;
}
else
{
temp_data[0] = total_price/10;
temp_data[1] = total_price%10;
wei_shu = 2;
point_place = 1;
}
}
/*中断初始化*/
void interrupt_init()
{
EA = 1; //开总中断
IT0 = 0; //设置外部中断0为下降沿触发
EX0 = 1; //开外部中断0
P1 = 0xf0; //初始化矩阵键盘外部引脚电平
}
int main()
{
interrupt_init();
init_iic_line();
init_iic_device();
/*读取传感器并显示重量,直到键盘输入重量跳出*/
while(1)
{
if(interrupt_flag != 1)
{
adc_data = read_adc_data();
adc_data_process();
display();
}
else
{
clear_led();
break;
}
}
/*显示从键盘输入的单价*/
while(1)
{
if(equal_sign != 1)
{
display();
adc_data = read_adc_data();
if(adc_data == 0)
{
break;
}
}
else
{
break;
}
}
/*计算总价并显示,直到重量为0 ,表示称量物品已经离开,回到程序开始执行处*/
calculate_total_price();
while(1)
{
adc_data = read_adc_data();
if(adc_data != 0)
{
display();
}
else
{
uchar i = 0;
for(i = 0 ; i<4 ; i++)
{
temp_data[i] = 0;
}
adc_data = 0;
key_value = 0;
point_place = 0;
wei_shu = 0;
equal_sign = 0;
interrupt_flag = 0;
price = 0;
break;
}
}
return 0;
}
/***************************中断处理函数************************/
void keyboard_int(void) interrupt 0
{
EA = 0;
/*清除数据 */
if(interrupt_flag == 0)
{
wei_shu = 0;
point_place = 0;
}
/*读取键盘值*/
key_value = keyboard_read();
if(key_value != '=')
{
if(wei_shu <4)
{
if(key_value!='.')
{
temp_data[wei_shu] = key_value;//将价格存入数组temp_data中
wei_shu ++;
price = price *10 + key_value;
}
else
{
point_place = wei_shu; //记录小数点位置
}
}
}
else
{
equal_sign = 1;
}
interrupt_flag = 1;
P1 = 0xf0;
EA = 1;
}
复制代码
作者:
T阿里巴巴
时间:
2017-6-9 13:05
代码很简洁,功能很强大,应该是一个实用的电子秤
作者:
winwinwin
时间:
2017-12-14 23:11
可以,好资料,51黑有你更精彩!!!
作者:
平生顾
时间:
2017-12-23 22:32
楼主真心棒!
作者:
512713659
时间:
2018-5-12 17:43
那个u2是什么啊 看不清
作者:
qqflyrnm
时间:
2018-11-29 13:49
附件呢
作者:
AaronHe
时间:
2018-11-30 00:45
可以,好好看看
作者:
zhouyidahaoren
时间:
2020-6-23 18:38
没有传感器呀
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1