有六路电子秤取平均值,可现实实时时间,检测车辆是否停止在合适位置,轮胎下压力传感器可获取车辆质量。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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)
|