找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2255|回复: 0
收起左侧

单片机电子秤仿真+程序

[复制链接]
ID:363250 发表于 2018-7-2 16:22 | 显示全部楼层 |阅读模式
电子秤程序   仿真
0.png
0.png

单片机源程序如下:
  1. /********************************************************
  2.                    压力测试仪
  3. 系统描述;输入  15--115kPA压力信号
  4.          输出  00h--ffh数字信号(adc0832)
  5.          在LCD上显示实际的压力值,如果超限则报警

  6. 线性区间标度变换公式:    y=(115-15)/(243-13)*X+15kpa   

  7. 作者:
  8. 日期:2018.6.27

  9. ********************************************************/

  10. #include <reg51.h>
  11. #include <intrins.h>
  12. #include <absacc.h>
  13. #include <math.h>

  14. #define uchar unsigned char
  15. #define uint   unsigned int
  16. #define BUSY  0x80                               //常量定义
  17. #define DATAPORT P1


  18. //ADC0832的引脚
  19. sbit ADCS =P3^5;  //ADC0832 chip seclect
  20. sbit ADDI =P3^7;  //ADC0832 k in
  21. sbit ADDO =P3^7;  //ADC0832 k out
  22. sbit ADCLK =P3^6;  //ADC0832 clock signal

  23. sbit LCM_RS=P2^5;
  24. sbit LCM_RW=P2^4;
  25. sbit LCM_EN=P2^3;

  26. uchar ad_data;                                    //采样值存储
  27. sbit Alarm_led_red =P3^1;                         //超过压力表量程最大值红色led报警定义
  28. sbit Alarm_led_green=P3^2;                        //低于压力表量程最小值绿色led报警定义
  29.                           //adc采样值存储单元
  30. char press_data;                                  //标度变换存储单元
  31. unsigned char ad_alarm;                           //报警值存储单元
  32. unsigned char press_ge=0;                        //显示值百位
  33. unsigned char press_shifen=0;                        //显示值十位
  34. unsigned char press_baifen=0;                         //显示值个位
  35. unsigned char press_qianfen=0;                        //显示值十分位

  36. uchar code str0[]={"Weight:  .   Kg "};
  37. uchar code str1[]={"DianZiCheng WH  "};

  38. void delay(uint);
  39. void lcd_wait(void);
  40. void delay_LCM(uint);                                                                                                     //LCD延时子程序
  41. void initLCM( void);                                                                                                       //LCD初始化子程序
  42. void lcd_wait(void);                                                                                                      //LCD检测忙子程序
  43. void WriteCommandLCM(uchar WCLCM,uchar BusyC);                              //写指令到ICM子函数
  44. void WriteDataLCM(uchar WDLCM);                                             //写数据到LCM子函数
  45. void DisplayOneChar(uchar X,uchar Y,uchar DData);                           //显示指定坐标的一个字符子函数
  46. void DisplayListChar(uchar X,uchar Y,uchar code *DData);                                         //显示指定坐标的一串字符子函数
  47.   void keyscan();                  
  48. void display(void);                                                         //系统显示子函数
  49. uchar Adc0832(unsigned char channel);                                                                                                                       
  50. void alarm(void);
  51. void data_pro(void);


  52. /**********main funcation************/

  53. void main(void)
  54. {
  55.     delay(500);                      //系统延时500ms启动
  56. //        ad_data=0;                       //采样值存储单元初始化为0
  57.            initLCM( );
  58.         
  59.            WriteCommandLCM(0x01,1);                    //清显示屏
  60.     DisplayListChar(0,0,str0);
  61.            DisplayListChar(0,1,str1);

  62.         while(1)
  63.     {
  64.            ad_data =Adc0832(0);           //采样值存储单元初始化为0
  65.           
  66.             alarm();
  67.        
  68.                 data_pro();
  69.                
  70.                 display();
  71.                                  
  72.         }
  73. }


  74. /*********延时K*1ms,12.000mhz**********/

  75. void delay(uint k)
  76. {
  77.     uint i,j;
  78.     for(i=0;i<k;i++)
  79.     {
  80.         for(j=0;j<60;j++)
  81.                 {;}
  82.     }
  83. }   
  84. /**********写指令到ICM子函数************/

  85. void WriteCommandLCM(uchar WCLCM,uchar BusyC)
  86. {
  87.     if(BusyC)lcd_wait();
  88.         DATAPORT=WCLCM;
  89.     LCM_RS=0;                   // 选中指令寄存器
  90.     LCM_RW=0;                       // 写模式       
  91.     LCM_EN=1;   
  92.         _nop_();   
  93.         _nop_();
  94.         _nop_();
  95.     LCM_EN=0;
  96.    
  97. }

  98. /**********写数据到LCM子函数************/

  99. void WriteDataLCM(uchar WDLCM)
  100. {
  101.     lcd_wait( );             //检测忙信号   
  102.         DATAPORT=WDLCM;
  103.     LCM_RS=1;                // 选中数据寄存器
  104.     LCM_RW=0;                    // 写模式
  105.     LCM_EN=1;
  106.     _nop_();
  107.         _nop_();
  108.         _nop_();
  109.     LCM_EN=0;
  110. }

  111. /***********lcm内部等待函数*************/

  112. void lcd_wait(void)
  113. {
  114.     DATAPORT=0xff;             //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色
  115.         LCM_EN=1;
  116.     LCM_RS=0;   
  117.     LCM_RW=1;   
  118.     _nop_();
  119.     _nop_();
  120.         _nop_();
  121.     while(DATAPORT&BUSY)  
  122.         {  LCM_EN=0;
  123.            _nop_();
  124.            _nop_();
  125.            LCM_EN=1;
  126.            _nop_();
  127.            _nop_();
  128.            }         
  129.            LCM_EN=0;       
  130.        
  131. }

  132. /**********LCM初始化子函数***********/

  133. void initLCM( )
  134. {   
  135.         DATAPORT=0;       
  136.         delay(15);
  137.         WriteCommandLCM(0x38,0);    //三次显示模式设置,不检测忙信号
  138.     delay(5);
  139.     WriteCommandLCM(0x38,0);
  140.     delay(5);
  141.     WriteCommandLCM(0x38,0);
  142.     delay(5);

  143.     WriteCommandLCM(0x38,1);    //8bit数据传送,2行显示,5*7字型,检测忙信号
  144.     WriteCommandLCM(0x08,1);    //关闭显示,检测忙信号
  145.     WriteCommandLCM(0x01,1);    //清屏,检测忙信号
  146.     WriteCommandLCM(0x06,1);    //显示光标右移设置,检测忙信号
  147.     WriteCommandLCM(0x0c,1);    //显示屏打开,光标不显示,不闪烁,检测忙信号
  148. }

  149. /****显示指定坐标的一个字符子函数****/

  150. void DisplayOneChar(uchar X,uchar Y,uchar DData)

  151. {
  152.    Y&=0x01;
  153.     X&=0x0f;
  154.     if(Y)X|=0x40;               //若y为1(显示第二行),地址码+0X40
  155.     X|=0x80;                    //指令码为地址码+0X80
  156.     WriteCommandLCM(X,1);
  157.     WriteDataLCM(DData);
  158. }

  159. /*******显示指定坐标的一串字符子函数*****/

  160. void DisplayListChar(uchar X,uchar Y,uchar code *DData)
  161. {
  162.     uchar ListLength=0;
  163.     Y&=0x01;
  164.     X&=0x0f;
  165.     while(X<16)
  166.     {
  167.         DisplayOneChar(X,Y,DData[ListLength]);
  168.         ListLength++;
  169.         X++;
  170.     }
  171. }

  172. /*****************系统显示子函数*****************/

  173. void display(void)
  174. {
  175.            WriteCommandLCM(0x0c,1);                                    //显示屏打开,光标不显示,不闪烁,检测忙信号       
  176.         DisplayListChar(0,0,str0);       
  177.         DisplayListChar(0,1,str1);       


  178.         DisplayOneChar(8,0,press_ge+0x30);
  179.         DisplayOneChar(10,0,press_shifen+0x30);
  180.         DisplayOneChar(11,0,press_baifen+0x30);
  181.     DisplayOneChar(12,0,press_qianfen+0x30);
  182.         delay(1000);                               //稳定显示
  183. }
  184. /************
  185. 读ADC0832函数
  186. ************/

  187. //采集并返回
  188. uchar Adc0832(unsigned char channel)     //AD转换,返回结果
  189. {
  190.     uchar i=0;
  191.     uchar j;
  192.     uint dat=0;
  193.     uchar ndat=0;

  194.     if(channel==0)channel=2;
  195.     if(channel==1)channel=3;
  196.     ADDI=1;
  197.     _nop_();
  198.     _nop_();
  199.     ADCS=0;//拉低CS端
  200.     _nop_();
  201.     _nop_();
  202.     ADCLK=1;//拉高CLK端
  203.     _nop_();
  204.     _nop_();
  205.     ADCLK=0;//拉低CLK端,形成下降沿1
  206.     _nop_();
  207.     _nop_();
  208.     ADCLK=1;//拉高CLK端
  209.     ADDI=channel&0x1;
  210.     _nop_();
  211.     _nop_();
  212.     ADCLK=0;//拉低CLK端,形成下降沿2
  213.     _nop_();
  214.     _nop_();
  215.     ADCLK=1;//拉高CLK端
  216.     ADDI=(channel>>1)&0x1;
  217.     _nop_();
  218.     _nop_();
  219.     ADCLK=0;//拉低CLK端,形成下降沿3
  220.     ADDI=1;//控制命令结束
  221.     _nop_();
  222.     _nop_();
  223.     dat=0;
  224.     for(i=0;i<8;i++)
  225.     {
  226.         dat|=ADDO;//收数据
  227.         ADCLK=1;
  228.         _nop_();
  229.         _nop_();
  230.         ADCLK=0;//形成一次时钟脉冲
  231.         _nop_();
  232.         _nop_();
  233.         dat<<=1;
  234.         if(i==7)dat|=ADDO;
  235.     }  
  236.     for(i=0;i<8;i++)
  237.     {
  238.         j=0;
  239.         j=j|ADDO;//收数据
  240.         ADCLK=1;
  241.         _nop_();
  242.         _nop_();
  243.         ADCLK=0;//形成一次时钟脉冲
  244.         _nop_();
  245.         _nop_();
  246.         j=j<<7;
  247.         ndat=ndat|j;
  248.         if(i<7)ndat>>=1;
  249.     }
  250.     ADCS=1;//拉低CS端
  251.     ADCLK=0;//拉低CLK端
  252.     ADDO=1;//拉高数据端,回到初始状态
  253.     dat<<=8;
  254.     dat|=ndat;
  255.     return(dat);            //return ad k
  256. }


  257. void data_pro(void)
  258. {
  259.       unsigned int temp;
  260.       float  press;                             

  261.           if(14<ad_data<243)                                       //当压力值介于15kpa到115kpa之间时,遵循线性变换
  262.                  {                            
  263.                     int vary=ad_data;                                                //y=(115-15)/(243-13)*X+15kpa                       
  264.                         press=((10.0/23.0)*vary)+9.3;                        //测试时补偿值为9.3
  265.                                                                                                                   
  266.                         temp=(int)(press*10);                        //放大10倍,便于后面的计算
  267.                                                                                               
  268.                                                                                                            
  269.                         press_ge=temp/1000;                                     //取压力值百位
  270.                         press_shifen=(temp%1000)/100;                            //取压力值十位
  271.                         press_baifen=((temp%1000)%100)/10;                    //取压力值个位
  272.                         press_qianfen=((temp%1000)%100)%10;                        //取压力值十分位

  273.                       }            
  274.                          
  275. }
  276. /*****************报警子函数*******************/

  277. void alarm(void)
  278. {
  279.          if(ad_data>=243)                           //如果当前压力值大于115kpa,

  280.           {  Alarm_led_red=0; }                 //则启动red led报警
  281.         
  282.           else
  283.              {          Alarm_led_red=1; }                        //关闭red led 报警
  284.                   
  285.        
  286.           if(ad_data<=14)                                                        //如果当前压力值小于16kpa

  287.              {  Alarm_led_green=0;  }               //则启动green led报警

  288.       else
  289.              {   Alarm_led_green=1; }                              //关闭green  led 报警
  290.          
  291. }



复制代码

所有资料51hei提供下载:
电子秤.zip (120.63 KB, 下载次数: 61)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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