找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机HX711+WT588D智能语音电子秤程序电路原理图设计

[复制链接]
ID:1108110 发表于 2024-3-6 17:27 | 显示全部楼层 |阅读模式
本系统采用单片机 + LCD1602液晶   + HX711AD模块   + 5 kg电阻应变式压力传感器 +蜂鸣器+矩阵键盘+WT588D语音模块而成。
1.单片机型号:STC89C52/51、AT89C52/51、AT89S52/51可以任选,都是51单片机。
2.称重传感器采用电子秤专用模拟/数字(A/D)转换器芯片hx711对传感器信号进行调理转换,提供更高的精度。
3.采用液晶LCD1602显示屏显示,第一行显示当前重量(单位为kg),第二行单价和总价(单位为元)。
4.按键具有提示声,具有超量程报警功能当超出压力传感器的量程时蜂鸣器会发出报警声。
5.采用高精度电阻应变式压力传感器,测量量程0 -5kg,测量精度可达3g。
6.采用4*4矩阵键盘进行人机交互,可以实现直接输入单价、删除单价、去皮、清零等功能操作非常方便。
7.采用WT588D语音模块实现语音播报功能。

4*4矩阵键盘定义如下
       1          2          3            15(删除键)
       4          5          6            14(去皮或是清零)
       7          8          9            13(清除单价)
10(未定义)   0    11(未定义)    12(未定义)

  键0—9为数字键,用于单价输入。
  键13为单价一键清零,按下该键则单价清为0。
  键14为去皮键,按下后当前重量清为0。
  键15为删除键,当我们单价输入错误时可以逐位删除输错的单价,删除后可以继续输入单价。

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
截图格式  双击可以打开.png 带语音.png

单片机源程序如下:
  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  4. #define ulong unsigned long
  5.   
  6. sbit rs=P1^0;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  7. sbit rw=P1^1;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  8. sbit e =P1^2;         //片选信号   下降沿触发

  9. sbit hx711_dout = P2^1;         //hx711 IO口定义
  10. sbit hx711_sck  = P2^0;         //hx711 IO口定义

  11. sbit beep = P2^7;     //蜂鸣器 IO口定义

  12. long weight;        //重量变量

  13. unsigned long Weight_Maopi;           //皮重变量

  14. #define GapValue 437.0

  15. uchar flag_300ms ;          //300毫秒的变量

  16. ulong price,z_price;   //单价 总价
  17. uchar flag_p;

  18. uchar menu_1,menu_2;  //设置不同参数的变量


  19. /***********************语音模块控制IO口的定义************************/
  20. sbit  VRST  = P1^3;          //复位脚
  21. sbit  VBUSY = P1^4;            //忙脚
  22. sbit  VDATA = P1^5;         //数据输入脚
  23. sbit  VCS   = P1^6;     //片选脚
  24. sbit  VCLK  = P1^7;            //时钟脚  


  25. /******1ms延时函数***12M晶振**************/
  26. void delay_1ms(uint q)
  27. {
  28.         uint i,j;
  29.         for(i=0;i<q;i++)
  30.                 for(j=0;j<120;j++);
  31. }

  32. /***********************语音模块子程序************************/
  33. void Send_threelines(unsigned char addr)
  34. {
  35.    unsigned char i;
  36.         VRST=0;                 //复位脚  低电平
  37.          VRST=1;                 //复位脚  高电平
  38.          VCS=0;                  //片选脚 低电平
  39.      for(i=0;i<8;i++)   //8位的数据 要循环8次1位1位的写入
  40.         {
  41.                 VCLK=0;                 //时钟脚 低电平
  42.                 if(addr&0x01 == 0x01)
  43.                 {
  44.                         VDATA=1;                 //数据输入脚 写数据1
  45.                 }
  46.                 else
  47.                         VDATA=0;                 //数据输入脚 写数据0
  48.                 addr>>=1;          //数据左移一位
  49.                 VCLK=1;                   //时钟脚   高电平
  50.         }
  51.         VCS=1;            //片选脚 高电平
  52.         while(VBUSY == 0);          //忙等待
  53. }


  54. /********************************************************************
  55. * 名称 : delay_uint()
  56. * 功能 : 小延时。
  57. * 输入 : 无
  58. * 输出 : 无
  59. ***********************************************************************/
  60. void delay_uint(uint q)
  61. {
  62.         while(q--);
  63. }

  64. /********************************************************************
  65. * 名称 : write_com(uchar com)
  66. * 功能 : 1602指令函数
  67. * 输入 : 输入的指令值
  68. * 输出 : 无
  69. ***********************************************************************/
  70. void write_com(uchar com)
  71. {
  72.          rs=0;             //写指令
  73.         rw=0;             //对1602写操作
  74.         P0=com;             //P0口对1602写指令数据
  75.         delay_uint(25);
  76.         e=1;                 //e=1使能信号
  77.         delay_uint(100);   //延时一下等1602完成操作
  78.         e=0;
  79. }

  80. /********************************************************************
  81. * 名称 : write_data(uchar dat)
  82. * 功能 : 1602写数据函数
  83. * 输入 : 需要写入1602的数据
  84. * 输出 : 无
  85. ***********************************************************************/
  86. void write_data(uchar dat)
  87. {
  88.          rs=1;             //写数据
  89.         rw=0;             //对1602写操作
  90.         P0=dat;                  //P0口对1602写数据
  91.         delay_uint(25);
  92.         e=1;                 //e=1使能信号
  93.         delay_uint(100);   //延时一下等1602完成操作
  94.         e=0;        
  95. }

  96. /********************************************************************
  97. * 名称 : write_string(uchar hang,uchar add,uchar *p)
  98. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  99.                   write_string(1,5,"ab cd ef;")
  100. * 输入 : 行,列,需要输入1602的数据
  101. * 输出 : 无
  102. ***********************************************************************/
  103. void write_string(uchar hang,uchar add,uchar *p)
  104. {
  105.         if(hang==1)   
  106.                 write_com(0x80+add);           //1602写第一行的地址
  107.         else
  108.                 write_com(0x80+0x40+add);   //1602写第二行的地址
  109.         while(1)                                                                                                                 
  110.         {
  111.                 if(*p == '\0')  break;        //\0字符串的结尾标志  break结束while循环 结束写字符
  112.                 write_data(*p);            //写数据
  113.                 p++;                    //指针地址加1  
  114.         }        
  115. }

  116. ////////////////在指定位置显示指定字符//////////
  117. void write_zifu(uchar hang,uchar add,uchar dat)
  118. {
  119.         if(hang==1)   
  120.                 write_com(0x80+add);           //1602写第一行的地址
  121.         else
  122.                 write_com(0x80+0x40+add);   //1602写第二行的地址
  123.         write_data(dat);
  124. }

  125. /********************************************************************
  126. * 名称 : write_lcd4_price(uchar hang,uchar add,uchar date)
  127. * 功能 : 显示价格
  128. * 输入 : 行,列,需要输入1602的数据
  129. * 输出 : 无
  130. ***********************************************************************/
  131. void write_lcd4_price(uchar hang,uchar add,uint date)
  132. {
  133.         if(hang==1)   
  134.                 write_com(0x80+add);           //1602写第一行的地址
  135.         else
  136.                 write_com(0x80+0x40+add);   //1602写第二行的地址
  137.         write_data(0x30+date/1000%10);         //显示千位数
  138.         write_data(0x30+date/100%10);    //显示百位数
  139.         write_data('.');                             //显示小数点
  140.         write_data(0x30+date/10%10);     //显示十位数
  141.          write_data(0x30+date%10);             //显示个位数        
  142. }

  143. /***********************lcd1602初始化设置************************/
  144. void init_1602()         //lcd1602初始化设置
  145. {
  146.         write_com(0x38);        //
  147.         write_com(0x0c);
  148.         write_com(0x06);
  149.         write_string(1,0,"   W:0.000kg    ");        //初始化1602显示
  150.         write_string(2,0,"P:00.00  Z:00.00");        //初始化1602显示
  151.         write_zifu(2,7,0x5c);        //¥               
  152. }

  153. /*******************重量显示程序***********************/
  154. void write_1602_yl(uchar hang,uchar add,uint date)


  155. /*********************AD采集程序*********************/
  156. unsigned long HX711_Read(void)        //增益128
  157. {
  158.         unsigned long count;
  159.         unsigned char i;
  160.           hx711_dout=1;
  161.           hx711_sck=0;
  162.           count=0;
  163.           for(i=0;i<24;i++)
  164.         {
  165.                   hx711_sck=1;
  166.                   count=count<<1;
  167.                 hx711_sck=0;
  168.                   if(hx711_dout)
  169.                         count++;
  170.         }
  171.          hx711_sck=1;
  172.     count=count^0x800000;//第25个脉冲下降沿来时,转换数据
  173.         hx711_sck=0;  
  174.         return(count);
  175. }


  176. void get_pizhong()          //获取皮重,秤盘重量
  177. {
  178.         Weight_Maopi = HX711_Read();        
  179. }

  180. void get_weight()          //获取被测物体重量
  181. {
  182.         weight = HX711_Read();
  183.         weight = weight - Weight_Maopi;                //获取净重
  184.         if(weight > 0)                        
  185.         {        
  186.                 weight = (unsigned int)((float)weight/GapValue);         //计算实物的实际重量                                                                                                                                       
  187.         }
  188.         else
  189.         {
  190.                 weight = 0;
  191.         }
  192. }

  193. /*****************语音报价********************/
  194. void bojia()  //语音报价
  195. {
  196.         Send_threelines(z_price / 1000 % 10);           //语音播放
  197.         Send_threelines(10);
  198.         Send_threelines(z_price / 100 % 10);           //语音播放
  199.          Send_threelines(11);             //点
  200.         Send_threelines(z_price / 10 % 10);           //语音播放
  201.         Send_threelines(z_price % 10);           //语音播放
  202.         Send_threelines(93);   //元
  203. }

  204. /*****************语音函数********************/
  205. void yuying()  //语音函数
  206. {
  207.          long z_p;
  208.         if(weight != 0)
  209.         if(weight == z_p)          //重量稳定
  210.         {
  211.                  bojia();  //语音报价
  212.          }
  213.          z_p = weight;
  214. }

  215. /********************独立按键程序*****************/
  216. uchar key_can;         //按键值

  217. void key()         //独立按键程序
  218. {
  219.         static uchar key_new = 0, key_l;
  220.         key_can = 20;                   //按键值还原
  221.         P3 = 0x0f;
  222.         if((P3 & 0x0f) != 0x0f)                //按键按下
  223.         {
  224.                 delay_1ms(1);                     //按键消抖动
  225.                 if(((P3 & 0x0f) != 0x0f) && (key_new == 1))
  226.                 {                                                //确认是按键按下
  227.                         key_new = 0;
  228.                         key_l = P3 | 0xf0;   //矩阵键盘扫描
  229.                         P3 = key_l;
  230.                         switch(P3)
  231.                         {
  232.                                 case 0xee:  key_can = 1;  break;  //得到按键值

  233.                                 case 0x77:  key_can = 12;  break;  //得到按键值         
  234.                         }        
  235.                         beep = 0;  //蜂鸣器叫一声
  236.                         delay_1ms(100);
  237.                         beep = 1;
  238.                 }                        
  239.         }
  240.         else
  241.                 key_new = 1;        
  242. }

  243. /************按键控制函数*************/
  244. void key_with()
  245. {
  246.         if(key_can <= 9)   //数字键
  247.         {
  248.                 if(flag_p >= 4)
  249.                 {
  250.                         flag_p = 0;
  251.                 }
  252.                 if(flag_p == 0)
  253.                         price = key_can;
  254.                 else
  255.                 {
  256.                         price = price * 10 + key_can;            
  257.                 }           
  258.                 write_lcd4_price(2,2,price);        //显示单价               
  259.                 flag_p ++;
  260.         }
  261.         if(key_can == 15)   //删除键
  262.         {   
  263.                 if(price != 0 )
  264.                 {
  265.                         flag_p --;
  266.                         price /= 10;                 //删除
  267.                         write_lcd4_price(2,2,price);//显示单价                                
  268.                 }
  269.         }
  270.         if(key_can == 14)   //去皮
  271.         {
  272.                 get_pizhong();          //获取皮重,秤盘重量
  273.         }
  274.         if(key_can == 13)   //价格清零
  275.         {
  276.                 flag_p = 0;
  277.                 price = 0;
  278.                 write_lcd4_price(2,2,price);//显示单价                                
  279.         }
  280. }

  281. /*****************主函数********************/
  282. void main()
  283. {        
  284.         beep = 0;  //蜂鸣器叫一声
  285.         delay_1ms(100);
  286.         P0 = P1 = P2 = P3 = 0xff;                //单片机IO口初始化为1
  287.          init_1602();                 //lcd1602初始化
  288.          get_pizhong();          //获取皮重,秤盘重量
  289.         while(1)
  290.         {
  291.                 key();         //独立按键程序
  292.                 if(key_can < 20)
  293.                         key_with();
  294.                 flag_300ms++;  
  295.                 if(flag_300ms >= 300)        //300毫秒执行一次里面的程序
  296.                 {
  297.                         flag_300ms = 0;
  298.                         get_weight();          //获取被测物体重量
  299.                          if(weight >= 0 )
  300.                                 write_1602_yl(1,5,weight);              //显示重量
  301.                         z_price = weight * price / 1000;   //总价等于重量*单价
  302.                         write_lcd4_price(2,11,z_price);        //显示总价                                       
  303.                         if(weight >= 5000)  //超重报警
  304.                                 beep = ~beep;        //蜂鸣器报警
  305.                         else
  306.                                 beep = 1;
  307.                         yuying();  //语音函数        
  308.                 }
  309.                 delay_1ms(1);
  310.         }
  311. }
复制代码

程序+原理图+PCB 51hei附件下载:
电子秤.7z (505.64 KB, 下载次数: 32)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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