找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4628|回复: 7
收起左侧

电子秤仿真与单片机代码

  [复制链接]
ID:209262 发表于 2017-6-8 16:34 | 显示全部楼层 |阅读模式
没事做了一个电子秤仿真

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
电子秤.PNG

单片机代码:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include"delay.h"
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define WRITE_ADDR 0x90
  7. #define AD_COMMAND 0x00
  8. #define READ_ADDR 0x91
  9. /*管脚定义*/
  10. sbit SDA = P2^0;
  11. sbit SCL = P2^1;
  12. sbit shumaguan1 = P3^4;
  13. sbit shumaguan2 = P3^5;
  14. sbit shumaguan3 = P3^6;
  15. sbit shumaguan4 = P3^7;
  16. sbit xiaoshudian = P0^7;
  17. sbit alarm = P2^2;
  18. /*共阴极数码管编码*/
  19. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  20. /*全局变量*/
  21. uchar adc_data = 0;          //记录每一次读取的adc数据
  22. uchar key_value =0;  //记录每一次按键值
  23. uchar temp_data[4] = {0}; //记录输入的单价
  24. uchar point_place = 0;    //记录小数点位置
  25. uchar wei_shu = 0;                  //记录总共数据位数
  26. uchar equal_sign = 0;          //记录是否按下“=”号
  27. uchar interrupt_flag = 0; //发生中断标记
  28. uint  price = 0;  //用来记录单价
  29. /*微秒级别延时(5us)*/
  30. void delay_us()
  31. {;;}
  32. /*毫秒级别延时(z微妙)*/
  33. void delay_ms(unsigned int z)
  34. {
  35.         unsigned int x,y;
  36.         for(x = z;x > 0;x--)
  37.                 for(y = 120 ;y>0;y--);
  38. }
  39. /*报警*/
  40. void beep_on(void)
  41. {
  42.         alarm = 0;
  43. }
  44. void beep_off(void)
  45. {
  46.         alarm = 1;
  47. }
  48. /*键盘读取函数*/
  49. uchar keyboard_read()
  50. {
  51.         uchar key,temp;
  52.     P1=0xfe;
  53.     temp=P1;
  54.     temp=temp&0xf0;
  55.     if(temp!=0xf0)
  56.     {
  57.       delay_ms(10);
  58.       if(temp!=0xf0)
  59.       {
  60.         temp=P1;
  61.         switch(temp)
  62.         {
  63.           case 0xee:
  64.                key=7;
  65.                break;
  66.           case 0xde:
  67.                key=8;
  68.                break;
  69.           case 0xbe:
  70.                key=9;
  71.                break;
  72.           case 0x7e:
  73.                key='/';
  74.                break;
  75.          }
  76.          while(temp!=0xf0)
  77.          {
  78.            temp=P1;
  79.            temp=temp&0xf0;
  80.          }
  81.       }
  82.     }
  83.     P1=0xfd;
  84.     temp=P1;
  85.     temp=temp&0xf0;
  86.     if(temp!=0xf0)
  87.     {
  88.       delay_ms(10);
  89.       if(temp!=0xf0)
  90.       {
  91.         temp=P1;
  92.         switch(temp)
  93.         {
  94.           case 0xed:
  95.                key=4;
  96.                break;

  97.           case 0xdd:
  98.                key=5;
  99.                break;
  100.           case 0xbd:
  101.                key=6;
  102.                break;
  103.           case 0x7d:
  104.                key='*';
  105.                break;
  106.          }
  107.          while(temp!=0xf0)
  108.          {
  109.            temp=P1;
  110.            temp=temp&0xf0;
  111.          }
  112.       }
  113.       }
  114.     P1=0xfb;
  115.     temp=P1;
  116.     temp=temp&0xf0;
  117.     if(temp!=0xf0)
  118.     {
  119.       delay_ms(10);
  120.       if(temp!=0xf0)
  121.       {
  122.         temp=P1;
  123.         switch(temp)
  124.         {
  125.           case 0xeb:
  126.                key=1;
  127.                break;
  128.           case 0xdb:
  129.                key=2;
  130.                break;
  131.           case 0xbb:
  132.                key=3;
  133.                break;
  134.           case 0x7b:
  135.                key='-';
  136.                break;
  137.          }
  138.          while(temp!=0xf0)
  139.          {
  140.            temp=P1;
  141.            temp=temp&0xf0;
  142.          }
  143.       }
  144.       }
  145.     P1=0xf7;
  146.     temp=P1;
  147.     temp=temp&0xf0;
  148.     if(temp!=0xf0)
  149.     {
  150.       delay_ms(10);
  151.       if(temp!=0xf0)
  152.       {
  153.         temp=P1;
  154.         switch(temp)
  155.         {
  156.           case 0xe7:
  157.                key='.';
  158.                break;
  159.           case 0xd7:
  160.                key=0;
  161.                break;
  162.           case 0xb7:
  163.                key='=';
  164.                break;
  165.           case 0x77:
  166.                key='+';
  167.                break;
  168.          }
  169.          while(temp!=0xf0)
  170.          {
  171.            temp=P1;
  172.            temp=temp&0xf0;
  173.          }
  174.       }
  175.     }
  176.         return key;
  177. }
  178. /*iic开始信号*/
  179. void start()
  180. {
  181.         SCL = 1;
  182.         _nop_();
  183.         SDA = 1;
  184.         delay_us();
  185.         SDA = 0;
  186.         delay_us();
  187.         SCL = 0;//拉低时钟线,开始信号以后方便更改SDA 上面的数据来发送
  188.         _nop_();
  189. }
  190. /*iic 停止信号*/
  191. void stop()
  192. {
  193.         SCL = 1;
  194.         _nop_();
  195.         SDA = 0;
  196.         delay_us();
  197.         SDA = 1;
  198.         delay_us();
  199. }
  200. /*回复响应信号*/
  201. void respond()
  202. {
  203.         SCL = 1;
  204.         _nop_();
  205.         SDA = 0;
  206.         delay_us();
  207.         
  208.         SCL = 0; //凡是在一个小节后拉低SCL 都是为了方便接下来的 数据传输
  209.         _nop_();
  210. }
  211. /*不响应*/
  212. void norespond()
  213. {
  214.         SCL = 1;
  215.         _nop_();
  216.         SDA = 1;
  217.         delay_us();
  218. }
  219. /*初始化iic总线*/
  220. void init_iic_line()
  221. {
  222.         SCL = 1;
  223.         _nop_();
  224.         SDA = 1;
  225.         _nop_();
  226. }

  227. /*往iic设备发送数据,先发送数据的最高位 */
  228. void write_byte(uchar value)
  229. {
  230.         uchar i,temp;
  231.         temp = value;
  232.         for(i = 0;i<8;i++)
  233.         {
  234.                 SCL = 0;
  235.                 _nop_();
  236.                 if((temp & 0x80) == 0x80)
  237.                 {
  238.                         SDA = 1;
  239.                 }
  240.                 else
  241.                 {
  242.                         SDA = 0;
  243.                 }
  244.                 SCL = 1;
  245.                 _nop_();  
  246.                 temp <<=1;
  247.         }
  248.         SCL = 0;
  249.         _nop_();
  250. }
  251. /*读取iic设备发送过来的数据*/
  252. uchar read_byte()
  253. {
  254.         uchar i, return_value = 0;
  255.         SDA = 1;//释放数据线,交给从机控制
  256.         _nop_();
  257.         SCL = 0;
  258.         _nop_();
  259.         for(i = 0;i<8;i++)
  260.         {
  261.                 SCL = 1;
  262.                 if(SDA == 1)
  263.                 {
  264.                         return_value  = return_value |0x01;
  265.                 }
  266.                 if(i<7)//这里很重要
  267.                 {
  268.                         return_value <<= 1;
  269.                 }
  270.                 SCL = 0;
  271.                 _nop_();
  272.         }
  273.         return return_value;
  274. }
  275. /*显示一个数码管*/
  276. void display_one(uchar value)
  277. {
  278.         P0 = table[value];
  279. }
  280. /*初始化iic设备*/
  281. void init_iic_device()
  282. {
  283.         start();
  284.         write_byte(WRITE_ADDR);
  285.         respond();
  286.         write_byte(AD_COMMAND);
  287.         respond();
  288. }
  289. /*读取adc数据*/
  290. uchar read_adc_data()
  291. {
  292.         uchar adc_data = 0;
  293.         start();
  294.         write_byte(READ_ADDR);
  295.         respond();
  296.         adc_data = read_byte();
  297.         norespond();
  298.         stop();
  299.         return adc_data;
  300. }
  301. /*adc数据处理*/
  302. void adc_data_process()
  303. {
  304.         long temp_weight;
  305.         temp_weight = ((long)adc_data)*1000/51;
  306.         temp_data[0] = temp_weight/1000;
  307.         temp_data[1] = temp_weight%1000/100;
  308.         temp_data[2] = temp_weight%1000%100/10;
  309.         temp_data[3] = temp_weight%1000%100%10;
  310.         point_place = 1;
  311.         wei_shu = 4;
  312. }
  313. /*选择哪个数码管亮*/
  314. void shumaguan_slect_on(uchar num)
  315. {
  316.         uchar temp = 4;
  317.         temp = temp-(wei_shu -num);
  318.         switch(temp)
  319.         {
  320.                  case 0:
  321.                          shumaguan1 = 0;
  322.                         break;
  323.                  case 1:
  324.                          shumaguan2 = 0;
  325.                         break;
  326.                  case 2:
  327.                          shumaguan3 = 0;
  328.                         break;
  329.                  case 3:
  330.                          shumaguan4 = 0;
  331.                         break;
  332.                  default:
  333.                          break;
  334.         }
  335. }
  336. /*选择哪个数码管熄灭*/
  337. void shumaguan_slect_off(uchar num)
  338. {
  339.         uchar temp = 4;
  340.         temp = temp-(wei_shu -num);
  341.         switch(temp)
  342.         {
  343.                  case 0:
  344.                          shumaguan1 = 1;
  345.                         break;
  346.                  case 1:
  347.                          shumaguan2 = 1;
  348.                         break;
  349.                  case 2:
  350.                          shumaguan3 = 1;
  351.                         break;
  352.                  case 3:
  353.                          shumaguan4 = 1;
  354.                         break;
  355.                  default:
  356.                          break;
  357.         }
  358. }
  359. void clear_led(void)
  360. {
  361.         shumaguan1 = 1;
  362.         shumaguan2 = 1;
  363.         shumaguan3 = 1;
  364.         shumaguan3 = 1;        
  365. }
  366. /*显示子程序,支持显示重量,单价,总价*/
  367. void display()
  368. {
  369.         uchar i;
  370.         clear_led();
  371.         for(i = 0;i < wei_shu;i++)
  372.         {
  373.                 if((i + 1) == point_place)
  374.                 {
  375.                         shumaguan_slect_off(i);
  376.                         display_one(temp_data[i]);
  377.                         xiaoshudian = 1;
  378.                         shumaguan_slect_on(i);
  379.                         delay_ms(5);
  380.                         shumaguan_slect_off(i);
  381.                 }
  382.                 else
  383.                 {
  384.                         shumaguan_slect_off(i);
  385.                         display_one(temp_data[i]);
  386.                         shumaguan_slect_on(i);
  387.                         delay_ms(5);
  388.                         shumaguan_slect_off(i);        
  389.                 }
  390.         }        
  391. }
  392. /*计算总价并将总价每一位分离*/
  393. void calculate_total_price()
  394. {
  395.         int temp_number = 0 ;
  396.         unsigned long total_price = 0;
  397.         switch(wei_shu -point_place)
  398.         {
  399.                 case 3:
  400.                         temp_number = 100;
  401.                         break;
  402.                 case 2:
  403.                         temp_number = 10;
  404.                         break;
  405.                 case 1:
  406.                         temp_number = 1;
  407.                         break;
  408.         }
  409.         total_price = (unsigned long)price * (unsigned long)adc_data*1000;
  410.         total_price = total_price/51/temp_number/1000;
  411.         if(total_price <10000&&total_price>999)
  412.         {
  413.                 temp_data[0] = total_price/1000;
  414.                 temp_data[1] = total_price%1000/100;
  415.                 temp_data[2] = total_price%1000%100/10;
  416.                 temp_data[3] = total_price%1000%100%10;
  417.                 wei_shu = 4;
  418.                 point_place = 3;
  419.         }
  420.         else if(total_price <1000&&total_price >99)
  421.         {
  422.                 temp_data[0] = total_price/100;
  423.                 temp_data[1] = total_price%100/10;
  424.                 temp_data[2] = total_price%100%10;
  425.                 wei_shu = 3;
  426.                 point_place = 2;
  427.         }
  428.         else if(total_price < 100&&total_price>9)
  429.         {
  430.                 temp_data[0] = total_price/10;
  431.                 temp_data[1] = total_price%10;
  432.                 wei_shu = 2;
  433.                 point_place = 1;
  434.         }
  435.         else
  436.         {
  437.                 temp_data[0] = total_price/10;
  438.                 temp_data[1] = total_price%10;
  439.                 wei_shu = 2;
  440.                 point_place = 1;
  441.         }
  442. }

  443. /*中断初始化*/
  444. void interrupt_init()
  445. {
  446.         EA = 1;           //开总中断
  447.         IT0 = 0;   //设置外部中断0为下降沿触发
  448.         EX0 = 1;   //开外部中断0
  449.         P1 = 0xf0; //初始化矩阵键盘外部引脚电平
  450. }
  451. int main()
  452. {
  453.         interrupt_init();
  454.         init_iic_line();
  455.         init_iic_device();
  456.         /*读取传感器并显示重量,直到键盘输入重量跳出*/
  457.         while(1)
  458.         {
  459.                 if(interrupt_flag != 1)
  460.                 {
  461.                         adc_data = read_adc_data();
  462.                         adc_data_process();
  463.                         display();         
  464.                 }
  465.                 else
  466.                 {
  467.                         clear_led();
  468.                         break;
  469.                 }         
  470.         }
  471.         /*显示从键盘输入的单价*/
  472.         while(1)
  473.         {
  474.                 if(equal_sign != 1)
  475.                 {
  476.                         display();
  477.                         adc_data = read_adc_data();
  478.                         if(adc_data == 0)
  479.                         {
  480.                                 break;
  481.                         }
  482.                 }
  483.                 else
  484.                 {
  485.                         break;
  486.                 }
  487.         }
  488.         /*计算总价并显示,直到重量为0 ,表示称量物品已经离开,回到程序开始执行处*/
  489.         calculate_total_price();
  490.         while(1)
  491.         {        
  492.                 adc_data = read_adc_data();
  493.                 if(adc_data != 0)
  494.                 {
  495.                         display();
  496.                 }
  497.                 else
  498.                 {
  499.                         uchar i = 0;
  500.                         for(i = 0 ; i<4 ; i++)
  501.                         {
  502.                                 temp_data[i] = 0;
  503.                         }
  504.                         adc_data = 0;         
  505.                          key_value = 0;  
  506.                         point_place = 0;   
  507.                         wei_shu = 0;                 
  508.                         equal_sign = 0;
  509.                         interrupt_flag = 0;
  510.                         price = 0;
  511.                         break;
  512.                 }
  513.         }
  514.         return 0;
  515. }
  516. /***************************中断处理函数************************/
  517. void keyboard_int(void) interrupt 0
  518. {
  519.         EA = 0;
  520.         /*清除数据 */
  521.         if(interrupt_flag == 0)
  522.         {
  523.                 wei_shu = 0;
  524.                 point_place = 0;
  525.         }
  526.         /*读取键盘值*/
  527.         key_value = keyboard_read();
  528.         if(key_value != '=')
  529.         {
  530.                 if(wei_shu <4)
  531.                 {
  532.                         if(key_value!='.')
  533.                         {
  534.                                 temp_data[wei_shu] = key_value;//将价格存入数组temp_data中
  535.                                 wei_shu ++;
  536.                                 price = price *10 + key_value;
  537.                         }
  538.                         else
  539.                         {
  540.                                 point_place = wei_shu; //记录小数点位置
  541.                         }
  542.                 }
  543.         }
  544.         else
  545.         {
  546.                 equal_sign = 1;
  547.         }
  548.         interrupt_flag = 1;
  549.         P1 = 0xf0;
  550.         EA = 1;
  551. }
复制代码



评分

参与人数 1黑币 +4 收起 理由
T阿里巴巴 + 4 赞一个!

查看全部评分

回复

使用道具 举报

ID:193104 发表于 2017-6-9 13:05 | 显示全部楼层
代码很简洁,功能很强大,应该是一个实用的电子秤
回复

使用道具 举报

ID:260802 发表于 2017-12-14 23:11 | 显示全部楼层
可以,好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:265870 发表于 2017-12-23 22:32 | 显示全部楼层
楼主真心棒!
回复

使用道具 举报

ID:326666 发表于 2018-5-12 17:43 | 显示全部楼层
那个u2是什么啊 看不清
回复

使用道具 举报

ID:263018 发表于 2018-11-29 13:49 | 显示全部楼层
附件呢
回复

使用道具 举报

ID:254939 发表于 2018-11-30 00:45 | 显示全部楼层
可以,好好看看
回复

使用道具 举报

ID:777921 发表于 2020-6-23 18:38 | 显示全部楼层
没有传感器呀
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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