找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于电阻式应变片的电子秤Proteus仿真+程序设计

  [复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include<reg52.h>
  2. typedef unsigned char uint8;
  3. typedef unsigned int uint16;
  4. sbit rs=P2^6;
  5. sbit rw=P2^5;
  6. sbit e=P2^7;
  7. sbit scl=P2^1;
  8. sbit sda=P2^0;
  9. uint8 num[]="0123456789";
  10. uint8 d1[]="RMB/kg: ";
  11. uint16 ad[5],m[5];
  12. uint8 kn=10;
  13. uint8 keynum[3];
  14. uint16 pric=0;
  15. void delay(uint16 i)
  16. {
  17.         while(i--);
  18. }
  19. void wrc(uint8 c)
  20. {
  21.         delay(1000);
  22.         rs=0;
  23.         rw=0;
  24.         e=0;
  25.         P0=c;
  26.         e=1;
  27.         delay(10);
  28.         e=0;
  29. }
  30. void wrd(uint8 dat)
  31. {
  32.         delay(1000);
  33.         rs=1;
  34.         rw=0;
  35.         e=0;
  36.         P0=dat;
  37.         e=1;
  38.         delay(10);
  39.         e=0;
  40.         rs=0;
  41. }
  42. void init()
  43. {
  44.         delay(1000);
  45.         wrc(0x38);
  46.         wrc(0x38);
  47.         wrc(0x38);
  48.         wrc(0x06);
  49.         wrc(0x0c);
  50.         wrc(0x01);
  51. }
  52. void iicinit()
  53. {
  54.         sda=1;
  55.         scl=1;        
  56. }
  57. void iicstart()
  58. {
  59.         sda=1;
  60.         scl=1;
  61.         delay(10);
  62.         sda=0;
  63.         delay(10);
  64.         scl=0;
  65.         delay(10);
  66. }
  67. void iicstop()
  68. {
  69.         sda=0;
  70.         scl=1;
  71.         delay(10);
  72.         sda=1;
  73.         delay(10);
  74.         sda=0;
  75.         delay(10);
  76. }
  77. void ack()
  78. {
  79.         sda=1;
  80.         scl=0;
  81.         delay(2);
  82.         sda=0;
  83.         delay(2);
  84.         scl=1;
  85.         delay(10);
  86.         scl=0;
  87.         delay(2);
  88.         sda=1;
  89.         delay(5);
  90. }
  91. void noack()
  92. {
  93.         sda=0;
  94.         scl=0;
  95.         delay(2);
  96.         sda=1;
  97.         delay(2);        
  98.         scl=1;
  99.         delay(10);
  100.         scl=0;
  101.         delay(2);
  102.         sda=0;
  103.         delay(5);
  104. }

  105. void iicwrbyte(uint8 dat)
  106. {
  107.         uint8 i;
  108.         scl=0;
  109.         for(i=0;i<8;i++)                                
  110.         {
  111.                 if(dat&0x80)        
  112.                 {
  113.                         sda=1;
  114.                 }
  115.                 else
  116.                 {
  117.                         sda=0;
  118.                 }
  119.                 dat<<=1;
  120.                 scl=1;
  121.                 delay(10);
  122.                 scl=0;
  123.                 delay(10);
  124.         }
  125.         sda=1;
  126.         delay(10);
  127. }

  128. uint8 iicread()
  129. {
  130.         uint8 i,dat;
  131.         scl=0;
  132.         sda=1;
  133.         for(i=0;i<8;i++)
  134.         {
  135.                 dat<<=1;
  136.                 if(sda==1)               
  137.                 {
  138.                         dat|=0x01;        
  139.                 }
  140.                 scl=1;
  141.                 delay(10);
  142.                 scl=0;
  143.                 delay(10);
  144.         }
  145.         return         dat;
  146. }

  147. void pcf8591wrbyte(uint8 channel)
  148. {
  149.         iicinit();
  150.         iicstart();
  151.         iicwrbyte(0x90);           //pcf8591写数据  1001 A2A1A0 R/W
  152.         ack();
  153.         iicwrbyte(channel|0x70);   //通过打开通道channelX,模拟输出使能打开
  154.         noack();
  155.         iicstop();
  156. }
  157. uint8 pcf8591read()
  158. {
  159.         uint8 dat;
  160.         iicinit();
  161.         iicstart();
  162.         iicwrbyte(0x90);
  163.         ack();
  164.         iicstart();
  165.         iicwrbyte(0x91);         //        pcf8591读数据  1001 A2A1A0 R/W
  166.         ack();
  167.         dat=iicread();
  168.         noack();
  169.         iicstop();
  170.         return dat;        
  171. }

  172. void pcf8591dac(uint8 value)           //DA转换
  173. {
  174.         iicinit();
  175.         iicstart();
  176.         iicwrbyte(0x90);
  177.         ack();
  178.         iicwrbyte(0x70);                //不需要打开通道channelX,模拟输出使能打开
  179.         ack();
  180.         iicwrbyte(value);
  181.         noack();
  182.         iicstop();        
  183. }
  184. uint8 keyscan()                 //按键扫描程序
  185. {
  186.         uint8 h,l,value;
  187.         P1=0x0f;
  188.         h=P1&0x0f;
  189.         if(h!=0x0f)
  190.         {
  191.                 delay(1);
  192.                 if(h!=0x0f)
  193.                 {
  194.                         h=P1&0x0f;
  195.                         l=P1|0xf0;
  196.                         P1=l;
  197.                         l=P1&0xf0;
  198.                         h=P1&0x0f;
  199.                         value=h+l;        
  200.                 }
  201.                 return value;
  202.         }
  203. }
  204. void keypros()                  //按键处理函数
  205. {
  206.         uint8 key;
  207.         key=keyscan();
  208.         switch(key)
  209.         {
  210.                 case 0xee: kn=0;break;
  211.                 case 0xde: kn=1;break;
  212.                 case 0xbe: kn=2;break;
  213.                 case 0x7e: kn=3;break;
  214.                 case 0xed: kn=4;break;
  215.                 case 0xdd: kn=5;break;
  216.                 case 0xbd: kn=6;break;
  217.                 case 0x7d: kn=7;break;
  218.                 case 0xeb: kn=8;break;
  219.                 case 0xdb: kn=9;break;
  220.                 case 0xbb: break;   
  221.                 case 0x7b: break;
  222.                 case 0xe7: kn=12;break; //小数点按下标志位
  223.                 case 0xd7: kn=11;break; //计价确认按键标志
  224.                 case 0xb7: kn=13;break; //clear,清空计价输入
  225.                 case 0x77: break;
  226.                 default :  break;
  227.         }        
  228. }
  229. void datapros()
  230. {
  231.         uint8 i,count=0;
  232.         do                                           //将按键值保存在数组keynum中
  233.         {
  234.                 P1=0x0f;
  235.                 if(P1!=0x0f)               
  236.                 {
  237.                         keypros();
  238.                         P1=0x0f;
  239.                         while(P1!=0x0f);//等待按键松开
  240.                         if(kn>=0&&kn<=9)
  241.                         {
  242.                                 keynum[count]=kn;
  243.                                 wrc(0x0b+count+0x80);  //移位显示
  244.                                 wrd(keynum[count]+0x30);
  245.                                 count++;
  246.                         }
  247.                         if(kn==13)          //清除按键计价数
  248.                         {
  249.                                 wrc(0x01);//清屏处理        
  250.                                 pric=0;
  251.                         }
  252.                         if(kn==11)         //当计价确认按键按下时候退出循环
  253.                         {
  254.                                 goto xian;
  255.                         }        
  256.                 }                        
  257.         }
  258.         while(count<=2);
  259.         if(count>=2)
  260.         {
  261.                 goto xian;
  262.         }
  263.         xian:        for(i=0;i<count;i++)
  264.         {
  265.                 pric=pric*10+keynum[i];        
  266.                 if(i==count)count=0;//当进行一次转换后清空计数器的值        
  267.         }
  268. }
  269. void display()
  270. {
  271.         float v;
  272.         uint8 i;
  273.         uint16 price;
  274.         pcf8591wrbyte(0);          //电位器转换
  275.         ad[0]=pcf8591read();        //读取第一次之前的那次数据
  276.         delay(10);
  277.         v=ad[0]*0.01953;//将电位器的数据转换成电压值
  278.         v=v*100;//取2位有效数值
  279.         ad[0]=v;
  280.         price=ad[0]*pric;         //每千克多少钱如果我们定义每千克2元那么就可以乘以2,如果为其他我们可以乘以其他数,最大定义的价格是200元每千克
  281.         wrc(0x00+0x80);
  282.         for(i=0;i<8;i++)
  283.         {
  284.                 wrd(d1[i]);
  285.         }
  286.         wrc(0x40+0x80);
  287.         wrd('m');
  288.         wrd(':');
  289.         wrd(num[ad[0]/100]);
  290.         wrd('.');
  291.         wrd(num[ad[0]%100/10]);
  292.         wrd(num[ad[0]%100%10]);
  293. //        wrd(num[ad[0]%1000%100%10]);
  294.         wrd('K');
  295. //        wrd('G');
  296.         ad[4]=ad[0];
  297.         pcf8591dac(ad[4]/2);//将数字量转换为模拟量由pcf8591的AOUT输出

  298.         wrd(' ');
  299.         wrd('P');
  300.         wrd(':');
  301.         wrd(num[price/10000]);//为什么是除以10000,本来不计价的话是除以100,但是计价最大可以使百位数,所以除以的数也得乘以100
  302.         
  303.         wrd(num[price%10000/1000]);
  304.         
  305.         wrd(num[price%10000%1000/100]);
  306.         wrd('.');
  307.         if((price%10000%1000%100%10)>=5)  //进价,四舍五入法
  308.                 wrd(num[(price%10000%1000%100/10)+1]);
  309.         else        
  310.                 wrd(num[price%10000%1000%100/10]);        
  311.         wrd('
  312. );
  313. }

  314. void main()
  315. {
  316.         init();
  317.         while(1)
  318.         {
  319.                 display();
  320.                 datapros();        
  321.         }               
  322. }
复制代码


所有资料51hei提供下载:
基于电阻式应变片的电子秤的设计.zip (346.64 KB, 下载次数: 249)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:652328 发表于 2019-12-20 15:43 | 只看该作者
isis打不开怎么办
回复

使用道具 举报

板凳
ID:477512 发表于 2019-12-29 09:18 | 只看该作者
这个文件没能下载成功却扣分,先是说无法连接,后又点击了一下,积分已被扣,我不明白,无法连接怎么登录该网站?
回复

使用道具 举报

地板
ID:655388 发表于 2020-5-23 15:03 | 只看该作者
好强,谢谢楼主
回复

使用道具 举报

5#
ID:778621 发表于 2020-6-13 23:18 | 只看该作者
强打耳洞打耳洞
回复

使用道具 举报

6#
ID:436873 发表于 2020-6-25 10:46 | 只看该作者
不能仿真
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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