[文章]基于小凌派RK2206开发板的电子秤功能实现

阅读量0
0
0
    秤是一种在生活中经常使用的测量工具,随着科学技术的发展,传统的机械结构的秤逐渐被淘汰,电子秤能够准确、快速的测量并且显示直观操作灵活方便等诸多优点备受人们的青睐。
    和传统秤相比较,电子秤利用新型传感器、高精度AD转换器件、单片机设计实现,具有精度高、功能强等特点。该电子秤的测量范围为0-5Kg,测量精度达到1g,有高精度,低成本的特点。电子秤采用液晶显示汉字和数值,比传统秤具有更高的准确性和直观性。另外,该电子秤电路简单,使用寿命长,应用范围广。

系统由RK2206+Openharmony+2.4寸LCD显示模块+hx711ad模块+按键模块+5kg压力传感器构成。
部分相关软件代码
  1. void HX711_GPIO_Init()
  2. {
  3.     PinctrlSet(HX711_DOUT, MUX_FUNC0, PULL_UP, DRIVE_KEEP);
  4.     LzGpioInit(HX711_DOUT);
  5.     LzGpioSetDir(HX711_DOUT, LZGPIO_DIR_IN);
  6.     LOS_Msleep(10);

  7.     PinctrlSet(HX711_SCK, MUX_FUNC0, PULL_KEEP, DRIVE_KEEP);
  8.     LzGpioInit(HX711_SCK);
  9.     LzGpioSetDir(HX711_SCK, LZGPIO_DIR_OUT);
  10.     LOS_Msleep(10);
  11. }

  12. uint32_t HX711_Read(void) //增益128
  13. {
  14.     uint32_t count;
  15.     uint8_t  i;
  16.     uint8_t  val;
  17.     HX711_SCK_L();
  18.     count = 0;

  19.     uint_tick ts = get_current_tick();
  20.     do{
  21.         LzGpioGetVal(HX711_DOUT, &val);
  22.     }while (val && get_time_us(ts) < 500000);

  23.     for (i = 0; i < 24; i++)
  24.     {
  25.         HX711_SCK_H();
  26.         count = count << 1;
  27.         HX711_SCK_L();
  28.         LzGpioGetVal(HX711_DOUT, &val);
  29.         if (val)
  30.             count++;
  31.     }
  32.     HX711_SCK_H();
  33.     count = count ^ 0x800000; //第25个脉冲下降沿来时,转换数据
  34.     ToyUdelay(7);
  35.     HX711_SCK_L();
  36.     return (count);
  37. }

  38. uint32_t e53_es_get_adc_average(void)
  39. {
  40.     uint8_t  cnt;
  41.     uint32_t val;
  42.     uint64_t sum = 0;
  43.     uint32_t min = -1;
  44.     uint32_t max = 0;

  45.     for (cnt = 0; cnt < 5; cnt++)
  46.     {
  47.         val = HX711_Read();
  48.         sum += val;
  49.         if (val > max)
  50.             max = val;
  51.         if (val < min)
  52.             min = val;
  53.     }
  54.     return (sum - max - min) / (cnt-2);
  55. }

  56. float e53_es_get_weight(float w, uint32_t peel_w, float percision)
  57. {
  58.     float weight = ES_GET_WEIGHT_VAL(HX711_Read(), peel_w); //通过公式将ad值转换为重量值
  59.    
  60.     if(percision == 0.0) percision = 0.01;

  61.     if (abs(w - weight) < percision)  //浮动小于percision不改变值
  62.     {
  63.         weight = w;
  64.     }
  65.     if (weight < 0 || weight > 10000.0)
  66.     {
  67.         weight = 0;
  68.     }

  69.     return weight;
  70. }

  71. unsigned int lcd_init(uint8_t dir)
  72. {
  73.     static bool init = false;
  74.     if(!init)
  75.     {
  76.         init = true;
  77.         if (LOS_SemCreate(1, &m_sem_lcd) != LOS_OK)
  78.         {
  79.             init = false;
  80.             printf("nn%s Falied to create Semaphore!!!nn", __FUNCTION__);
  81.         }
  82.     }
  83.     /* 重启lcd */
  84.     LCD_RES_Clr();
  85.     LOS_Msleep(100);
  86.     LCD_RES_Set();
  87.     LOS_Msleep(100);
  88.     LOS_Msleep(500);
  89.     lcd_wr_reg(0x11);
  90.     /* 等待LCD 100ms */
  91.     LOS_Msleep(100);
  92.     /* 启动LCD配置,设置显示和颜色配置 */
  93.     lcd_wr_reg(0X36);

  94.     switch (dir)
  95.     {
  96.     case 0:
  97.         g_lcd_size.w = LCD_W;
  98.         g_lcd_size.h = LCD_H;
  99.         lcd_wr_data8(0x00);
  100.         break;
  101.     case 1:
  102.         g_lcd_size.w = LCD_W;
  103.         g_lcd_size.h = LCD_H;
  104.         lcd_wr_data8(0xC0);
  105.         break;   
  106.     case 2:
  107.         g_lcd_size.w = LCD_H;
  108.         g_lcd_size.h = LCD_W;
  109.         lcd_wr_data8(0x70);
  110.         break;
  111.     default:
  112.         g_lcd_size.w = LCD_H;
  113.         g_lcd_size.h = LCD_W;
  114.         lcd_wr_data8(0xA0);
  115.         break;
  116.     }

  117.     lcd_wr_reg(0X3A);
  118.     lcd_wr_data8(0X05);
  119.     /* ST7789S帧刷屏率设置 */
  120.     lcd_wr_reg(0xb2);
  121.     lcd_wr_data8(0x0c);
  122.     lcd_wr_data8(0x0c);
  123.     lcd_wr_data8(0x00);
  124.     lcd_wr_data8(0x33);
  125.     lcd_wr_data8(0x33);
  126.     lcd_wr_reg(0xb7);
  127.     lcd_wr_data8(0x35);
  128.     /* ST7789S电源设置 */
  129.     lcd_wr_reg(0xbb);
  130.     lcd_wr_data8(0x35);
  131.     lcd_wr_reg(0xc0);
  132.     lcd_wr_data8(0x2c);
  133.     lcd_wr_reg(0xc2);
  134.     lcd_wr_data8(0x01);
  135.     lcd_wr_reg(0xc3);
  136.     lcd_wr_data8(0x13);
  137.     lcd_wr_reg(0xc4);
  138.     lcd_wr_data8(0x20);
  139.     lcd_wr_reg(0xc6);
  140.     lcd_wr_data8(0x0f);
  141.     lcd_wr_reg(0xca);
  142.     lcd_wr_data8(0x0f);
  143.     lcd_wr_reg(0xc8);
  144.     lcd_wr_data8(0x08);
  145.     lcd_wr_reg(0x55);
  146.     lcd_wr_data8(0x90);
  147.     lcd_wr_reg(0xd0);
  148.     lcd_wr_data8(0xa4);
  149.     lcd_wr_data8(0xa1);
  150.     /* ST7789S gamma设置 */
  151.     lcd_wr_reg(0xe0);
  152.     lcd_wr_data8(0xd0);
  153.     lcd_wr_data8(0x00);
  154.     lcd_wr_data8(0x06);
  155.     lcd_wr_data8(0x09);
  156.     lcd_wr_data8(0x0b);
  157.     lcd_wr_data8(0x2a);
  158.     lcd_wr_data8(0x3c);
  159.     lcd_wr_data8(0x55);
  160.     lcd_wr_data8(0x4b);
  161.     lcd_wr_data8(0x08);
  162.     lcd_wr_data8(0x16);
  163.     lcd_wr_data8(0x14);
  164.     lcd_wr_data8(0x19);
  165.     lcd_wr_data8(0x20);
  166.     lcd_wr_reg(0xe1);
  167.     lcd_wr_data8(0xd0);
  168.     lcd_wr_data8(0x00);
  169.     lcd_wr_data8(0x06);
  170.     lcd_wr_data8(0x09);
  171.     lcd_wr_data8(0x0b);
  172.     lcd_wr_data8(0x29);
  173.     lcd_wr_data8(0x36);
  174.     lcd_wr_data8(0x54);
  175.     lcd_wr_data8(0x4b);
  176.     lcd_wr_data8(0x0d);
  177.     lcd_wr_data8(0x16);
  178.     lcd_wr_data8(0x14);
  179.     lcd_wr_data8(0x21);
  180.     lcd_wr_data8(0x20);
  181.     lcd_wr_reg(0x29);
  182.    
  183.     return 0;
  184. }

  185. void e53_es_thread(uint32_t args)
  186. {
  187.     float w = 0, last_w = 0;
  188.     uint32_t *flag = (uint32_t *)args;
  189.     e53_es_init(*flag);

  190.     m_c12.peel.flag = false;
  191.     m_c12.add.flag  = false;
  192.     m_c12.dec.flag  = false;
  193.     m_c12.add.w     = 0;
  194.     m_c12.dec.w     = 0;
  195.     m_c12.init_peel = e53_es_get_adc_average();
  196.     m_c12.peel.w    = m_c12.init_peel;
  197.     m_c12.lcd_msg.e53_c12.data.peel_w = ES_GET_WEIGHT_VAL(m_c12.peel.w , m_c12.init_peel);

  198.     while (1)
  199.     {  
  200.         if(m_c12.add.flag)
  201.         {
  202.             m_c12.lcd_msg.e53_c12.data.weight -= m_c12.add.w;
  203.         }
  204.         else if(m_c12.dec.flag)
  205.         {
  206.             m_c12.lcd_msg.e53_c12.data.weight += m_c12.weight;
  207.         }

  208.         m_c12.weight = e53_es_get_weight(m_c12.lcd_msg.e53_c12.data.weight, m_c12.peel.w, 0.01);

  209.         if(m_c12.add.flag)
  210.         {
  211.             m_c12.lcd_msg.e53_c12.data.weight = m_c12.add.w+m_c12.weight;
  212.         }
  213.         else if(m_c12.dec.flag)
  214.         {
  215.             m_c12.lcd_msg.e53_c12.data.weight = m_c12.dec.w-m_c12.weight;
  216.         }
  217.         else
  218.         {
  219.             m_c12.lcd_msg.e53_c12.data.weight = m_c12.weight;
  220.         }

  221.         m_c12.lcd_msg.e53_c12.data.peel_flag = m_c12.peel.flag;
  222.         m_c12.lcd_msg.e53_c12.data.add_flag  = m_c12.add.flag;
  223.         m_c12.lcd_msg.e53_c12.data.dec_flag  = m_c12.dec.flag;
  224.         if(last_w != m_c12.lcd_msg.e53_c12.data.weight)
  225.         {
  226.             if(m_c12.add.flag)
  227.             {
  228.                 printf("add:%f,%.0fn", m_c12.add.w, m_c12.weight);            
  229.             }
  230.             else if(m_c12.dec.flag)
  231.             {
  232.                 printf("dec:%f,%.0fn", m_c12.dec.w, m_c12.weight);
  233.             }
  234.             printf("weight:%6.1f,peel:%6.1fn", m_c12.lcd_msg.e53_c12.data.weight, m_c12.lcd_msg.e53_c12.data.peel_w);
  235.         }
  236.         last_w = m_c12.lcd_msg.e53_c12.data.weight;
  237.         e53_c12_msg_send(&m_c12);
  238.     }
  239. }

  240. void e53_es_example()
  241. {
  242.     unsigned int ret = LOS_OK;
  243.     unsigned int thread_id;
  244.     TSK_INIT_PARAM_S task = {0};
  245.     task.pfnTaskEntry = (TSK_ENTRY_FUNC)e53_es_thread;
  246.     task.uwStackSize = 10240;
  247.     task.pcName = "e53_es_example";
  248.     task.usTaskPrio = 2;
  249.     ret = LOS_TaskCreate(&thread_id, &task);
  250.     if (ret != LOS_OK)
  251.     {
  252.         printf("Falied to create e53_es_example ret:0x%xn", ret);
  253.         return;
  254.     }
  255. }

  256. APP_FEATURE_INIT(e53_es_example);
复制代码
实际展示效果
上电后显示
图片6.png

20g砝码称重显示
图片7.png

电路板称重显
图片8.png


电路板+砝码显示
图片9.png
去皮20g砝码显示
图片10.png

回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友