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