标题:
基于51单片机的车辆电子秤程序与Proteus仿真图 六路电子秤取平均值
[打印本页]
作者:
anan111
时间:
2023-4-3 12:09
标题:
基于51单片机的车辆电子秤程序与Proteus仿真图 六路电子秤取平均值
有六路电子秤取平均值,可现实实时时间,检测车辆是否停止在合适位置,轮胎下压力传感器可获取车辆质量。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
1.png
(85.54 KB, 下载次数: 40)
下载附件
2023-4-4 04:46 上传
51hei.gif
(97.39 KB, 下载次数: 45)
下载附件
2023-4-4 04:45 上传
单片机源程序如下:
#include <reg52.h>
#include <intrins.h> //包含NOP空指令函数_nop_
#include <stdio.h>
#include "LCD1602.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
#define MC 1388
#define BC -5
#define KC 2
//------------------------------ADC0832的引脚------------------------------
sbit ADCS =P2^3; //ADC0832 chip seclect
sbit ADDI =P2^5; //ADC0832 k in
sbit ADDO =P2^5; //ADC0832 k out
sbit ADCLK =P2^4;
sbit RED =P3^6;
sbit LOUD =P2^6;
sbit Motor=P3^7;
//-----------------------------定义ADC0808使用的IO口-----------------------
sbit ST= P3^3; //启动信号
sbit EOC=P3^4; //转换结束信号
sbit OE= P3^5; //输出使能
sbit CLK=P2^7; //时钟信号
//-----------------------------定义74LS165使用的IO口-----------------------
sbit SO=P1^0; //输出端
sbit SH= P1^1; //移位控制(低电平有效)
sbit SCK=P1^2; //时钟信号
sbit ACS=P1^3;
sbit BCS= P1^4;
sbit CCS=P1^5;
sbit ALE=P1^6;
void delaynms(uint x);
void adc0808(unsigned char channel);
void Delay_ms(unsigned int n);
unsigned int Adc0832(unsigned char channel);
void Display_weight(void);
void Display_IRrd(void);
uchar one_weight(uchar count);
float avr_weight(void);
void Tishi(void);
//void display_D(uint x);
unsigned char HC165(void);
uint ad_0809,a4=0;
float weight1;
unsigned int weight2;
//uchar table[]="D: ";
uchar table1[]="W: . t D: ";
char DisplayData[18]="22 - : : ";
void datapros()
{
Ds1302ReadTime(); //反馈时间TIME
DisplayData[2] = TIME[4]/16+0x30;
DisplayData[3] = (int)(TIME[4]&0x0f)+0x30; //月
DisplayData[5] = TIME[3]/16+0x30;
DisplayData[6] = (int)(TIME[3]&0x0f)+0x30; //日
DisplayData[8] = TIME[2]/16+0x30; //时
DisplayData[9] = (int)(TIME[2]&0x0f)+0x30;
DisplayData[11] = TIME[1]/16+0x30; //分
DisplayData[12] = (int)(TIME[1]&0x0f)+0x30;
DisplayData[14] = TIME[0]/16+0x30; //秒
DisplayData[15] = (int)(TIME[0]&0x0f)+0x30;
}
void main()
{
int i;
Init_LCD1602();
// RED=0;
TMOD=0x02; //T0工作模式2
TH0=0x14;
TL0=0x14;
ET0=1;
EA=1;//允许中断
TR0=1;
SCK = 1;
SH = 0;//读
SH = 1;//暂停读
while(1)
{
//-------------时间显示-------------------
datapros(); //数据处理函数
LCD1602_write_com(0x80);
for(i=0;i<18;i++)
{
LCD1602_write_data(DisplayData[i]);
}
//-------------距离和重量-----------------
LCD1602_write_com(0x80+0x40);//屏幕显示命令
Display_IRrd();
Display_weight();//称重
Tishi();//报警
}
}
void Timer0_INT() interrupt 1
{
CLK=~CLK;
}
//-------------------------------给ad8080延时函数------------------------------
void delaynms(uint x)
{
while(x-->0)
{
unsigned char k;
for(k=10;k>0;k--);
}
}
//------------------------------显示距离函数----------------------------
void adc0808(unsigned char channel)
{
if(channel==0) {ACS=0;BCS= 0;CCS=0;}//0/0
else if(channel==1) {ACS=1;BCS= 0;CCS=0;}//4/1
else if(channel==2) {ACS=0;BCS= 1;CCS=0;}//2/2
else if(channel==3) {ACS=1;BCS= 1;CCS=0;}//6/3
else if(channel==4) {ACS=0;BCS= 0;CCS=1;}//1/4
else if(channel==5) {ACS=1;BCS= 0;CCS=1;}//5/5
OE=0;
ALE=1;
ST=1;
ALE=0;
ST=0;
while(!EOC);
OE=1;
// display_D(HC165()); //显示转换的数据
}
//-----------------------------读拓展芯片?---------------------------
unsigned char HC165(void)
{
unsigned char i;
unsigned char Temp, Temp1;
SCK = 1;
SH = 0; //HC165???
SH = 1; //??HC165???
Temp1 = 0;
if(SO == 1)
{
Temp1 |= 0x01;
}
for(i = 0;i < 7;i++)
{
SCK = 0;
SCK = 1;
Temp1 <<= 1;
if(SO == 1)
{
Temp1 |= 0x01;
}
}
SCK = 0;
Temp = Temp1;
return(Temp);;
}
//----------------MS延时函数(12M晶振下测试)--------------------------------
void Delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
//-------------------显示物体重量-------------------------------
void Display_weight(void)
{
unsigned int i;
weight1 = avr_weight();
weight2=(int)(weight1*10);// 放大10倍,便于后面的计算
table1[2]=(weight2/1000)+0x30;
table1[3]=(weight2%1000)/100+0x30;
table1[4]=((weight2%1000)%100)/10+0x30;
table1[6]=((weight2%1000)%100)%10+0x30;
for(i=0;i<16;i++)
{
LCD1602_write_data(table1[i]);
}
}
//-------------------计算单重量-----------------------------
uchar one_weight(uchar count)
{
float press;
unsigned char weight;
adc0808(count);
weight = HC165();
if(14<weight<243) //有效值的范围 当压力值介于15kpa到115kpa之间时,遵循线性变换
{
int vary=weight;
press=((10.0/23.0)*vary)+9.3;//公式测试时补偿值为9.3
}
return press;
}
//-------------------计算平均重量-----------------------------
float avr_weight(void)
{
float w1,w2,w3,w4,w5,w6,w_avr;
w1=one_weight(0);
Delay_ms(100);
w2=one_weight(1);
Delay_ms(100);
w3=one_weight(2);
Delay_ms(100);
w4=one_weight(3);
Delay_ms(100);
w5=one_weight(4);
Delay_ms(100);
w6=one_weight(5);
Delay_ms(100);
w_avr = (w1+w2+w3+w4+w5+w6)/6.0;
return w_avr;
}
//-------------------显示红外距离-------------------------------
void Display_IRrd(void)
{
unsigned char d=0;
d= Adc0832(0);
d = ( (MC*1.0) / ((d+BC)*1.0) ) - (KC*1.0);
table1[11]=d/100+0x30; //百位
table1[12]=(d%100)/10+0x30; //十位
table1[13]=d%10+0x30; //个位
}
//--------------------采集并返回--------------------------------
unsigned int Adc0832(unsigned char channel) //AD转换,返回结果
{
unsigned char i=0;
unsigned char j;
unsigned int dat=0;
unsigned char ndat=0;
if(channel==0)channel=2;
if(channel==1)channel=3;
ADDI=1;
_nop_();
_nop_();
ADCS=0;//拉低CS端
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿1
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=channel&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿2
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=(channel>>1)&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿3
ADDI=1;//控制命令结束
_nop_();
_nop_();
dat=0;
for(i=0;i<8;i++)
{
dat|=ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
dat<<=1;
if(i==7)dat|=ADDO;
}
for(i=0;i<8;i++)
{
j=0;
j=j|ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
j=j<<7;
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
Keil代码与Proteus8.13仿真下载:
电子秤V2.0.zip
(447.2 KB, 下载次数: 42)
2023-4-3 12:07 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1