基于stm32的智能电子称(开源)

基于stm32的智能电子称(开源)

前言

源代码下载链接:

https://download.csdn.net/download/m0_74712453/90071676

功能演示

基于stm32的智能电子称

简介

这是最近别人让我帮他做的一个毕业设计,总体来说非常简单,半天都不需要就可以实现,我做完之后,打算开源在这里让大家进行学习,我们先看一下他的任务书吧:

主要内容与基本要求:

本设计采用单片机作为主控制芯片,通过按键和微型屏幕来实现人机交互。同时可以通过无线通讯模块来实现信息的传递。本课题的主要研究内容如下:

收集并阅读相关资料,确定系统的总体设计方案。硬件系统的设计:包括单片机最小开发板、液晶显示模块、压力传感器、蓝牙模块ADC模块等。在软件的编程方面采用C语言作为系统程序语言。系统实物体的制作以及相关的调试,要求整个系统完整并且稳定运行。

基本要求如下:

按键结合液晶屏幕,实现按键切换功能。用蓝牙模块控制实现系统相关参数的设置。液晶屏显示功能提醒词、系统的状态、已设置的参数等。实现压力传感器的数据采集。实现读取重量的功能并通过液晶屏幕显示超过最大重量报警

硬件资料

序号元器件型号数量#DescriptionCommentQuantity1STM32F103C8T6最小系统板/120.96寸OLED屏幕/13语音播报模块JQ8900-16P14喇叭8欧3W喇叭154.7K电阻0603R16三极管SS805017有源蜂鸣器BUZ-TH_BD12.018按键SW-TH_4P49主从一体蓝牙模块HC-05110PM254-1-08-Z-8.5HDR-TH_8P-P2.54211PM254-1-04-Z-8.5HDR-TH_4P-P2.54212PM254-1-02-Z-8.5HDR-TH_2P-P2.54113Type-c充电线/1

PCB图以及原理图

软件分析

工程文件

Start:存放stm32配置的起始文件、内核相关文件、系统文件。

Library:存放stm32f103的标准库文件。

User:存放用户文件。

Hardware:存放硬件文件,包括蜂鸣器、HX711、OLED、JQ8900......

System:存放用户写的一些系统文件,例如延时、时钟配置、相关宏定义。

软件流程

1、各模块初始化

Key_Init();//按键初始化

Buzzer_Init();//蜂鸣器初始化

OLED_Init();//oled初始化

Serial_Init();//蓝牙串口初始化

HX711_Init();//HX711初始化

Interface_Init();//接口初始化(屏幕初始化,显示对应内容)

JQ8900_Init();//语音模块初始化

2、初始化模块状态

HX711_SetTareWeight();//开机默认去皮一次

JQ8900_SetVolume(15);//设置音量为15

3、检测蓝牙模块是否发送消息(如果搜到消息,将消息转换成按键值,之后在进行对应按键按下的处理)

if(Serial_GetRxFlag())

{

Key_Num = Serial_GetRxData();

}

4、 扫描按键(根据按键设置对应的键值,之后进行对应按键按下的处理)

Key_Num = Key_GetNum(); //扫描按键

5、检测是否超出电子称的最大重量

if(HX711_ReadCount()>Weight_Max) //超过设定的最大重量

{

//显示超重界面

OLED_Clear();

OLED_ShowF16x16(1,7,26);//警告

OLED_ShowF16x16(1,9,27);

OLED_ShowF16x16(2,3,28);//超出最大重量

OLED_ShowF16x16(2,5,29);

OLED_ShowF16x16(2,7,30);

OLED_ShowF16x16(2,9,31);

OLED_ShowF16x16(2,11,32);

OLED_ShowF16x16(2,13,33);

OLED_ShowF16x16(4,1,34);//请按下返回键返回

OLED_ShowF16x16(4,3,35);

OLED_ShowF16x16(4,5,36);

OLED_ShowF16x16(4,7,37);

OLED_ShowF16x16(4,9,38);

OLED_ShowF16x16(4,11,39);

OLED_ShowF16x16(4,13,37);

OLED_ShowF16x16(4,15,38);

while(Key_GetNum()!='4');

OLED_Clear();

Interface_Init();//接口初始化(屏幕初始化,显示对应内容)

}

//如果超过最大重量,显示提醒界面,等待按下返回键回到正常界面

6、刷新重量,并时刻根据商品类型刷新价格来显示在oled上

Weight = HX711_Get_Weight(); //称重

Show_Weight(); //显示重量

Price = Commdoity_Price[Commodity_Num]*Weight;

lprice = (uint32_t)Price;

OLED_ShowNum(4,6,lprice,4);

7、根据按下的键值或者蓝牙模块发来的命令,进行对应事件的处理

if(Key_Num == '1') //去皮

{

Key_Num = 0;

JQ8900_Play(2);

HX711_SetTareWeight();

Show_States(1); //显示 状态 去皮

Delay_s(1);

Show_States(0); //显示 状态 称重

}

else if(Key_Num == '2') //切换商品

{

Key_Num = 0;

JQ8900_Play(1);

(Commodity_Num == CNUM-1)?(Commodity_Num = 0):(Commodity_Num++);

Show_Commodity(Commodity_Num);

}

else if((Key_Num >= 'a') && (Key_Num <= 'f')) //蓝牙直接切换到某商品

{

Commodity_Num = Key_Num - 'a';

Show_Commodity(Commodity_Num);

}

else if(Key_Num == '3') //打印账单

{

JQ8900_Play(3);

Key_Num = 0;

Buzzer_ON();

Delay_ms(500);

Buzzer_OFF();

Serial_SendCommodity(Commodity_Num);

Serial_SendString("0.");

Serial_SendNumber(Commdoity_Price[Commodity_Num]*100,2);

Serial_SendString("yuan/gram\n");

Serial_SendString("Bying ");

Serial_SendNumber(Weight,4);

Serial_SendString("gram and costing ");

Serial_SendNumber(lprice,3);

Serial_SendByte('.');

Serial_SendNumber(rprice,2);

Serial_SendString("yuan\n");

}

具体源码

main.c

#include "stm32f10x.h" // Device header

#include "Delay.h"

#include "Key.h"

#include "Buzzer.h"

#include "OLED.h"

#include "Serial.h"

#include "HX711.h"

#include "JQ8900.h"

#define Weight_Max 1000 //最大称重质量为5kg,这里不取到满,留一点缓冲

#define CNUM 6 //商品个数

uint8_t Key_Num, Commodity_Num; //键码

uint32_t Weight; //皮重,重量

float Price; //多少钱一克,价格

float Commdoity_Price[CNUM] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6}; //对应每种商品单价

uint32_t Weight_last;//去皮之前的重量

void Show_States(uint8_t num);

void Interface_Init(void);

void Show_Commodity(uint8_t num);

void Show_Weight(void);

void Serial_SendCommodity(uint8_t num);

int main(void)

{

uint32_t lprice=0, rprice;

Key_Init();//按键初始化

Buzzer_Init();//蜂鸣器初始化

OLED_Init();//oled初始化

Serial_Init();//蓝牙串口初始化

HX711_Init();//HX711初始化

Interface_Init();//接口初始化(屏幕初始化,显示对应内容)

JQ8900_Init();//语音模块初始化

HX711_SetTareWeight();//开机默认去皮一次

JQ8900_SetVolume(25);//设置音量为15

while (1)

{

if(Serial_GetRxFlag())

{

Key_Num = Serial_GetRxData();

}

else

{

Key_Num = Key_GetNum(); //扫描按键

}

if(HX711_Get_Weight()>Weight_Max-Weight_last) //超过设定的最大重量

{

//显示超重界面

OLED_Clear();

OLED_ShowF16x16(1,7,26);//警告

OLED_ShowF16x16(1,9,27);

OLED_ShowF16x16(2,3,28);//超出最大重量

OLED_ShowF16x16(2,5,29);

OLED_ShowF16x16(2,7,30);

OLED_ShowF16x16(2,9,31);

OLED_ShowF16x16(2,11,32);

OLED_ShowF16x16(2,13,33);

OLED_ShowF16x16(4,1,34);//请按下返回键返回

OLED_ShowF16x16(4,3,35);

OLED_ShowF16x16(4,5,36);

OLED_ShowF16x16(4,7,37);

OLED_ShowF16x16(4,9,38);

OLED_ShowF16x16(4,11,39);

OLED_ShowF16x16(4,13,37);

OLED_ShowF16x16(4,15,38);

while(Key_GetNum()!='4');

OLED_Clear();

Interface_Init();//接口初始化(屏幕初始化,显示对应内容)

}

Weight = HX711_Get_Weight(); //称重

Show_Weight(); //显示重量

Price = Commdoity_Price[Commodity_Num]*Weight;

lprice = (uint32_t)Price;

OLED_ShowNum(4,6,lprice,4);

if(Key_Num == '1') //去皮

{

Key_Num = 0;

JQ8900_Play(1);

Weight_last=HX711_Get_Weight();//获取此时的重量

HX711_SetTareWeight();

Show_States(1); //显示 状态 去皮

Delay_s(1);

Show_States(0); //显示 状态 称重

}

else if(Key_Num == '2') //切换商品

{

Key_Num = 0;

JQ8900_Play(2);

(Commodity_Num == CNUM-1)?(Commodity_Num = 0):(Commodity_Num++);

Show_Commodity(Commodity_Num);

}

else if((Key_Num >= 'a') && (Key_Num <= 'f')) //蓝牙直接切换到某商品

{

Commodity_Num = Key_Num - 'a';

Show_Commodity(Commodity_Num);

}

else if(Key_Num == '3') //打印账单

{

JQ8900_Play(3);

Key_Num = 0;

Buzzer_ON();

Delay_ms(500);

Buzzer_OFF();

Serial_SendCommodity(Commodity_Num);

Serial_SendString("0.");

Serial_SendNumber(Commdoity_Price[Commodity_Num]*100,2);

Serial_SendString("yuan/gram\n");

Serial_SendString("Bying ");

Serial_SendNumber(Weight,4);

Serial_SendString("gram and costing ");

Serial_SendNumber(lprice,3);

Serial_SendByte('.');

Serial_SendNumber(rprice,2);

Serial_SendString("yuan\n");

}

Delay_ms(50);

}

}

void Interface_Init(void)

{

OLED_ShowF16x16(1,1,13); //状

OLED_ShowF16x16(1,3,14); //态

OLED_ShowChar(1,5,':');

Show_States(0);

OLED_ShowF16x16(2,1,17); //重

OLED_ShowF16x16(2,3,18); //量

OLED_ShowChar(2,5,':');

OLED_ShowF16x16(2,10,19); //克

Show_Commodity(Commodity_Num);

OLED_ShowChar(3,5,':');

OLED_ShowF16x16(3,10,0); //元

OLED_ShowChar(3,12,'/');

OLED_ShowF16x16(3,13,19); //克

OLED_ShowF16x16(4,1,22); //价

OLED_ShowF16x16(4,3,23); //格

OLED_ShowChar(4,5,':');

OLED_ShowF16x16(4,10,0); //元

}

void Show_States(uint8_t num)

{

switch(num){

case 0:

OLED_ShowF16x16(1,7,20); //称

OLED_ShowF16x16(1,9,17); //重

break;

case 1:

OLED_ShowF16x16(1,7,15); //去

OLED_ShowF16x16(1,9,16); //皮

break;

case 2:

OLED_ShowF16x16(1,7,21); //计

OLED_ShowF16x16(1,9,22); //价

break;

}

}

void Show_Commodity(uint8_t num)

{

uint8_t i;

switch(num){

case 0:

OLED_ShowF16x16(3,1,1); //苹

OLED_ShowF16x16(3,3,2); //果

i = (uint8_t)Commdoity_Price[num];

OLED_ShowNum(3,6,i,1);

OLED_ShowChar(3,7,'.');

OLED_ShowNum(3,8,(uint8_t)((Commdoity_Price[num]-i)*100),2);

break;

case 1:

OLED_ShowF16x16(3,1,3); //香

OLED_ShowF16x16(3,3,4); //蕉

i = (uint8_t)Commdoity_Price[num];

OLED_ShowNum(3,6,i,1);

OLED_ShowChar(3,7,'.');

OLED_ShowNum(3,8,(uint8_t)((Commdoity_Price[num]-i)*100),2);

break;

case 2:

OLED_ShowF16x16(3,1,5); //橘

OLED_ShowF16x16(3,3,6); //子

i = (uint8_t)Commdoity_Price[num];

OLED_ShowNum(3,6,i,1);

OLED_ShowChar(3,7,'.');

OLED_ShowNum(3,8,(uint8_t)((Commdoity_Price[num]-i)*100),2);

break;

case 3:

OLED_ShowF16x16(3,1,7); //葡

OLED_ShowF16x16(3,3,8); //萄

i = (uint8_t)Commdoity_Price[num];

OLED_ShowNum(3,6,i,1);

OLED_ShowChar(3,7,'.');

OLED_ShowNum(3,8,(uint8_t)((Commdoity_Price[num]-i)*100),2);

break;

case 4:

OLED_ShowF16x16(3,1,9); //菠

OLED_ShowF16x16(3,3,10); //萝

i = (uint8_t)Commdoity_Price[num];

OLED_ShowNum(3,6,i,1);

OLED_ShowChar(3,7,'.');

OLED_ShowNum(3,8,(uint8_t)((Commdoity_Price[num]-i)*100),2);

break;

case 5:

OLED_ShowF16x16(3,1,11); //西

OLED_ShowF16x16(3,3,12); //瓜

i = (uint8_t)Commdoity_Price[num];

OLED_ShowNum(3,6,i,1);

OLED_ShowChar(3,7,'.');

OLED_ShowNum(3,8,(uint8_t)((Commdoity_Price[num]-i)*100),2);

break;

}

}

void Show_Weight(void)

{

OLED_ShowNum(2,6,Weight,4);

}

void Serial_SendCommodity(uint8_t num)

{

switch(num){

case 0:

Serial_SendString("apple ");

break;

case 1:

Serial_SendString("banana ");

break;

case 2:

Serial_SendString("orange ");

break;

case 3:

Serial_SendString("grape ");

break;

case 4:

Serial_SendString("pineapple ");

break;

case 5:

Serial_SendString("watermelon ");

break;

}

}

总结

其实你只要学过一点stm32,以上资料完全够你手动复刻,去购买我硬件清单的对应模块,然后找到商家要驱动代码,移植到你的工程,然后调用相应的函数到我给你的main.c里面,这个项目就可以轻而易举的复刻出来了,希望我这篇文章可以帮助到你,如果需要完整的工程,可以私信我。

猜你喜欢 💖

3匹(约34-50㎡)空调报价
beat365体育下载

3匹(约34-50㎡)空调报价

📅 07-17 👁️ 1545
眼药水开封后,能用多久?
365bet网上足球比赛

眼药水开封后,能用多久?

📅 08-16 👁️ 2027
系统的基本特征有哪些?,系统的基本特征分析
365bet网上足球比赛

系统的基本特征有哪些?,系统的基本特征分析

📅 10-10 👁️ 8555