The second real question of the 13th Blue Bridge Cup Embedded Provincial Competition (giant simplified code based on HAL library + super detailed explanation)

foreword

Related instructions:

Development board: CT117E-M4(STM32G431RBT6)
Development environment: CubeMX+Keil5
Involved topics: the second real question of the 13th Blue Bridge Cup Embedded Provincial Competition
Winners of the first round:

CubeMX configuration, main function code and description:

1. CubeMX configuration (the second real question of the 13th provincial competition)

1. Enable external high-speed clock:

2. Configure the clock tree:

3.GPIO:

4.TIM2 (channel 2 PA1 output pulse signal):

5.UART:

6.NVIC priority configuration

2. Code-related definitions and declarations

1. Variable declaration

unsigned char x[3]={0,10,10};//Define the commodity X array and initialize it as the purchase quantity, 10 times the unit price, and the inventory quantity respectively.
unsigned char y[3]={0,10,10};//Define the product Y array and initialize it as the purchase quantity, 10 times the unit price, and the inventory quantity respectively.
unsigned char jiemian;//Display interface 0 is the commodity purchase interface 1 is the commodity price interface 2 is the inventory information interface
unsigned char uled;//LED display parameters
unsigned char tx[21],rx,rx_buf[7],dex;//Serial port related variables
unsigned char pwm;//The initial value is 0, and the default output duty cycle is 5% pulse. 1 is the output pulse with a duty cycle of 30%.
unsigned char e2prom[7];//Temporarily store the data read from the E2PROM in this array
__IO uint32_t PWM_Tick;//Timing pulse output time
__IO uint32_t LED_Tick;//Chronograph LED display time

2. Function declaration

void Key_Proc();
void Lcd_Proc();
void Uart_Proc();
void Led_Proc();

Three, the main function

1.main function

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_TIM2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  LCD_Init();
  LCD_Clear(Black);
  LCD_SetBackColor(Black);
  LCD_SetTextColor(White);
  I2CInit();
	
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
  HAL_UART_Receive_IT(&huart1,&rx,1);
	
  IIC_Read(e2prom,0,7);//Read out the commodity information stored in the E2PROM and the flag bit of whether it is running for the first time
  HAL_Delay(100);
  if((e2prom[4]==0x77)&&(e2prom[5]==0x7A)&&(e2prom[6]==0x64))//STM32 is not the first run
  {
	 x[2]=e2prom[0];//commodity information data exchange
 	 y[2]=e2prom[1];
	 x[1]=e2prom[2];
	 y[1]=e2prom[3];
  }
  else//STM32 first run
  {
	 e2prom[4]=0x77;e2prom[5]=0x7A;e2prom[6]=0x64;//The blogger's customized information indicates that the STM is running for the first time
	 e2prom[0]=x[2];e2prom[1]=y[2];e2prom[2]=x[1];e2prom[3]=y[1];//Write the initial commodity inventory and price to E2PROM according to the specified location
	 IIC_Write(e2prom,0,7);
  }
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	Key_Proc();
    Lcd_Proc();
    Uart_Proc();
    Led_Proc();
  }
  /* USER CODE END 3 */
}

2. Key scan, E2PROM storage, print purchase information

void Key_Proc()
{
	static __IO uint32_t Key_Tick;//deceleration variable
	static unsigned char key_old;
	unsigned char key_down,key_value;
	
	if(uwTick-Key_Tick<50)
		return;
	Key_Tick=uwTick;
	
	key_value=Key_Scan();
	key_down=key_value&(key_value^key_old);
	key_old=key_value;
	
	switch(key_down)
	{
		case 1:
			if(++jiemian>2)//interface switching
				jiemian=0;
			LCD_Clear(Black);//Clear screen when switching screens
		break;
		
		case 2://Commodity x
			if(jiemian==0)//product purchase interface
			{
				if(++x[0]>x[2])
					x[0]=0;
			}
			else if(jiemian==1)//commodity price interface
			{
				if(++x[1]>20)
					x[1]=10;
				IIC_Write(&x[1],2,1);//Write E2PROM commodity x unit price
			}
			else//product inventory interface
			{
				x[2]++;
				IIC_Write(&x[2],0,1);//Write E2PROM item x stock quantity
			}
		break;
		
		case 3://product y
			if(jiemian==0)//product purchase interface
			{
				if(++y[0]>y[2])
					y[0]=0;
			}
			else if(jiemian==1)//commodity price interface
			{
				if(++y[1]>20)
					y[1]=10;
				IIC_Write(&y[1],3,1);//Write E2PROM commodity y unit price
			}
			else//product inventory interface
			{
				y[2]++;
				IIC_Write(&y[2],1,1);//Write E2PROM commodity y inventory quantity
			}
		break;
		
		case 4://product confirmation button
			if(jiemian==0)//product purchase interface
			{
				x[2]=x[2]-x[0];//Commodity x inventory reduction
				y[2]=y[2]-y[0];//Commodity y inventory decreases
				IIC_Write(&x[2],0,1);//Write E2PROM item x stock quantity
				sprintf((char*)tx,"X:%d,Y:%d,Z:%0.1f\n",x[0],y[0],0.1*x[0]*x[1]+0.1*y[0]*y[1]);//Print total price, send purchase information
				HAL_UART_Transmit(&huart1,tx,strlen(tx),50);
				x[0]=y[0]=0;//The purchase quantity is reset to 0
				uled|=0x01;//Indicator LED1 lights up
				LED_Tick=uwTick;//LED display timer starts
				pwm=1;//Output 2kHz duty cycle 30% pulse
				PWM_Tick=uwTick;//Output pulse timing starts
				IIC_Write(&y[2],1,1);//Write E2PROM commodity y inventory quantity
			}
		break;
	}
}

3. Screen display, PWM output

void Lcd_Proc()
{
	static __IO uint32_t Lcd_Tick;//deceleration variable
	
	unsigned char lcd_string[21];
	
	if(uwTick-Lcd_Tick<100)
		return;
	Lcd_Tick=uwTick;
	
	if(pwm==0)//Output 2kHz duty cycle 5% pulse
		__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,25);
	else//Output 2kHz duty cycle 30% pulse
		__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,150);
	
	if(uwTick-PWM_Tick>5000)//Pulse output time reaches 5 seconds
		pwm=0;//Converts to a pulse with a duty cycle of 5% after 5 seconds of output
	
	if(jiemian==0)//When purchasing a product
	{
		sprintf((char*)lcd_string,"        SHOP");
		LCD_DisplayStringLine(Line1,lcd_string);
		sprintf((char*)lcd_string,"     X:%d",x[0]);//Displays the number of purchases of item X
		LCD_DisplayStringLine(Line3,lcd_string);
		sprintf((char*)lcd_string,"     Y:%d",y[0]);//Display the purchase quantity of item Y
		LCD_DisplayStringLine(Line4,lcd_string);
	}
	else if(jiemian==1)//commodity price interface
	{
		sprintf((char*)lcd_string,"        PRICE");
		LCD_DisplayStringLine(Line1,lcd_string);
		sprintf((char*)lcd_string,"     X:%3.1f",0.1*x[1]);
		LCD_DisplayStringLine(Line3,lcd_string);
		sprintf((char*)lcd_string,"     Y:%3.1f",0.1*y[1]);
		LCD_DisplayStringLine(Line4,lcd_string);
	}
	else
	{
		sprintf((char*)lcd_string,"        REP");
		LCD_DisplayStringLine(Line1,lcd_string);
		sprintf((char*)lcd_string,"     X:%d   ",x[2]);
		LCD_DisplayStringLine(Line3,lcd_string);
		sprintf((char*)lcd_string,"     Y:%d   ",y[2]);
		LCD_DisplayStringLine(Line4,lcd_string);
	}
}

4. Determine whether the data received by the serial port is legal

unsigned char isRxCplt()//The return value is 1 when the received data is valid
{
	unsigned char i;
	
	if(dex==0)//No data received
		return 0;
	if(dex!=1)//Invalid when the received data is not 1 ASCII
		return 2;
	if(rx_buf[0]==0x3F)//When the received data is '?'
		return 1;
	else//Illegal when the received data is not '?'
		return 2;
}

5. Check the current commodity price

void Uart_Proc()
{
	static __IO uint32_t Uart_Tick;//deceleration variable
	
	if(uwTick-Uart_Tick<100)
		return;
	Uart_Tick=uwTick;
	
	if(isRxCplt()==1)//Receive data legally
	{
		sprintf((char*)tx,"X:%3.1f,Y:%3.1f\n",0.1*x[1],0.1*y[1]);
			HAL_UART_Transmit(&huart1,tx,strlen(tx),50);//Send OK to the upper computer to indicate that the modification is successful
	}
	else if(isRxCplt()==2)//Receiving data is illegal
	{
		sprintf((char*)tx,"Password format error\n");
		HAL_UART_Transmit(&huart1,tx,strlen(tx),50);//Send Error to the upper computer to indicate that the modification fails
	}
	
	dex=0;//Clear serial port receive array index
}

6. Serial port interrupt

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	rx_buf[dex++]=rx;//One by one into the cache array index + 1
	
	HAL_UART_Receive_IT(&huart1,&rx,1);//Re-enable receive interrupts
}

7.LED indication function

void Led_Proc()
{
	static __IO uint32_t Led_Tick;//deceleration variable
	
	if(uwTick-Led_Tick<100)//Blinks at 0.1 second intervals
		return;
	Led_Tick=uwTick;
	
	if(uwTick-LED_Tick>=5000)//LED1 lights up for 5 seconds
		uled&=~0x01;//Indicator LED1 is off
	
	if((x[2]==0)&&(y[2])==0)//Both item x and item y have 0 inventory
		uled^=0x02;//LED2 blinks at 0.1 second intervals
	else
		uled&=~0x02;//Indicator LED2 is off
	
	Led_Disp(uled);
}

Fourth, programming experience, pre-exam prediction

   The blogger participated in the first session. After the second session, the school did not release nucleic acid in a unified manner. After receiving the real question for the first time, he opened the computer STM32CubeMx software configuration, the second session and the first session. It's very similar, everything changes, and bloggers quickly write the code.
   The serial port in the second field is very simple. It only receives a character and sends a string. It is very conventional. The difficulty lies in the continuous reading and writing of E2PROM when changing prices and inventory continuously, but putting it into the key scan can solve this problem very well. , At the same time, when the microcontroller is powered on for the first time, it needs to meet the price of 1.0, and the inventory is 10. After re-powering it, it should be saved after power-off, so you need to judge whether your microcontroller is powered on for the first time. Other modules are very conventional, not difficult, I believe you can do it with ease.
   The night before the competition, a junior asked me about the serial port related knowledge, and then gave him a prediction of the modules that would be investigated. I applied for my prediction today, and I was very happy.
   Here, I wish you all the best in advance to win the provincial one and attack the national competition together!



Attachment 1: The first real question of the 13th Blue Bridge Cup Embedded Provincial Competition (HAL library-based giant simplified code + super detailed explanation)

https://blog.csdn.net/weixin_45949982/article/details/124065431

Attachment 2: The 13th Blue Bridge Cup Embedded Second Program Design, Objective Question PDF

Link: https://pan.baidu.com/s/1eLUZVDym40VOuE_TXhU7DQ?pwd=94sd
Extraction code: 94sd

Tags: Embedded system Single-Chip Microcomputer stm32

Posted by jibosh on Sun, 15 May 2022 06:21:47 +0300