本帖最后由 通州彭于晏 于 2021-7-9 18:30 编辑
基于CC2540单片机的简易电子秤:
随着微电子技术的应用,电子秤的出现迅速得到了人们的青睐。相比传统的机械式称量工具,电子秤具有称量精度高、功能齐全、装机体积小、应用范围广、易于操作使用等优点,在外形布局、工作原理、结构和材料上都是全新的计量衡器。 本设计的简易电子秤以CC2540为核心,以电阻应变片采集应变数据,通过HX711放大并进行AD转换供单片机处理,用LCD12864显示所测量5.00g-500g范围内的重量,且满足误差在一定范围内的要求,同时本电子秤系统还提供物品单价设置可进行价格的计算和多个物品的金额累加以及去皮功能。此外,本设计还具有界面切换、个体选择功能。通过一些简单低成本的元器件就完成了一个功能齐全的电子秤的制作,将传统电子秤的成本进行了缩减。 关键词:简易电子秤 CC2540 电阻应变片 HX711   方案比较与选取 2.1 压力传感器的比较与选择 方案一:采用惠更斯电桥,当电阻应变片承受载荷产生变形时,其阻值将发生变化。从而使电桥失去平衡,产生相应的差动信号,但其线性度不理想。 方案二∶采用全桥电路,此电路对压力的灵敏度比惠更斯电桥增加一倍以上,测量的精度将更加准确,线性度更好。还具有机械滞后小横向效应小以及体积小的特点。 通过上述两种方案比较,全桥差动压力传感器符合设计要求,称重范围为0~5Kg,满足题目要求的5g ~500g的测量范围。 2.2 A/D转换模块的比较与选取 方案一:采用分立元件构成的仪用放大电路对电阻应变式传感器输出的模拟信号进行放大,然后外接高精度的AD模块将模拟信号转换成数字信号送给单片机进行处理。 方案二:采用集成芯片HX711,其内部PGA和24位AD,放大倍数可以在128和64两档中选择,24位的精度足够准确的分辨出题设中1g的精度变化要求。 通过比较,方案二的电路具有简单且高效的特点,节省了很多电路的调试时间而且降低了实物制作的面积,所以,本设计采用方案二。 2.3 单片机模块的比较与选取 方案一∶采用最常见的51单片机作为主控芯片,其主频范围在11~32MHz范围内可选择,同时具有32个IIO口,完全满足O口的使用,价格合适,便于设计整体电路。 方案二:采用CC2540,是一个超低消耗功率的真正系统单晶片,它整合了包含微控制器、主机端及应用程序在一个元件上且结合一个优异的无线射频传送接收器及一个工业标准的加强型8051微控制器,CC2540可让强固的主控或从属式节点以很低的成本建立起来,它具有很低的睡眠模式功率消耗及不同工作模式间短暂的转换时间,适用于需要超低消耗功率的系统。 通过比较,方案二的功能更为全面,故最终选取方案二。 总体框架:   3.1.1 全桥差动压力传感器
图 3.1.1(b) 电阻应变式传感器的电路工作原理
|

传感器应题目要求选用电阻应变片,是用于测量应变的元件。它能将机械构件上应变的变化转换电阻变化。为了减少测量误差,本简易电子秤系统采用全桥差动形式,全桥差动测量电路不仅没有非线性测量误差,且电压灵敏度是单臂电阻应变片工作时的四倍,运用全桥差动使得本电子秤系统更加稳定和可靠。 
图 3.1.1(a) 电阻应变式传感器的受力工作原理
应变式力传感器的受力工作原理如图 3.1.1(a)所示。将应变片粘贴到受力的力敏型弹性元件上,当弹性元件受力产生形变(上面的应变片受力拉伸,下面的应变片受力压缩),转化成电阻变化。将应变片接成如图3.1.1(b)所示的电桥,力引起的电阻变化将转换为测量电路的电压变化,通过测量输出电压的数值,再通过换算即可得到所测量物体的重量。 电桥的四个臂上接工作应变片,都参与机械变形,同处一个温度场,温度影响相互抵消,电压输出灵敏度高。当4个应变片的材料、阻值都想同时,可推导出以下公式:   [payamount]10.00[/payamount]
[pay]软件模块:
称重模块:
- void GetWeight()
- {
- unsigned long Count;
-
- unsigned char i;
- //ADSK=0;
- HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF );
- Count=0;
- while(ADDO);
- for(i=0;i<24;i++)
- {
- //ADSK=1;
- HalLedSet(HAL_LED_1, HAL_LED_MODE_ON );
- Count=Count<<1;
- // ADSK=0;
- HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF );
- if(ADDO) Count++;
-
- }
- ADSK=1;
-
- HalLedSet(HAL_LED_1, HAL_LED_MODE_ON );
- Count=Count^0x800000;//负o电Ì?压1正y转Áa换?
- //ADSK=0;
- HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF );
-
- weigh = (uint32)(Count>>3); //取¨?高?十º?六¢¨´位?有®D效¡ì值¦Ì
- sum = sum - data[count];
- sum = sum + weigh;
- data[count] = weigh;
- if((sum>>4)<20460)
- weigh=(sum>>4)/3.27-3972;///3.27;///34;
- else weigh=(sum>>4)/3.27-26778-3972;
- return;
- }
界面设计模块:
- void Draw()
- {
- switch(menu)
- {
- case 0:
- HalLcdWriteString("ELECTRONIC SCALE",HAL_LCD_LINE_1);
- HalLcdWriteString("Weight:5or500g",HAL_LCD_LINE_2);
- HalLcdWriteString("please chose:",HAL_LCD_LINE_3);
- if((count< 7)&&(select == 0))
- {
- HalLcdWriteString(">>* weight",HAL_LCD_LINE_4);
- }else
- {
- HalLcdWriteString(" weight",HAL_LCD_LINE_4);
- }
-
- if((count< 7)&&(select == 1))
- {
- HalLcdWriteString(">>* weight maopi",HAL_LCD_LINE_5);
- }else
- {
- HalLcdWriteString(" weight maopi",HAL_LCD_LINE_5);
- }
-
- if((count< 7)&&(select == 2))
- {
- HalLcdWriteString(">>* input price",HAL_LCD_LINE_6);
- }else
- {
- HalLcdWriteString(" input price",HAL_LCD_LINE_6);
- }
- if((count< 7)&&(select == 3))
- {
- HalLcdWriteString(">>* all price",HAL_LCD_LINE_7);
- }else
- {
- HalLcdWriteString(" all price ",HAL_LCD_LINE_7);
- }
- if((count< 7)&&(select == 4))
- {
- HalLcdWriteString(">>* reset",HAL_LCD_LINE_8);
- }else
- {
- HalLcdWriteString(" reset",HAL_LCD_LINE_8);
- }
- break;
-
- case 1:
- HalLcdWriteString("ELECTRONIC SCALE",HAL_LCD_LINE_1);
- HalLcdWriteString("according put:",HAL_LCD_LINE_2);
- myLcdStringV("Weight:",((weigh-qupi)*10),10,HAL_LCD_LINE_3);
- HalLcdWriteString("please chose:",HAL_LCD_LINE_6);
- if((count< 7)&&(select == 0))
- {
- HalLcdWriteString(">>* add",HAL_LCD_LINE_7);
- }else
- {
- HalLcdWriteString(" add",HAL_LCD_LINE_7);
- }
- if((count< 7)&&(select == 4))
- {
- HalLcdWriteString(">>* reset",HAL_LCD_LINE_8);
- }else
- {
- HalLcdWriteString(" reset",HAL_LCD_LINE_8);
- }
- break;
- case 2:
- HalLcdWriteString("ELECTRONIC SCALE",HAL_LCD_LINE_1);
- HalLcdWriteString("according put:",HAL_LCD_LINE_2);
- HalLcdWriteStringValue("input price:",price,10,HAL_LCD_LINE_3);
- HalLcdWriteString("please chose:",HAL_LCD_LINE_6);
- if((count< 7)&&(select == 0))
- {
- HalLcdWriteString(">>* add",HAL_LCD_LINE_7);
- }else
- {
- HalLcdWriteString(" add",HAL_LCD_LINE_7);
- }
- if((count< 7)&&(select == 1))
- {
- HalLcdWriteString(">>* reset",HAL_LCD_LINE_8);
- }else
- {
- HalLcdWriteString(" reset",HAL_LCD_LINE_8);
- }
- break;
- case 3:
- HalLcdWriteString("ELECTRONIC SCALE",HAL_LCD_LINE_1);
- HalLcdWriteString("according put:",HAL_LCD_LINE_2);
- HalLcdWriteStringValue("total price:",(weigh-qupi)*price/10,10,HAL_LCD_LINE_3);
- HalLcdWriteString("please chose:",HAL_LCD_LINE_6);
- if((count< 7)&&(select == 0))
- {
- HalLcdWriteString(">>* add",HAL_LCD_LINE_7);
- }else
- {
- HalLcdWriteString(" add",HAL_LCD_LINE_7);
- }
- if((count< 7)&&(select == 1))
- {
- HalLcdWriteString(">>* reset",HAL_LCD_LINE_8);
- }else
- {
- HalLcdWriteString(" reset",HAL_LCD_LINE_8);
- }
- break;
- case 4:
- HalLcdWriteString("ELECTRONIC SCALE",HAL_LCD_LINE_1);
- HalLcdWriteString("according put:",HAL_LCD_LINE_2);
- myLcdStringV("Weight maopi:",weigh*10, 10,HAL_LCD_LINE_3);
- HalLcdWriteString("please chose:",HAL_LCD_LINE_6);
- if((count< 7)&&(select == 0))
- {
- HalLcdWriteString(">>* add",HAL_LCD_LINE_7);
- }else
- {
- HalLcdWriteString(" add",HAL_LCD_LINE_7);
- }
- if((count< 7)&&(select == 1))
- {
- HalLcdWriteString(">>* reset",HAL_LCD_LINE_8);
- }else
- {
- HalLcdWriteString(" reset",HAL_LCD_LINE_8);
- }
- break;
- }
- }
按键设计模块:
浮点数显示模块:
- unsigned char * ltoah(unsigned long l, unsigned char *buf)
- {
-
- unsigned char tmp1[10] = "", tmp2[10] = "", tmp3[10] = "";
- unsigned short num1, num2, num3;
- unsigned char i;
- buf[0] = '\0';
- num1 = l % 100;
- num2 = (l / 100) % 100;
- num3 = (unsigned short)(l / 10000);
- if (num3) _itoa(num3, tmp3, 10);
- if (num2) _itoa(num2, tmp2, 10);
- if (num1) _itoa(num1, tmp1, 10);
- if (num3)
- {
- strcpy((char*)buf, (char const*)tmp3);
- for (i = 0; i < 2 - strlen((char const*)tmp2); i++)
- strcat((char*)buf, "0");
- }
- strcat((char*)buf, (char const*)tmp2);
- if (num3 || num2)
- {
- for (i = 0; i < 2 - strlen((char const*)tmp1); i++)
- strcat((char*)buf, "0");
- }
- strcat((char*)buf,".");
- strcat((char*)buf, (char const*)tmp1);
- if (!num3 && !num2 && !num1)
- strcpy((char*)buf, "0");
- return buf;
- }
- void myLcdStringV( char *title, uint16 value, uint8 format, uint8 line )
- {
- char buf[10];
- unsigned char * number;
- number = ltoah(value, buf);
- char len = strlen(title);
- title[len] = 32;
- char com[30];
- int i;
- for(i = 0; i<30; i++)
- {
- if(title[i]==0)
- break;
- else
- com[i] = title[i];
- }
- int j = i;
- for( ; i<30; i++)
- {
- com[i] = buf[i-j];
- if(buf[i-j]==0)
- break;
-
- }
- // strcat((char*)title, (char const*)buf);
- HalLcdWriteString(com,line);
-
- }
总代码:
- /*********************************************************************
- * INCLUDES
- */
- #include "bcomdef.h"
- #include "OSAL.h"
- #include "OSAL_PwrMgr.h"
- #include "OnBoard.h"
- #include "hal_adc.h"
- #include "hal_led.h"
- #include "hal_key.h"
- #include "hal_lcd.h"
- #include "SimpleOsal.h"
- #define ADSK P1_0 //定义为711时钟
- #define ADDO P1_3 //定义为711输入
- uint8 SimpleOsal_TaskID;
- static char menu;
- static char select;
- static int weigh,total_weigh;
- static int price=5;
- static int total_price;
- unsigned long data[10];
- unsigned long sum;
- long Weight_Shiwu,shiwu;
- long qupi=0;
-
- #define GapValue 100
- char count;
- unsigned int ADval;
- #define SBP_PERIODIC_EVT_PERIOD 2000
- /*********************************************************************
- * PUBLIC FUNCTIONS
- */
- static void simpleOsal_HandleKeys( uint8 shift, uint8 keys );
- static void SimpleOsal_ProcessOSALMsg( osal_event_hdr_t *pMsg );
- void myLcdStringV( char *title, uint16 value, uint8 format, uint8 line );
- void Draw();
- void GetWeight();
- unsigned char * ltoah(unsigned long l, unsigned char *buf);
- /*********************************************************************
- * @fn SimpleOsal_Init
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Initialization function for the Simple BLE Peripheral App Task.
- * This is called during initialization and should contain
- * any application specific initialization (ie. hardware
- * initialization/setup, table initialization, power up
- * notificaiton ... ).
- *
- * @param task_id - the ID assigned by OSAL. This ID should be
- * used to send messages and set timers.
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] none
- */
- void SimpleOsal_Init( uint8 task_id )
- {
- SimpleOsal_TaskID = task_id;
-
- sum = 0;
- for(int i=0; i<10; i++)
- {
- data[i]=0;
-
- }
-
- // Register for all key events - This app will handle all key events
- RegisterForKeys( SimpleOsal_TaskID );
- //熄灭LED1
- HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF );
- //点亮背光
- HalLedSet(HAL_LED_4, HAL_LED_MODE_ON );
-
- //向lcd输出相关信息
- //第一行,显示内容:"SimpleOsal"
- // HalLcdWriteString( "SimpleOsal", HAL_LCD_LINE_1 );
- //第二行,显示内容:"Ghostyu OSAL Test"
- // HalLcdWriteString( "Ghostyu OSAL Test", HAL_LCD_LINE_2 );
- //向led输出相关信息
- //HalLcdWriteString( "SimpleOsal", HAL_LCD_LINE_1 );
- //HalLcdWriteString( "Ghostyu OSAL Test", HAL_LCD_LINE_2 );
- // Setup a delayed profile startup
- //为了方便观察实验现象,延时2s执行后面的操作
- osal_start_timerEx( SimpleOsal_TaskID, SBP_START_DEVICE_EVT, 2000 );
- menu = 0;
- select = 1;
- count = 0;
- ADval = 0;
- weigh = 98888;
- //#define ADSK P0_2 //定义P1.7口为711时钟
- //#define ADDO P0_3 //定义P1.6口为711输入
- //P0DIR |= BV(2);
- //P0DIR &=~BV(2);
- // P0SEL &= ~( BV(2) | BV(3)); // 定义为一般GPIO
- P1DIR &=~BV(3);
- P1SEL &= ~ BV(3); //| BV(3)); // 定义为一般GPIO
- P1INP &= ~ BV(3);
-
- }
- /*********************************************************************
- * @fn SimpleOsal_ProcessEvent
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Simple BLE Peripheral Application Task event processor. This function
- * is called to process all events for the task. Events
- * include timers, messages and any other user defined events.
- *
- * @param task_id - The OSAL assigned task ID.
- * @param events - events to process. This is a bit map and can
- * contain more than one event.
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] events not processed
- */
- static char cou = 0;
- uint16 SimpleOsal_ProcessEvent( uint8 task_id, uint16 events )
- {
-
-
- VOID task_id; // OSAL required parameter that isn't used in this function
- float temp;
- if ( events & SYS_EVENT_MSG )
- {
- uint8 *pMsg;
- if ( (pMsg = osal_msg_receive( SimpleOsal_TaskID )) != NULL )
- {
- SimpleOsal_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
- // Release the OSAL message
- VOID osal_msg_deallocate( pMsg );
- }
- // return unprocessed events
- return (events ^ SYS_EVENT_MSG);
- }
- if ( events & SBP_START_DEVICE_EVT )
- {
- //点亮LED1,表示OSAL正在运行
-
- osal_start_timerEx( SimpleOsal_TaskID, SBP_START_DEVICE_EVT, 100 );
- if(count<9)
- {
- //HalLedSet(HAL_LED_1, HAL_LED_MODE_ON );
- count = count +1;
- }
- else
- {
- // HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF );
- count = 0;
- }
- GetWeight();
-
- //ADval
- // temp = 78.332;
- // unsigned long l = 49548;
- // char st1[20];
- // unsigned char * st = ltoah(l, st1);
- //HalLcdWriteString( st, HAL_LCD_LINE_3 );
- Draw();
-
- //HalLcdWriteStringValue("Weigh:", weigh, 10,HAL_LCD_LINE_1);
- //cou = cou + 1;
- //HalLcdWriteStringValue("cou:", cou, 10,HAL_LCD_LINE_2);
-
- return ( events ^ SBP_START_DEVICE_EVT );
- }
- // Discard unknown events
- return 0;
- }
附录:原理图
[/pay]
|