找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4418|回复: 4
收起左侧

stc15w4单片机+HX711称重传感器+12864源程序

[复制链接]
ID:586048 发表于 2019-8-5 15:08 | 显示全部楼层 |阅读模式
这是我从网上一堆程序整合成的电子秤,发给大家参考参考,有什么不对的希望大家指出。
程序已经完全调试正常,在虽然小数点的显示不出来,但是稳定在克是没有什么问题的。

单片机源程序如下:
  1. /*********************************************************************
  2. //主时钟在 common.H 定义
  3. //u8,u16,u32已在"STC15Fxxxx.h"定义
  4. //因为15W系列快89系列 6——12倍,
  5. //时序图上面的时间也要相应的加倍,具体多少要具体测试
  6. *********************************************************************/

  7. /*
  8. **********************************************************************
  9. *                         头文件包含
  10. **********************************************************************
  11. */

  12. #include "common.h"
  13. #include "LCD12864.h"
  14. #include "HX711.h"
  15. //使用了宏晶科技的资料及程序

  16. /*********************************************************************
  17. 0 0 准双向口(标准 8051 单片机输出模式),灌电流可达 20mA,拉电流典型 值为 200uA,由于制造误差,实际为 150~270 uA。
  18. 0 1 推挽输出,强上拉输出,可达 20 mA,外加限流电阻,尽量少用
  19. 1 0 仅为输入(高阻)
  20. 1 1 开漏,内部上拉电阻断开,要外接上拉电阻才可以输出高电平。
  21. **********************************************************************/
  22. void port_mode(void)
  23. {
  24.         P0M1 = 0;        P0M0 = 0;        //设置为准双向口
  25.         P1M1 = 0;        P1M0 = 0;        //设置为准双向口
  26.         P2M1 = 0;        P2M0 = 0;        //设置为准双向口
  27.         P3M1 = 0;        P3M0 = 0;        //设置为准双向口
  28.         P4M1 = 0;        P4M0 = 0;        //设置为准双向口
  29.         P5M1 = 0;        P5M0 = 0;        //设置为准双向口
  30.         P6M1 = 0;        P6M0 = 0;        //设置为准双向口
  31.         P7M1 = 0;        P7M0 = 0;        //设置为准双向口
  32. }

  33. /*********************************************************************
  34. * 函 数 名       : main
  35. * 函数功能                   : 主函数
  36. * 参数列表       : 无
  37. * 函数输出             : 无
  38. *********************************************************************/

  39. void main(void)
  40. {
  41.                 port_mode();                                                                //设置为准双向口

  42.                 Lcd12864Init();                                                        //初始化
  43.                 Lcd12864ClearScreen();                        // 清屏        
  44.                 Lcd12864ShowStr(0,0,"   Holle word!");
  45.                 Lcd12864FlashScreen();
  46.                 delay_ms(200);
  47.                 Lcd12864ClearScreen();                        // 清屏        
  48.         delay_ms(1);
  49.         chengzhongmain();                                                                //显示重量:单位G
  50.         while(1);

  51. }
复制代码

所有资料51hei提供下载:
stc15w4k.zip (141.24 KB, 下载次数: 114)
回复

使用道具 举报

ID:586048 发表于 2019-8-5 15:14 | 显示全部楼层
12864的部分代码
  1. /*
  2. **********************************************************************
  3. *                         头文件包含
  4. **********************************************************************
  5. */
  6. #include "lcd12864.h"
  7. #include "delay.h"

  8. /*
  9. **********************************************************************
  10. *                         本地全局变量
  11. **********************************************************************
  12. */
  13. sbit gLcd12864_E  = P5^2;                        // LCD12864控制总线的使能信号
  14. sbit gLcd12864_RW = P5^1;                        // LCD12864控制总线的读写选择信号
  15. sbit gLcd12864_RS = P5^0;                        // LCD12864控制总线的数据/命令选择信号
  16. sbit gLcd12864_PSB= P5^4;                        // PSB脚为12864-12系列的串、并通讯功能切换,PSB=1为并口,PSB=0为串口


  17. // 显示的图片字模,取模软件在光盘工具软件目录下的字模提取软件
  18. // 注意要设置为横向取模,不要勾选字节倒序

  19. /*
  20. **********************************************************************
  21. *                         内部函数原型声明
  22. **********************************************************************
  23. */


  24. /*********************************************************************
  25. * 函 数 名       : Lcd12864WaitNoBusy
  26. * 函数功能                 : 阻塞等待LCD12864直到不忙状态
  27. * 参数列表       : 无
  28. * 函数输出             : 无
  29. *********************************************************************/
  30. static void Lcd12864WaitNoBusy(void)  //忙检测函数,判断bit7是0,允许执行;1禁止
  31. {
  32.     u8 sta = 0;      

  33.     LCD12864_DATA_PORT = 0xff;
  34.     gLcd12864_RS = 0;
  35.     gLcd12864_RW = 1;
  36.     do
  37.     {
  38.         gLcd12864_E = 1;
  39.         sta = LCD12864_DATA_PORT;
  40.         gLcd12864_E = 0;    //使能,用完就拉低,释放总线
  41.     }while(sta & 0x80);
  42. }


  43. /*********************************************************************
  44. * 函 数 名       : Lcd12864WriteCmd
  45. * 函数功能                 : 按照LCD12864低层时序向LCD内部写入8位命令字
  46. * 参数列表       : cmd - 待写入的8位命令字
  47. * 函数输出             : 无
  48. *********************************************************************/
  49. static void Lcd12864WriteCmd(u8 cmd)          
  50. {
  51.         Lcd12864WaitNoBusy();                // 先等待LCD1602处于不忙状态

  52.         gLcd12864_E = 0;                     // 禁止LCD
  53. //        Delay100us();
  54.         gLcd12864_RS = 0;                           // 选择发送命令模式
  55. //        Delay100us();
  56.         gLcd12864_RW = 0;                           // 选择写入模式       
  57. //        Delay100us();
  58.         LCD12864_DATA_PORT = cmd;    // 将1字节命令字放入8位并行数据端口
  59.         Delay100us();
  60.         gLcd12864_E = 1;                          // 使能LED
  61.         Delay100us();
  62.         gLcd12864_E = 0;                                // 禁止LCD
  63. }


  64. /*********************************************************************
  65. * 函 数 名       : Lcd12864WriteData
  66. * 函数功能                 : 按照LCD12864低层时序向LCD内部写入8位数据
  67. * 参数列表       : dat - 待写入的8位命令字
  68. * 函数输出             : 无
  69. *********************************************************************/
  70. static void Lcd12864WriteData(u8 dat)                       
  71. {
  72.         Lcd12864WaitNoBusy();                // 先等待LCD12864处于不忙状态

  73.         gLcd12864_E = 0;                     // 禁止LCD
  74. //        Delay100us();
  75.         gLcd12864_RS = 1;                           // 选择发送数据模式
  76. //        Delay100us();
  77.         gLcd12864_RW = 0;                           // 选择写入模式       
  78. //        Delay100us();
  79.         LCD12864_DATA_PORT = dat;    // 将1字节命令字放入8位并行数据端口
  80.         Delay100us();
  81.         gLcd12864_E = 1;                          // 使能LED
  82.         Delay100us();
  83.         gLcd12864_E = 0;                                // 禁止LCD
  84. }


  85. /************* 上面是底层时序函数,下面是高层时序函数 ***************/

  86. /*********************************************************************
  87. * 函 数 名       : Lcd12864Init
  88. * 函数功能                 : 按照LCD12864低层时序进行初始化序列
  89. * 参数列表       : 无
  90. * 函数输出             : 无
  91. *********************************************************************/
  92. void Lcd12864Init(void)                                               
  93. {
  94.         gLcd12864_PSB = 1;                        // 设置为8位并行总线
  95.         Delay100us();
  96.         // 发送初始化序列
  97.         Lcd12864WriteCmd(0x30);          // 0x30为基本指令集
  98.         Lcd12864WriteCmd(0x01);                // 0x01为清屏指令
  99.         Lcd12864WriteCmd(0x06);          // 地址自动加1
  100.         Lcd12864WriteCmd(0x0c);                // 整体显示、游标关闭
  101. }


  102. /*********************************************************************
  103. * 函 数 名       : Lcd12864ClearScreen
  104. * 函数功能                 : 清屏,即清除屏幕整个显示内容
  105. * 参数列表       : 无
  106. * 函数输出             : 无
  107. *********************************************************************/
  108. void Lcd12864ClearScreen(void)                                               
  109. {

  110.         // 发送初始化序列
  111.         Lcd12864WriteCmd(0x01);          // 0x01为清屏指令
  112. //        Lcd12864WriteCmd(0x34);                // 0x34为扩充指令集
  113. //        Lcd12864WriteCmd(0x30);          // 0x30为基本指令集
  114. }


  115. /*********************************************************************
  116. * 函 数 名       : Lcd12864FlashScreen3
  117. * 函数功能                         : 屏幕闪烁3次
  118. * 参数列表       : 无
  119. * 函数输出             : 无
  120. *********************************************************************/
  121. void Lcd12864FlashScreen(void)                                               
  122. {
  123.         u8 time = 0;

  124.         for (time=0; time<3; time++)
  125.         {
  126.                 Lcd12864WriteCmd(0x08);
  127.                 Delay500ms();
  128.                 Lcd12864WriteCmd(0x0c);       
  129.                 Delay500ms();               
  130.         }
  131. }
  132. /****************************************************
  133. //显示一个字符
  134. void Lcd12864ShowChar(u8 x, u8 y, u8 DData)
  135. {
  136.         switch (y)
  137.         {
  138.                 case 0:
  139.                         x |= 0x80;        break;
  140.                 case 1:
  141.                         x |= 0x90;        break;
  142.                 case 2:
  143.                         x |= 0x88;        break;
  144.                 case 3:
  145.                         x |= 0x98;        break;
  146.                 default:
  147.                                                 break;
  148.         }
  149.                                 Lcd12864WriteCmd(x); //这里不检测忙信号,发送地址码
  150.         Lcd12864WriteData(DData);
  151. }
  152. *******************************************************/
  153. /*********************************************************************
  154. * 函 数 名       : Lcd12864ShowStr
  155. * 函数功能                 : 从坐标(x, y)开始显示字符串str,注意这个函数不能跨行
  156. *                                   显示,因为显存地址是不连续的。
  157. * 参数列表       : x - 横向坐标,范围是0-7
  158. *                                   y - 纵向坐标,范围是0-3
  159. *                                   pStr - 指向待显示的字符串的指针
  160. * 函数输出             : 无
  161. *********************************************************************/
  162. void Lcd12864ShowStr(u8 x, u8 y, u8 *pStr)     //显示字符串
  163. {
  164.         switch (y)
  165.         {
  166.                 case 0:
  167.                         x |= 0x80;        break;
  168.                 case 1:
  169.                         x |= 0x90;        break;
  170.                 case 2:
  171.                         x |= 0x88;        break;
  172.                 case 3:
  173.                         x |= 0x98;        break;
  174.                 default:
  175.                                                 break;
  176.         }
  177.         Lcd12864WriteCmd(x);                                         // 发送地址码
  178.           while (*pStr != '\0')                         // 若到达字串尾则退出
  179.           {
  180.              Lcd12864WriteData(*pStr);
  181.              pStr++;
  182.                  Delay100us();
  183.           }
  184. }


  185. /*********************************************************************
  186. * 函 数 名       : Lcd12864ShowImage
  187. * 函数功能                         : 显示一个128*64分辨率的2值位图。
  188. * 参数列表       : pData - 指向待显示的位图图像数组指针                  
  189. * 函数输出             : 无
  190. *********************************************************************/
  191. //void Lcd12864ShowImage(u8 *pData)
  192. //{
  193. //        u8 x = 0, y = 0, i = 0;
  194. //        u16 tmp = 0;

  195. //        //分两屏,上半屏和下半屏,因为起始地址不同,需要分开
  196. //        for (i=0; i<9; i+=8)
  197. //        {               
  198. //                for (x=0; x<32; x++)
  199. //                {                                //32行
  200. //                        Lcd12864WriteCmd(0x34);
  201. //                        Lcd12864WriteCmd(0x80 + x);                // 列地址
  202. //                        Lcd12864WriteCmd(0x80 + i);                // 行地址,下半屏,即第三行地址0X88
  203. //                        Lcd12864WriteCmd(0x30);               
  204. //                        for (y=0; y<16; y++)       
  205. //                                Lcd12864WriteData(pData[tmp+y]);        // 将取数据写入LCD
  206. //                        tmp += 16;               
  207. //                }
  208. //        }
  209. //        Lcd12864WriteCmd(0x36);                                        // 扩充功能设定
  210. //        Lcd12864WriteCmd(0x30);
  211. //}


复制代码
回复

使用道具 举报

ID:586048 发表于 2019-8-5 15:14 | 显示全部楼层
HX711部分代码
  1. #include "HX711.h"
  2. #include "LCD12864.h"


  3. //校准参数
  4. //因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
  5. //当发现测试出来的重量偏大时,增加该数值。
  6. //如果测试出来的重量偏小时,减小改数值。
  7. //该值可以为小数

  8. #define GapValue A
  9. u16 A = 442.8;//这是一个修正系数,例如100g砝码称出来是99.2g,A=99.2*A/原数据;

  10. #define MEDIAN_LEN  9               //中值滤波的滤波长度,一般取奇数
  11. #define MEDIAN      5               //中值在滤波数组中的位置
  12. u32   buffer[MEDIAN_LEN];           //中值滤波的数据缓存
  13. u16     medleng = 0;                //一组中值滤波数据中,进入滤波缓存的数据个数
  14. u32   xd,xd1;                       //数据对比大小中间变量

  15. //函数或者变量声明
  16. extern void Delay_ms(unsigned int n);
  17. extern void Get_Maopi();
  18. extern void Get_Weight();
  19. extern void Scan_Key();


  20. /*unsigned char code b[]={"0123456789.-g"};                //ZF        占两个字符*/
  21. u8        dat[]="0000.00G";

  22. unsigned long HX711_Buffer = 0;
  23. unsigned long Weight_Maopi = 0;
  24. long Weight_Shiwu = 0;

  25. unsigned char flag = 0;
  26. bit Flag_ERROR = 0;                                                                       
  27. sbit KEY1 = P2^3;


  28. sbit speak= P5^5;//板子上的测试灯

  29. //****************************************************
  30. //读取HX711
  31. //****************************************************
  32. u32 HX711_Read(void)        //增益128
  33. {
  34.         unsigned long count;
  35.         unsigned char i;
  36.        
  37.           HX711_DOUT=1;
  38.                 Delay5us();
  39.           HX711_SCK=0;
  40.           count=0;
  41.                         EA = 1;
  42.                         while(HX711_DOUT);
  43.                         EA = 0;
  44.                         for(i=0;i<24;i++)        //做24个脉冲
  45.                                 {
  46.                                         HX711_SCK=1;
  47.                                         count=count<<1;
  48.                                         HX711_SCK=0;
  49.                                        
  50.                                         if(HX711_DOUT)
  51.                                                 count++;
  52.                                 }
  53.                 HX711_SCK=1;
  54.     count=count^0x800000;//第25个脉冲下降沿来时,转换数据
  55.                 Delay5us();
  56.                 HX711_SCK=0;  
  57.                 return(count);
  58. }

  59. //****************************************************
  60. //显示称重程序
  61. //****************************************************
  62. void chengzhongmain()
  63. {
  64.         u16 i;
  65.                 Get_Maopi();                                //称毛皮重量
  66.                 Delay100us();
  67.                 Get_Maopi();                                //再次称毛皮重量
  68.                
  69.                 while(1)
  70.                 {
  71.                         EA = 0;
  72.                         Get_Weight();                        //称重
  73.                         EA = 1;

  74.                         Scan_Key();                                //按键,触发去皮

  75.                         if(medleng == 0)                    //缓存的第1个元素,直接放入,不需要排序
  76.                         {
  77.                                 buffer[0] = Weight_Shiwu; medleng = 1;
  78.                         }
  79.                         else                                            //插入排序算法,按从小到大的顺序排列
  80.                         {  
  81.                                 for(i = 0; i < medleng; i ++)  
  82.                                 {
  83.                                         if( buffer[i] > Weight_Shiwu)         // 轮询到的当前元素>AD值,则交换它们的值,xd为中间变量存放位置
  84.                                         {
  85.                                                 xd = Weight_Shiwu; Weight_Shiwu = buffer[i]; buffer[i] = xd;
  86.                                         }
  87.                                 }
  88.                                 buffer[medleng] = Weight_Shiwu;         //把轮询出较大的数放入缓存的后面.
  89.                                 medleng++;
  90.                         }               
  91.                         //显示当前重量
  92.                 if(medleng >= MEDIAN_LEN)                                     //ADC采样的数据个数达到中值滤波要求的数据个数
  93.                 {
  94.                         Weight_Shiwu = buffer[MEDIAN];            //最终重量取中值滤波数组的中间值
  95.                         medleng = 0;
  96.                         if( Flag_ERROR == 1)
  97.                         {
  98.                                 Lcd12864ClearScreen();                                                                                        //清屏
  99.                                 Lcd12864ShowStr(2,1,"error");                                                                //显示错误
  100.                                 speak=0;                                                                                                                                                //大于5千克时亮
  101.                                 delay_ms(200);
  102.                                 Lcd12864ClearScreen();                                                                                        //清屏
  103.                         }               
  104.                         else
  105.                         {                                                                                                     
  106.                                                         speak=1;       
  107.                                         Lcd12864ShowStr(0,0,"重量:");                                                        //占三个字符
  108.                                         dat[0] = Weight_Shiwu/100000+'0';                                                //显示千位
  109.                                         dat[1] = Weight_Shiwu%100000/10000+'0';
  110.                                         dat[2] = Weight_Shiwu%10000/1000+'0';
  111.                                         dat[3] = Weight_Shiwu%1000/100+'0';
  112.                                         dat[5] = Weight_Shiwu%100/10 + '0';                                        //显示小数点后一位
  113.                                         dat[6] = Weight_Shiwu%10 + '0';                                       
  114.                                         Lcd12864ShowStr(3,0,dat);                                                                                //从第三个字符开始显示,按中文字符算两个
  115.                         }                                                                                                                                                                                                //中文前面不能只有一个英文字符,否则会乱码
  116.                 }
  117.         }
  118. }


  119. //扫描按键
  120. void Scan_Key()                                        //key = P2^3
  121. {
  122.         if(KEY1 == 0)
  123.         {
  124.                 Delay_ms(5);
  125.                 if(KEY1 == 0)
  126.                 {
  127.                         while(KEY1 == 0);
  128.                         Get_Maopi();                        //去皮
  129.                 }       
  130.         }
  131. }

  132. //****************************************************
  133. //称重:获取被测物体重量
  134. //****************************************************
  135. void Get_Weight()
  136. {
  137.         Weight_Shiwu = 100*HX711_Read();                                                        //放大获取小数
  138.         Weight_Shiwu = Weight_Shiwu - Weight_Maopi;                //获取净重
  139.         if(Weight_Shiwu > 1)                       
  140.         {       
  141.                 Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/GapValue);         //计算实物的实际重量,重量转换函数,传感器型号不同此函数要适当修改(修GapValue大小)
  142.                                                                                                                                                                                                                                                                                                
  143.                 if(Weight_Shiwu > 500000)                //超重报警,5千克放大了100倍
  144.                 {
  145.                         Flag_ERROR = 1;       
  146.                 }
  147.                 else
  148.                 {
  149.                         Flag_ERROR = 0;
  150.                 }
  151.         }
  152.         else
  153.         {
  154.                 Weight_Shiwu = 0;
  155.         //        Flag_ERROR = 1;                                //负重报警
  156.         }
  157.        
  158. }

  159. //****************************************************
  160. //获取毛皮重量,秤盘重量
  161. //****************************************************
  162. void Get_Maopi()
  163. {
  164.         /*u32 hx711_dat;
  165.         u16 i;
  166.         for(i=0;i<MEDIAN_LEN;i++)
  167.         {
  168.                 hx711_dat=HX711_Read();                          //HX711AD转换数据处理
  169.                 if(medleng == 0)                    //缓存的第1个元素,直接放入,不需要排序
  170.                 {
  171.                         buffer[0] = hx711_dat; medleng = 1;
  172.                 }
  173.                 else                                    //插入排序算法,按从小到大的顺序排列
  174.                 {  
  175.                         for(i = 0; i < medleng; i ++)  
  176.                         {
  177.                                 if( buffer[i] > hx711_dat)                 // 轮询到的当前元素>AD值,则交换它们的值,xd为中间变量存放位置
  178.                                 {
  179.                                         xd = hx711_dat; hx711_dat = buffer[i]; buffer[i] = xd;
  180.                                 }
  181.                         }
  182.                         buffer[medleng] = hx711_dat;                 //把轮询出较大的数放入缓存的后面.
  183.                         medleng++;
  184.                 }               
  185.                 if(medleng >= MEDIAN_LEN)                     //ADC采样的数据个数达到中值滤波要求的数据个数
  186.                 {
  187.                         hx711_dat = buffer[MEDIAN];            //最终重量取中值滤波数组的中间值
  188.                         medleng = 0;
  189.                 }
  190.         }*///去掉上面这个可以加快速度,但精度有所降低,如果不显示小数,加不加无所谓
  191.         Weight_Maopi = 100*HX711_Read();                //放大获取小数
  192. }       
复制代码
回复

使用道具 举报

ID:597842 发表于 2019-8-8 17:39 | 显示全部楼层
这是用的51还是?
回复

使用道具 举报

ID:62514 发表于 2019-8-16 20:39 | 显示全部楼层
学习中,希望一次调试通过。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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