找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用51单片机制作电子秤的资料(带仿真文件)

  [复制链接]
跳转到指定楼层
楼主


源码和仿真文件下载: 0150、电子秤proteus仿真 程序资料.rar (188.4 KB, 下载次数: 804)

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

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

  7. 作者:
  8. 单位:
  9. 日期:2008.3.7

  10. ********************************************************/

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

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


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

  24. sbit LCM_RS=P2^0;
  25. sbit LCM_RW=P2^1;
  26. sbit LCM_EN=P2^2;

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

  37. uchar code str0[]={"Weight:  .   Kg "};
  38. uchar code str1[]={"Make by GUO TAO "};
  39. uchar code str2[]={"Price:          "};
  40. uchar code str3[]={"Total:          "};
  41. void delay(uint);
  42. void lcd_wait(void);
  43. void delay_LCM(uint);                                                                                                     //LCD延时子程序
  44. void initLCM( void);                                                                                                       //LCD初始化子程序
  45. void lcd_wait(void);                                                                                                      //LCD检测忙子程序
  46. void WriteCommandLCM(uchar WCLCM,uchar BusyC);                              //写指令到ICM子函数
  47. void WriteDataLCM(uchar WDLCM);                                             //写数据到LCM子函数
  48. void DisplayOneChar(uchar X,uchar Y,uchar DData);                           //显示指定坐标的一个字符子函数
  49. void DisplayListChar(uchar X,uchar Y,uchar code *DData);                                         //显示指定坐标的一串字符子函数
  50.   void keyscan();                  
  51. void display(void);                                                         //系统显示子函数
  52. uchar Adc0832(unsigned char channel);                                                                                                                       
  53. void alarm(void);
  54. void data_pro(void);


  55. /**********main funcation************/

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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


  260. void data_pro(void)
  261. {
  262.       unsigned int temp;
  263.       float  press;                             

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

  276.                       }            
  277.                          
  278. }
  279. /*****************报警子函数*******************/

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

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

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

  291.       else
  292.              {   Alarm_led_green=1; }                              //关闭green  led 报警
  293.          
  294. }



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

使用道具 举报

沙发
ID:51301 发表于 2013-6-26 20:28 | 只看该作者
谢谢分享啊
回复

使用道具 举报

板凳
ID:51343 发表于 2013-7-2 17:16 | 只看该作者
好东东,牛人,51Hei(51黑)论坛有你更精彩.
回复

使用道具 举报

地板
ID:40961 发表于 2013-7-9 14:32 | 只看该作者
学习学习
回复

使用道具 举报

5#
ID:52177 发表于 2013-7-23 23:20 | 只看该作者
不错的,好假货,大家一起学习下
回复

使用道具 举报

6#
ID:52456 发表于 2013-8-1 22:49 | 只看该作者
学习下
回复

使用道具 举报

7#
ID:52267 发表于 2013-9-27 16:18 | 只看该作者
学习下

回复

使用道具 举报

8#
ID:47175 发表于 2013-10-11 09:23 | 只看该作者
资料不错
回复

使用道具 举报

9#
ID:52286 发表于 2013-10-13 22:54 | 只看该作者
资料真不错.
回复

使用道具 举报

10#
ID:59269 发表于 2014-3-6 00:54 | 只看该作者
学习一下
回复

使用道具 举报

11#
ID:36525 发表于 2014-3-9 16:22 | 只看该作者
学习中
回复

使用道具 举报

12#
ID:23303 发表于 2014-5-11 09:02 | 只看该作者
好东东,牛人,51Hei(51黑)论坛有你更精彩
回复

使用道具 举报

13#
ID:61140 发表于 2014-6-9 19:57 | 只看该作者
好东东,牛人,51Hei(51黑)论坛有你更精彩
回复

使用道具 举报

14#
ID:62881 发表于 2014-6-12 11:34 | 只看该作者
1156615097 发表于 2013-7-23 23:20
不错的,好假货,大家一起学习下

感觉仿真了下 好像没用哎 是不是我的技术问题啊。哎
回复

使用道具 举报

15#
ID:67292 发表于 2014-10-12 22:06 | 只看该作者
学习了,不错
回复

使用道具 举报

16#
ID:74370 发表于 2015-3-27 07:44 | 只看该作者
学了点单片机皮毛,什么都想仿,学习下,灰常感谢!
回复

使用道具 举报

17#
ID:72050 发表于 2015-4-26 15:30 | 只看该作者
谢谢共享
回复

使用道具 举报

18#
ID:72050 发表于 2015-4-26 15:30 | 只看该作者
实用的东西
回复

使用道具 举报

19#
ID:77640 发表于 2015-5-12 17:25 | 只看该作者
学习学习
回复

使用道具 举报

20#
ID:81649 发表于 2015-5-31 13:15 | 只看该作者
可以下载不
回复

使用道具 举报

21#
ID:81662 发表于 2015-5-31 15:37 | 只看该作者
这个仿真起来怎么输入单价 总价都是0.0765啊
回复

使用道具 举报

22#
ID:109422 发表于 2016-3-17 22:12 | 只看该作者
学习了,谢谢楼主分享
回复

使用道具 举报

23#
ID:108109 发表于 2016-3-20 18:10 | 只看该作者
怎么设置price呢?不怎么行耶
回复

使用道具 举报

24#
ID:112595 发表于 2016-4-6 21:18 | 只看该作者
学习下
回复

使用道具 举报

25#
ID:113101 发表于 2016-4-9 13:17 | 只看该作者
谢谢分享
回复

使用道具 举报

26#
ID:119099 发表于 2016-5-7 17:06 | 只看该作者
谢谢分享
回复

使用道具 举报

27#
ID:119236 发表于 2016-5-8 11:24 | 只看该作者
houhouhou
回复

使用道具 举报

28#
ID:121949 发表于 2016-5-19 14:04 | 只看该作者

学习下
回复

使用道具 举报

29#
ID:121949 发表于 2016-5-19 14:10 | 只看该作者
谢谢分享
回复

使用道具 举报

30#
ID:123026 发表于 2016-5-25 02:08 | 只看该作者
谢谢分享
回复

使用道具 举报

31#
ID:127961 发表于 2016-6-24 12:19 | 只看该作者
学习了,谢谢楼主分享
回复

使用道具 举报

32#
ID:128034 发表于 2016-6-24 22:19 | 只看该作者
好帖子!!!!!!!!!!!楼主好人!
回复

使用道具 举报

33#
ID:128451 发表于 2016-6-28 17:00 | 只看该作者
仿真怎么运行,程序有没有详细的解释。求大神帮忙很急啊
回复

使用道具 举报

34#
ID:117047 发表于 2016-6-29 08:18 | 只看该作者
不错,学习啦!!
回复

使用道具 举报

35#
ID:129120 发表于 2016-7-4 20:27 | 只看该作者
GOOOD,GOOOD
回复

使用道具 举报

36#
ID:135206 发表于 2016-7-27 11:38 | 只看该作者
支持大神
回复

使用道具 举报

37#
ID:135166 发表于 2016-7-28 07:54 | 只看该作者
感谢楼主分享
回复

使用道具 举报

38#
ID:150328 发表于 2016-11-26 14:23 | 只看该作者
仿真软件用的啥  为什么我找不到仿真文件啊
回复

使用道具 举报

39#
ID:149790 发表于 2016-11-26 23:34 | 只看该作者
感谢分享谢谢楼主
回复

使用道具 举报

40#
ID:155605 发表于 2016-12-19 02:50 | 只看该作者
仿真是怎么用的啊。。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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