有六路電子秤取平均值,可現實實時時間,檢測車輛是否停止在合適位置,輪胎下壓力傳感器可獲取車輛質量。
仿真原理圖如下(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
|