第九届蓝桥杯嵌入式国赛(STM32G4与HAL库实现)

Posted ORI2333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九届蓝桥杯嵌入式国赛(STM32G4与HAL库实现)相关的知识,希望对你有一定的参考价值。

前言

本程序基于STM32G431RB开发,使用工具为STM32CubeMX + Keil MDK 5 + HAL库。

题目要求

基本要求

完成“电子秤”功能。

硬件框图

功能描述

基本功能

  1. 通过资源扩展板电位器RP5模拟称重传感器输出信号,STM32采集此电压信号,并计算货物重量。电子秤称重范围0-10kg。
  2. 通过按键选择不同货物、计费及货物单价参数设置等功能。
  3. 通过LCD显示所称货物重量和货物价格等信息。
  4. 设备基本工作流程:选择货物(按键操作)——称重——计费(按键操作)——更新显示及串口输出。

按键功能



显示功能


存储功能

称重功能

LED指示灯功能

  1. 称重计费状态下,LD1以0.8秒为间隔亮灭
  2. 单价设置状态下,LD1以0.4秒为间隔亮灭

串口功能

  1. 使用竞赛板上的USART2(USB转串口)完成串口输出功能。
  2. 串口通讯波特率:9600bps

资源扩展板跳线配置参考

代码实现

为了方便提交,或者说不容易遗漏,本工程将绝大部分实现代码写在main.c文件中.

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention			: 此为第九届蓝桥杯嵌入式设计大赛程序设计题
  *
  * <h2><center>&copy; 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);
	LCD_SetTextColor(White);
	
	第九届蓝桥杯嵌入式国赛(STM32G4与HAL库实现)

STM32G4备战蓝桥杯嵌入式---实战---第九届嵌入式国赛(电子秤)

STM32G4备战蓝桥杯嵌入式---实战---第九届嵌入式国赛(电子秤)

STM32G4备战蓝桥杯嵌入式---实战---第九届嵌入式国赛(电子秤)

第十届蓝桥杯嵌入式国赛(STM32G4及HAL库)

第十届蓝桥杯嵌入式国赛(STM32G4及HAL库)