#ifndef code_h
#define code_h
#include "stm32g4xx.h"
#include "stdio.h"
#include "string.h"
#include "stdint.h"
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "lcd.h"
void lcd_proc(void);
void key_proc(void);
void led_proc(u8 led_x,u8 led_mode);
double adc_proc(ADC_HandleTypeDef *hadc);
void usart_proc(void);
#endif
#include "code.h"
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
LCD_Init();
LCD_SetTextColor(White);
LCD_SetBackColor(Black);
LCD_Clear(Black);
//ADC采样校准
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);
HAL_TIM_Base_Start(&htim1);
HAL_TIM_Base_Start(&htim2);
HAL_TIM_Base_Start(&htim3);
extern u8 my_pData;
HAL_UART_Receive_IT(&huart1, &my_pData, 1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
lcd_proc();
key_proc();
usart_proc();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
#include "code.h"
/*---------------------------------lcd-----------------------------------------*/
u8 ui;
char lcd_buf[30];
double STAN[4] = {2.2, 1.2, 3.0, 1.4}; // R37_MAX,R37_MIN,R38_MAX,R37_MIN
double PASS[2];
void lcd_proc(void)
{
if (ui == 0)
{
LCD_DisplayStringLine(Line1, " GOODS");
sprintf(lcd_buf, " R37:%.2fV ", adc_proc(&hadc2));
LCD_DisplayStringLine(Line3, (u8 *)lcd_buf);
sprintf(lcd_buf, " R38:%.2fV ", adc_proc(&hadc1));
LCD_DisplayStringLine(Line4, (u8 *)lcd_buf);
}
else if (ui == 1)
{
LCD_DisplayStringLine(Line1, " STANDARD");
sprintf(lcd_buf, " SR37:%.1f-%.1f ", STAN[1], STAN[0]);
LCD_DisplayStringLine(Line3, (u8 *)lcd_buf);
sprintf(lcd_buf, " SR38:%.1f-%.1f ", STAN[3], STAN[2]);
LCD_DisplayStringLine(Line4, (u8 *)lcd_buf);
}
else
{
LCD_DisplayStringLine(Line1, " PASS");
sprintf(lcd_buf, " PR37:%.1f%% ", PASS[0] * 100);
LCD_DisplayStringLine(Line3, (u8 *)lcd_buf);
sprintf(lcd_buf, " PR38:%.1f%% ", PASS[1] * 100);
LCD_DisplayStringLine(Line4, (u8 *)lcd_buf);
}
led_proc(3, !ui);
led_proc(4, !(ui - 1));
led_proc(5, !(ui - 2));
}
/*---------------------------------key-----------------------------------------*/
u8 key_val[4];
u8 key_old[4];
u8 key;
u8 STAN_X; // 用来选择参数
double PASS_CNT[2]; // R37,R38合格率检测次数
double PASS_OK_CNT[2]; // R37,R38合格次数
void key_proc(void)
{
for (u8 i = 0; i < 4; i++)
{
key_val[i] = HAL_GPIO_ReadPin(i < 3 ? GPIOB : GPIOA, GPIO_PIN_0 << i % 3);
if (key_val[i] == 0 && key_old[i] == 1)
{
key = i + 1;
}
key_old[i] = key_val[i];
}
switch (key)
{
case 1:
ui++;
ui %= 3;
LCD_Clear(Black);
STAN_X = 0; // 题目没说,但一般都会有指定进入设置界面的默认调整参数(R37的上限)
break;
case 2:
if (ui == 0)
{
if (adc_proc(&hadc2) <= STAN[0] && adc_proc(&hadc2) >= STAN[1]) // R37合格
{
led_proc(1, 1);
TIM2->CNT = 0;
PASS[0] = ++PASS_OK_CNT[0] / ++PASS_CNT[0];
}
else
PASS[0] = PASS_OK_CNT[0] / ++PASS_CNT[0];
}
else if (ui == 1) // 选择参数
{
STAN_X++;
STAN_X %= 4;
}
break;
case 3:
if (ui == 0)
{
if (adc_proc(&hadc1) <= STAN[2] && adc_proc(&hadc1) >= STAN[3]) // R38合格
{
led_proc(2, 1);
TIM3->CNT = 0;
PASS[1] = ++PASS_OK_CNT[1] / ++PASS_CNT[1];
}
else
PASS[1] = PASS_OK_CNT[1] / ++PASS_CNT[1];
}
else if (ui == 1)
{
STAN[STAN_X] += 0.2;
// 注意浮点型在存储时存在精度误差,不要直接与3.0进行比较,会出错
if (STAN_X % 2 == 0 && STAN[STAN_X] > 3.1) // R37或R38上限溢出(STAN_X % 2 ==0 -> STAN_X == 0 / 2 )
STAN[STAN_X] = 2.2;
else if (STAN_X % 2 == 1 && STAN[STAN_X] > 2.1) // R37或R38下限溢出(STAN_X % 2 ==1 -> STAN_X == 1 / 3 )
STAN[STAN_X] = 1.2;
PASS[STAN_X / 2] = PASS_CNT[STAN_X / 2] = PASS_OK_CNT[STAN_X / 2] = 0; // 标准变化置零合格率
}
break;
case 4:
if (ui == 1)
{
STAN[STAN_X] -= 0.2;
if (STAN_X % 2 == 0 && STAN[STAN_X] < 2.1) // R37或R38上限溢出
STAN[STAN_X] = 3.0;
else if (STAN_X % 2 == 1 && STAN[STAN_X] < 1.1) // R37或R38下限溢出
STAN[STAN_X] = 2.0;
PASS[STAN_X / 2] = PASS_CNT[STAN_X / 2] = PASS_OK_CNT[STAN_X / 2] = 0; // 标准变化置零合格率
}
else if (ui == 2)
{
PASS[0] = PASS_CNT[0] = 0;
PASS[1] = PASS_CNT[1] = 0;
}
break;
}
key = 0;
if (TIM2->CNT > 10000)
led_proc(1, 0);
if (TIM3->CNT > 10000)
led_proc(2, 0);
}
/*---------------------------------led-----------------------------------------*/
void led_proc(u8 led_x, u8 led_mode)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
if (led_mode)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8 << (led_x - 1), GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8 << (led_x - 1), GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
/*---------------------------------adc-----------------------------------------*/
double adc_proc(ADC_HandleTypeDef *hadc)
{
double adc_val;
HAL_ADC_Start(hadc);
adc_val = 3.3 * HAL_ADC_GetValue(hadc) / 4096;
return adc_val;
}
/*---------------------------------usart-----------------------------------------*/
u8 my_pData;
char usart_buf[10];
u8 usart_cnt;
u8 rx_flag;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
usart_buf[usart_cnt] = my_pData;
usart_cnt++;
rx_flag = 1;
TIM1->CNT = 0;
HAL_UART_Receive_IT(&huart1, &my_pData, 1);
}
void usart_proc(void)
{
if (!rx_flag)
return;
if (TIM1->CNT < 20)
return;
if (strstr(usart_buf, "R37") != NULL)
{
sprintf(usart_buf, "R37:%.0f,%.0f,%0.1f%%", PASS_CNT[0], PASS_OK_CNT[0], PASS[0] * 100);
HAL_UART_Transmit(&huart1, (u8 *)usart_buf, strlen(usart_buf), 50);
}
else if (strstr(usart_buf, "R38") != NULL)
{
sprintf(usart_buf, "R38:%.0f,%.0f,%.1f%%", PASS_CNT[1], PASS_OK_CNT[1], PASS[1] * 100);
HAL_UART_Transmit(&huart1, (u8 *)usart_buf, strlen(usart_buf), 50);
}
memset(usart_buf, NULL, sizeof(usart_buf));
usart_cnt = 0;
rx_flag = 0;
}
非常答辩,尤其按键部分,对参数的设置非常不合理,明天就比赛,终于要结束了,前前后后准备快3个月,上学期就开始,然后寒假因为太忙没有练习,这篇文章应该是最后一篇了,可能吧,如果比赛结束后还有心情的话会考虑优化优化一下代码,最后就祝大家一切顺利,国赛见!