第九届蓝桥杯嵌入式国赛(STM32G4与HAL库实现)
Posted ORI2333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九届蓝桥杯嵌入式国赛(STM32G4与HAL库实现)相关的知识,希望对你有一定的参考价值。
前言
本程序基于STM32G431RB开发,使用工具为STM32CubeMX + Keil MDK 5 + HAL库。
题目要求
基本要求
完成“电子秤”功能。
硬件框图
功能描述
基本功能
- 通过资源扩展板电位器RP5模拟称重传感器输出信号,STM32采集此电压信号,并计算货物重量。电子秤称重范围0-10kg。
- 通过按键选择不同货物、计费及货物单价参数设置等功能。
- 通过LCD显示所称货物重量和货物价格等信息。
- 设备基本工作流程:选择货物(按键操作)——称重——计费(按键操作)——更新显示及串口输出。
按键功能
显示功能
存储功能
称重功能
LED指示灯功能
- 称重计费状态下,LD1以0.8秒为间隔亮灭
- 单价设置状态下,LD1以0.4秒为间隔亮灭
串口功能
- 使用竞赛板上的USART2(USB转串口)完成串口输出功能。
- 串口通讯波特率:9600bps
资源扩展板跳线配置参考
代码实现
为了方便提交,或者说不容易遗漏,本工程将绝大部分实现代码写在main.c文件中.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention : 此为第九届蓝桥杯嵌入式设计大赛程序设计题
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
#include "i2c - hal.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define BTN_BUFF_LEN 20
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
char TextBuff[30];
uint32_t adc_value = 0;
uint32_t key_value = 0;
u16 btn_buff[BTN_BUFF_LEN];
double Weight_Value = 0;
double Goodsprice1 = 0;
double Goodsprice2 = 0;
double Goodsprice3 = 0;
uint8_t SettingTimes = 0;
uint8_t Key_1_Flag = 0;
uint8_t Key_4_Flag = 0;
uint8_t Key_567_Flag = 1;
uint8_t Key_8_Flag = 0;
uint8_t Set_Flag = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC2_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
void LCD_cls(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/******************获取ADC值**********************/
uint16_t Get_ADC(uint32_t ch)
{
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ch;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
HAL_ADC_Start(&hadc2);
HAL_ADC_PollForConversion(&hadc2,10);
return (uint16_t)HAL_ADC_GetValue(&hadc2);
}
/*************************************************/
/****************均值滤波**************************/
u16 Get_Adc_Average(u32 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_ADC(ch);
HAL_Delay(5);
}
return temp_val/times;
}
/***************************************************/
/*********************ADC按键***********************/
u8 key_read()
{
u16 ADC_temp = 4500;
ADC_temp = Get_Adc_Average(ADC_CHANNEL_13,1);
if(ADC_temp<100)
{
return 1;
}
else if(ADC_temp<400)
{
return 2;
}
else if(ADC_temp<700)
{
return 3;
}
else if(ADC_temp<1100)
{
return 4;
}
else if(ADC_temp<1500)
{
return 5;
}
else if(ADC_temp<2000)
{
return 6;
}
else if(ADC_temp<2500)
{
return 7;
}
else if(ADC_temp<3500)
{
return 8;
}
else
return 0;
}
/***************************************************/
/*******************按键扫描************************/
void Key_Scan()
{
static u8 key_up=1; //按键松开标志
if(key_up && key_value != 0){
key_up = 0;
if(key_value == 1){
Key_1_Flag++;
if(Key_1_Flag > 2) Key_1_Flag = 0;
}
if(key_value == 2){
if(Key_4_Flag == 1){
Goodsprice1 += 0.01;
}
if(Key_4_Flag == 2){
Goodsprice2 += 0.01;
}
if(Key_4_Flag == 3){
Goodsprice3 += 0.01;
}
if(Goodsprice1 > 10) Goodsprice1 = 10;
if(Goodsprice2 > 10) Goodsprice2 = 10;
if(Goodsprice3 > 10) Goodsprice3 = 10;
Set_Flag = 1;
}
if(key_value == 3){
if(Key_4_Flag == 1){
Goodsprice1 -= 0.01;
}
if(Key_4_Flag == 2){
Goodsprice2 -= 0.01;
}
if(Key_4_Flag == 3){
Goodsprice3 -= 0.01;
}
if(Goodsprice1 < 0) Goodsprice1 = 0;
if(Goodsprice2 < 0) Goodsprice2 = 0;
if(Goodsprice3 < 0) Goodsprice3 = 0;
Set_Flag = 1;
}
if(key_value == 4){
Key_4_Flag++;
if(Key_4_Flag > 3){
Key_4_Flag = 0;
}
}
if(key_value == 5){
Key_567_Flag = 1;
}
if(key_value == 6){
Key_567_Flag = 2;
}
if(key_value == 7){
Key_567_Flag = 3;
}
if(key_value == 8){
Key_8_Flag = 1;
}
}
else if(key_value == 0){
key_up = 1;
Key_8_Flag = 0;
}
}
/*******************************************************/
/************************设置界面************************/
void SettingDisplay()
{
LCD_SetBackColor(Blue);
LCD_DisplayStringLine(Line0,(uint8_t *)" parameter settings ");
LCD_DisplayStringLine(Line1,(uint8_t *)" ");
LCD_DisplayStringLine(Line5,(uint8_t *)" ");
LCD_DisplayStringLine(Line6,(uint8_t *)" ");
LCD_DisplayStringLine(Line7,(uint8_t *)" ");
LCD_DisplayStringLine(Line8,(uint8_t *)" ");
sprintf(TextBuff,"PriceGoods1:%.2fY/kg", Goodsprice1);
if(Key_4_Flag == 1){
LCD_SetBackColor(Green);
LCD_DisplayStringLine(Line2,(uint8_t *)TextBuff);
LCD_SetBackColor(Blue);
}
else{
LCD_DisplayStringLine(Line2,(uint8_t *)TextBuff);
}
sprintf(TextBuff,"PriceGoods2:%.2fY/kg", Goodsprice2);
if(Key_4_Flag == 2){
LCD_SetBackColor(Green);
LCD_DisplayStringLine(Line3,(uint8_t *)TextBuff);
LCD_SetBackColor(Blue);
}
else{
LCD_DisplayStringLine(Line3,(uint8_t *)TextBuff);
}
sprintf(TextBuff,"PriceGoods3:%.2fY/kg", Goodsprice3);
if(Key_4_Flag == 3){
LCD_SetBackColor(Green);
LCD_DisplayStringLine(Line4,(uint8_t *)TextBuff);
LCD_SetBackColor(Blue);
}
else{
LCD_DisplayStringLine(Line4,(uint8_t *)TextBuff);
}
sprintf(TextBuff," Setting times:%d", SettingTimes);
LCD_DisplayStringLine(Line9,(uint8_t *)TextBuff);
}
/***************************************************************/
/****************************称重界面***************************/
void GoodsDisplay(uint8_t id, double Goodsprice)
{
Weight_Value =Get_Adc_Average(ADC_CHANNEL_17,20) * 10.0 / 4096;
LCD_DisplayStringLine(Line0,(uint8_t *)" Weighing charges ");
sprintf(TextBuff," Goods ID:%d ", id);
LCD_DisplayStringLine(Line2,(uint8_t *)TextBuff);
sprintf(TextBuff," Goods Price:%.2fY/Kg", Goodsprice);
LCD_DisplayStringLine(Line3,(uint8_t *)TextBuff);
sprintf(TextBuff," Goods Weight:%.2fKg", Weight_Value);
LCD_DisplayStringLine(Line4,(uint8_t *)TextBuff);
double Sum_Price = Goodsprice * Weight_Value;
sprintf(TextBuff," Sum Price:%.2f Y", Sum_Price);
LCD_DisplayStringLine(Line5,(uint8_t *)TextBuff);
LCD_DisplayStringLine(Line1,(uint8_t *)" ");
LCD_DisplayStringLine(Line9,(uint8_t *)" ");
LCD_DisplayStringLine(Line6,(uint8_t *)" ");
LCD_DisplayStringLine(Line7,(uint8_t *)" ");
LCD_DisplayStringLine(Line8,(uint8_t *)" ");
if(Key_8_Flag == 1){
printf("U.W.%d:%.2f\\n",id,Goodsprice);
printf("G.W:%.2f\\n", Weight_Value);
printf("Total:%.2f\\n",Sum_Price);
printf("\\n");
}
}
/****************************************************************/
//IIC读函数
uint8_t M24C02_Read(unsigned char address)
{
unsigned char val;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
val = I2CReceiveByte();
I2CWaitAck();
I2CStop();
return val;
}
//IIC写函数
void M2402_write(unsigned char address, uint16_t info)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CSendByte(info);
I2CWaitAck();
I2CStop();
}
void Seting_Save()
{
if(Set_Flag == 1){
SettingTimes++;
Set_Flag = 0;
}
sprintf(TextBuff," Setting times:%d", SettingTimes);
LCD_DisplayStringLine(Line9,(uint8_t *)TextBuff);
uint16_t temp_z = Goodsprice1;
uint16_t temp_x = (Goodsprice1-temp_z)*100;
M2402_write(0x00,temp_z);
HAL_Delay(5);
M2402_write(0x01,temp_x);
HAL_Delay(5);
temp_z = Goodsprice2;
temp_x = (Goodsprice2-temp_z)*100;
M2402_write(0x02,temp_z);
HAL_Delay(5);
M2402_write(0x03,temp_x);
HAL_Delay(5);
temp_z = Goodsprice3;
temp_x = (Goodsprice3-temp_z)*100;
M2402_write(0x04,temp_z);
HAL_Delay(5);
M2402_write(0x05,temp_x);
HAL_Delay(5);
M2402_write(0x06,SettingTimes);
HAL_Delay(5);
}
void Printf_Save()
{
static u8 Printf_Flag=1; //按键松开标志
if(Printf_Flag && Key_1_Flag == 2)
{
Printf_Flag=0;
if(Key_1_Flag == 2){
printf("U.W.1:%.2f\\n",Goodsprice1);
printf("U.W.2:%.2f\\n",Goodsprice2);
printf("U.W.3:%.2f\\n",Goodsprice3);
}
}else if(Key_1_Flag != 2)Printf_Flag = 1;
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
以上是关于第九届蓝桥杯嵌入式国赛(STM32G4与HAL库实现)的主要内容,如果未能解决你的问题,请参考以下文章
STM32G4备战蓝桥杯嵌入式---实战---第九届嵌入式国赛(电子秤)
STM32G4备战蓝桥杯嵌入式---实战---第九届嵌入式国赛(电子秤)