找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 831|回复: 0
打印 上一主题 下一主题
收起左侧

基于51单片机的车辆电子秤程序与Proteus仿真图 六路电子秤取平均值

[复制链接]
跳转到指定楼层
楼主
有六路电子秤取平均值,可现实实时时间,检测车辆是否停止在合适位置,轮胎下压力传感器可获取车辆质量。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h> //包含NOP空指令函数_nop_
  3. #include <stdio.h>
  4. #include "LCD1602.h"
  5. #include "ds1302.h"

  6. #define uchar unsigned char
  7. #define uint  unsigned int
  8. #define MC 1388
  9. #define BC -5
  10. #define KC 2
  11. //------------------------------ADC0832的引脚------------------------------
  12. sbit ADCS =P2^3;  //ADC0832 chip seclect
  13. sbit ADDI =P2^5;  //ADC0832 k in
  14. sbit ADDO =P2^5;  //ADC0832 k out
  15. sbit ADCLK =P2^4;


  16. sbit RED =P3^6;
  17. sbit LOUD =P2^6;
  18. sbit Motor=P3^7;

  19. //-----------------------------定义ADC0808使用的IO口-----------------------
  20. sbit ST= P3^3;                //启动信号
  21. sbit EOC=P3^4;                //转换结束信号
  22. sbit OE= P3^5;                //输出使能
  23. sbit CLK=P2^7;                //时钟信号
  24. //-----------------------------定义74LS165使用的IO口-----------------------
  25. sbit SO=P1^0;                //输出端
  26. sbit SH= P1^1;                //移位控制(低电平有效)
  27. sbit SCK=P1^2;                //时钟信号
  28. sbit ACS=P1^3;               
  29. sbit BCS= P1^4;               
  30. sbit CCS=P1^5;               
  31. sbit ALE=P1^6;        
  32. void delaynms(uint x);
  33. void adc0808(unsigned char channel);
  34. void Delay_ms(unsigned int n);
  35. unsigned int Adc0832(unsigned char channel);
  36. void Display_weight(void);
  37. void Display_IRrd(void);
  38. uchar one_weight(uchar count);
  39. float avr_weight(void);
  40. void Tishi(void);
  41. //void display_D(uint x);
  42. unsigned char HC165(void);
  43. uint ad_0809,a4=0;
  44. float weight1;
  45. unsigned int weight2;
  46. //uchar table[]="D:     ";
  47. uchar table1[]="W:   . t D:     ";
  48. char DisplayData[18]="22  -     :  :   ";

  49. void datapros()         
  50. {
  51.   Ds1302ReadTime();      //反馈时间TIME

  52.   DisplayData[2] = TIME[4]/16+0x30;
  53.   DisplayData[3] = (int)(TIME[4]&0x0f)+0x30;                        //月

  54.   DisplayData[5] = TIME[3]/16+0x30;
  55.   DisplayData[6] = (int)(TIME[3]&0x0f)+0x30;     //日
  56.         
  57.         DisplayData[8] = TIME[2]/16+0x30;                                                        //时
  58.         DisplayData[9] = (int)(TIME[2]&0x0f)+0x30;        
  59.         

  60.         DisplayData[11] = TIME[1]/16+0x30;                                                //分
  61.         DisplayData[12] = (int)(TIME[1]&0x0f)+0x30;        

  62.         DisplayData[14] = TIME[0]/16+0x30;                                                //秒
  63.         DisplayData[15] = (int)(TIME[0]&0x0f)+0x30;
  64. }



  65. void main()
  66. {
  67.         int i;
  68.   Init_LCD1602();
  69. //        RED=0;
  70.         TMOD=0x02;                                //T0工作模式2
  71.         TH0=0x14;               
  72.         TL0=0x14;
  73.         ET0=1;
  74.         EA=1;//允许中断
  75.         TR0=1;
  76.         SCK = 1;
  77.         SH = 0;//读
  78.         SH = 1;//暂停读
  79. while(1)
  80. {
  81.   //-------------时间显示-------------------
  82.         datapros();                                                 //数据处理函数        
  83.         LCD1602_write_com(0x80);
  84.         for(i=0;i<18;i++)
  85.         {
  86.                 LCD1602_write_data(DisplayData[i]);
  87.         }
  88.         //-------------距离和重量-----------------
  89.         
  90.         LCD1602_write_com(0x80+0x40);//屏幕显示命令
  91.         Display_IRrd();
  92.         Display_weight();//称重
  93.         Tishi();//报警
  94. }
  95. }

  96. void Timer0_INT() interrupt 1
  97. {
  98.         CLK=~CLK;
  99. }

  100. //-------------------------------给ad8080延时函数------------------------------
  101. void delaynms(uint x)        
  102. {
  103. while(x-->0)
  104.         {
  105.           unsigned char k;
  106.           for(k=10;k>0;k--);
  107.         }
  108. }
  109. //------------------------------显示距离函数----------------------------

  110. void adc0808(unsigned char channel)
  111. {
  112.                
  113.                 if(channel==0)        {ACS=0;BCS= 0;CCS=0;}//0/0
  114.     else if(channel==1)        {ACS=1;BCS= 0;CCS=0;}//4/1
  115.                 else if(channel==2)        {ACS=0;BCS= 1;CCS=0;}//2/2
  116.     else if(channel==3)        {ACS=1;BCS= 1;CCS=0;}//6/3
  117.                 else if(channel==4)        {ACS=0;BCS= 0;CCS=1;}//1/4
  118.     else if(channel==5)        {ACS=1;BCS= 0;CCS=1;}//5/5
  119.                 OE=0;
  120.                 ALE=1;
  121.                 ST=1;
  122.                 ALE=0;
  123.                 ST=0;
  124.                 while(!EOC);
  125.                 OE=1;
  126.                
  127.         //        display_D(HC165());                //显示转换的数据
  128. }

  129. //-----------------------------读拓展芯片?---------------------------
  130. unsigned char HC165(void)
  131. {
  132.   unsigned char i;
  133.     unsigned char Temp, Temp1;
  134.     SCK = 1;
  135.     SH = 0;        //HC165???
  136.     SH = 1;        //??HC165???
  137.     Temp1 = 0;
  138.     if(SO == 1)
  139.                 {
  140.                         Temp1 |= 0x01;
  141.                 }
  142.                 for(i = 0;i < 7;i++)
  143.     {   
  144.         SCK = 0;  
  145.         SCK = 1;  
  146.         Temp1 <<= 1;
  147.         if(SO == 1)
  148.         {
  149.             Temp1 |= 0x01;
  150.         }
  151.     }
  152.         SCK = 0;  
  153.                  Temp = Temp1;
  154.   return(Temp);;
  155.         }
  156. //----------------MS延时函数(12M晶振下测试)--------------------------------

  157. void Delay_ms(unsigned int n)
  158. {
  159.         unsigned int  i,j;
  160.         for(i=0;i<n;i++)
  161.                 for(j=0;j<123;j++);
  162. }

  163. //-------------------显示物体重量-------------------------------

  164. void Display_weight(void)
  165. {
  166.                 unsigned int i;
  167.                 weight1 = avr_weight();
  168.                 weight2=(int)(weight1*10);//         放大10倍,便于后面的计算
  169.                
  170.                 table1[2]=(weight2/1000)+0x30;
  171.                 table1[3]=(weight2%1000)/100+0x30;
  172.                 table1[4]=((weight2%1000)%100)/10+0x30;
  173.                 table1[6]=((weight2%1000)%100)%10+0x30;
  174.         for(i=0;i<16;i++)
  175.         {
  176.                 LCD1602_write_data(table1[i]);
  177.         }
  178.         
  179. }
  180. //-------------------计算单重量-----------------------------
  181. uchar one_weight(uchar count)
  182. {        
  183.          float  press;
  184.          unsigned char weight;
  185.         adc0808(count);
  186.         weight = HC165();
  187.          if(14<weight<243)        //有效值的范围                  当压力值介于15kpa到115kpa之间时,遵循线性变换            
  188.                  {        
  189.                 int        vary=weight;
  190.                 press=((10.0/23.0)*vary)+9.3;//公式测试时补偿值为9.3
  191.                 }
  192.         return press;
  193.         
  194. }
  195. //-------------------计算平均重量-----------------------------
  196. float avr_weight(void)
  197. {
  198.         float  w1,w2,w3,w4,w5,w6,w_avr;
  199.         w1=one_weight(0);
  200.         Delay_ms(100);
  201.         w2=one_weight(1);
  202.         Delay_ms(100);
  203.         w3=one_weight(2);
  204.         Delay_ms(100);
  205.         w4=one_weight(3);
  206.         Delay_ms(100);
  207.         w5=one_weight(4);
  208.         Delay_ms(100);
  209.         w6=one_weight(5);
  210.         Delay_ms(100);
  211.         w_avr = (w1+w2+w3+w4+w5+w6)/6.0;
  212.         return w_avr;
  213.         
  214. }
  215. //-------------------显示红外距离-------------------------------
  216. void Display_IRrd(void)
  217. {
  218.   unsigned char d=0;
  219.         d= Adc0832(0);
  220.         d = ( (MC*1.0) / ((d+BC)*1.0) ) - (KC*1.0);
  221.         table1[11]=d/100+0x30;                //百位
  222.         table1[12]=(d%100)/10+0x30;        //十位
  223.         table1[13]=d%10+0x30;                        //个位
  224. }
  225. //--------------------采集并返回--------------------------------
  226. unsigned int Adc0832(unsigned char channel)     //AD转换,返回结果
  227. {
  228.     unsigned char i=0;
  229.     unsigned char j;
  230.     unsigned int dat=0;
  231.     unsigned char ndat=0;

  232.     if(channel==0)channel=2;
  233.     if(channel==1)channel=3;
  234.         
  235.     ADDI=1;
  236.     _nop_();
  237.     _nop_();
  238.     ADCS=0;//拉低CS端
  239.     _nop_();
  240.     _nop_();
  241.     ADCLK=1;//拉高CLK端
  242.     _nop_();
  243.     _nop_();
  244.     ADCLK=0;//拉低CLK端,形成下降沿1
  245.     _nop_();
  246.     _nop_();
  247.     ADCLK=1;//拉高CLK端
  248.     ADDI=channel&0x1;
  249.     _nop_();
  250.     _nop_();
  251.     ADCLK=0;//拉低CLK端,形成下降沿2
  252.     _nop_();
  253.     _nop_();
  254.     ADCLK=1;//拉高CLK端
  255.     ADDI=(channel>>1)&0x1;
  256.     _nop_();
  257.     _nop_();
  258.     ADCLK=0;//拉低CLK端,形成下降沿3
  259.     ADDI=1;//控制命令结束
  260.     _nop_();
  261.     _nop_();
  262.     dat=0;
  263.     for(i=0;i<8;i++)
  264.     {
  265.         dat|=ADDO;//收数据
  266.         ADCLK=1;
  267.         _nop_();
  268.         _nop_();
  269.         ADCLK=0;//形成一次时钟脉冲
  270.         _nop_();
  271.         _nop_();
  272.         dat<<=1;
  273.         if(i==7)dat|=ADDO;
  274.     }  
  275.     for(i=0;i<8;i++)
  276.     {
  277.         j=0;
  278.         j=j|ADDO;//收数据
  279.         ADCLK=1;
  280.         _nop_();
  281.         _nop_();
  282.         ADCLK=0;//形成一次时钟脉冲
  283.         _nop_();
  284.         _nop_();
  285.         j=j<<7;
  286. ……………………

  287. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

Keil代码与Proteus8.13仿真下载:
电子秤V2.0.zip (447.2 KB, 下载次数: 38)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表