蓝桥杯嵌入式第十五届省赛模拟赛第三场——程序设计部分

源码:

链接:https://pan.baidu.com/s/1O7LO84ecTPMKxE4SRUjJPg?pwd=d1qg 
提取码:d1qg

由于木有会员,只能一个一个文件上传,就上传了关键的。

成绩已经可查,本Blog代码可拿程序题满分:

原题:

代码:

变量定义:

extern struct key keys[4];//四个按键
extern char rxdata[30];//串口数据
extern uint p;
extern uint8_t data;


int view=0;//界面切换
double tR37=1.25,tR38=2.36;//ADC的值
double SR37_l=1.2,SR37_r=2.2;//R37的上下限
double SR38_l=1.4,SR38_r=3.0;//R38的上下限
int PR37=0,PR38=0;//合格数
int sumR37=0,sumR38=0;//总数
int swic=0;//选择配置
int R37_flag=0,R38_flag=0;//是否通过
double res37,res38;//合格率

__IO uint32_t LD1Tick=0;//计时1s  下同
__IO uint32_t LD2Tick=0;

main: 

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_TIM3_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  /* USER CODE BEGIN 2 */
    //LCD的初始化
	LCD_Init();
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	LCD_Clear(Black);
	
    //按键定时器开启
	HAL_TIM_Base_Start_IT(&htim3);
	
    //LED初始化
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
	
    //串口初始化
	HAL_UART_Receive_IT(&huart1,&data,1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		led_proc();
		lcd_proc();
		key_proc();
		
        //判断接收数据是否结束
		while(p!=0)
		{
			int t=p;
			HAL_Delay(1);
			if(t==p) usart_rx();
		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

lcd:

void lcd_proc(void)
{
	char text[20];
	
	if(sumR37==0) res37=0.0;
	else res37=(PR37*1.0/sumR37);
	if(sumR38==0) res38=0.0;
	else res38=(PR38*1.0/sumR38);

	//获取ADC
	tR38=getADC(&hadc1);
	tR37=getADC(&hadc2);
	
	if(view==0)//产品参数界面
	{
		sprintf(text,"       GOODS   ");
		LCD_DisplayStringLine(Line1,(u8*)text);
		sprintf(text,"     R37:%.2lfV   ",tR37);
		LCD_DisplayStringLine(Line3,(u8*)text);
		sprintf(text,"     R38:%.2lfV   ",tR38);
		LCD_DisplayStringLine(Line4,(u8*)text);
	}else if(view==1)//标准设置界面
	{
		sprintf(text,"      STANDARD   ");
		LCD_DisplayStringLine(Line1,(u8*)text);
		sprintf(text,"    SR37:%.1lf-%.1lf   ",SR37_l,SR37_r);
		LCD_DisplayStringLine(Line3,(u8*)text);
		sprintf(text,"    SR38:%.1lf-%.1lf   ",SR38_l,SR38_r);
		LCD_DisplayStringLine(Line4,(u8*)text);
	}else if(view==2)//合格率界面
	{
		sprintf(text,"        PASS   ");
		LCD_DisplayStringLine(Line1,(u8*)text);
		sprintf(text,"     PR37:%.1lf%%   ",res37*100);
		LCD_DisplayStringLine(Line3,(u8*)text);
		sprintf(text,"     PR38:%.1lf%%   ",res38*100);
		LCD_DisplayStringLine(Line4,(u8*)text);
	}
}

key:

void key_proc(void)
{
	if(keys[0].single_flag==1)
	{
		view=(view+1)%3;
		if(view==1) swic=0;
		LCD_Clear(Black);
		keys[0].single_flag=0;
	}else if(keys[1].single_flag==1)
	{
		if(view==0)//检测R37
		{
			sumR37++;
			if(tR37>=SR37_l&&tR37<=SR37_r)//通过
			{
				R37_flag=1;
				PR37++;
			}else R37_flag=0;
		}
		else if(view==1)//调整设置
		{
			swic=(swic+1)%4;
		}
		keys[1].single_flag=0;
	}else if(keys[2].single_flag==1)
	{
		if(view==0)//检测R38
		{
			sumR38++;
			if(tR38>=SR38_l&&tR38<=SR38_r)//通过
			{
				R38_flag=1;
				PR38++;
			}else R38_flag=0;
		}
		else if(view==1)//加
		{
			switch(swic)
			{
				case 0:
				{
					//R37上限
					SR37_r+=0.2;
					if(SR37_r>=3.2) SR37_r=2.2;
					sumR37=0;
					PR37=0;
				}
				break;
				case 1:
				{
					//R37下限
					SR37_l+=0.2;
					if(SR37_l>=2.2) SR37_l=1.2;
					sumR37=0;
					PR37=0;
				}
				break;
				case 2:
				{
					//R38上限
					SR38_r+=0.2;
					if(SR38_r>=3.2) SR38_r=2.2;
					sumR38=0;
					PR38=0;
				}
				break;
				case 3:
				{
					//R38下限
					SR38_l+=0.2;
					if(SR38_l>=2.2) SR38_l=1.2;
					sumR38=0;
					PR38=0;
				}
				break;
			}
		}
		keys[2].single_flag=0;
	}else if(keys[3].single_flag==1)
	{
		if(view==2)
		{
			sumR37=sumR38=0;
			PR37=PR38=0;
		}
		else if(view==1)//减
		{
			switch(swic)
			{
				case 0:
				{
					//R37上限
					SR37_r-=0.2;
					if(SR37_r<=2.0) SR37_r=3.0;
					sumR37=0;
					PR37=0;
				}
				break;
				case 1:
				{
					//R37下限
					SR37_l-=0.2;
					if(SR37_l<=1.0) SR37_l=2.0;
					sumR37=0;
					PR37=0;
				}
				break;
				case 2:
				{
					//R38上限
					SR38_r-=0.2;
					if(SR38_r<=2.0) SR38_r=3.0;
					sumR38=0;
					PR38=0;
				}
				break;
				case 3:
				{
					//R38下限
					SR38_l-=0.2;
					if(SR38_l<=1.0) SR38_l=2.0;
					sumR38=0;
					PR38=0;
				}
				break;
			}
		}
		keys[3].single_flag=0;
	}
}

led:

void led_proc(void)
{
	//定时1s 熄灭
	if(uwTick-LD1Tick>=1000)
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
	}
	if(uwTick-LD2Tick>=1000)
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET);
	}
	
    //通过了 先点亮  再过1s进行熄灭
	if(R37_flag==1)
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
		LD1Tick=uwTick;
		R37_flag=0;
	}
	if(R38_flag==1)
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
		LD2Tick=uwTick;
		R38_flag=0;
	}
	
    //检测当时是哪个界面 点亮对应的灯  否则熄灭
	if(view==0)
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);
	else 
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_SET);
	
	if(view==1)
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);
	else 
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_SET);
	
	if(view==2)
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET);
	else
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_SET);
	
    //很重要
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

usart: 

void usart_rx(void)
{
	char text[50];
	if(p>0)//有接受到数据
	{
		if(p==3)//是否符合题目要求的位数
		{
			if(strcmp(rxdata,"R37")==0)
			{
                //发送数据
				sprintf(text,"R37:%d,%d,%.1lf%%\r\n",sumR37,PR37,res37*100);
				HAL_UART_Transmit(&huart1,(uint8_t*)text,strlen(text),50);
			}else if(strcmp(rxdata,"R38")==0)
			{
				sprintf(text,"R38:%d,%d,%.1lf%%\r\n",sumR38,PR38,res38*100);
				HAL_UART_Transmit(&huart1,(uint8_t*)text,strlen(text),50);
			}
		}
	}
    //要清零 很重要
	p=0;
	memset(rxdata,0,sizeof(rxdata));
}

interrupt.c:

#include "interrupt.h"
#include "usart.h"

struct key keys[4];

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM3)
	{
		keys[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		keys[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		keys[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		keys[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		
        //状态机消抖
		for(int i=0;i<4;i++)
		{
			switch(keys[i].judge_sta)
			{
				case 0:
				{
					if(keys[i].key_sta==0)
					{
						keys[i].judge_sta=1;
					}
					break;
				}
				case 1:
				{
					if(keys[i].key_sta==0)
					{
						keys[i].judge_sta=2;
						keys[i].single_flag=1;
					}else
					{
						keys[i].judge_sta=0;
					}
					break;
				}
				case 2:
				{
					if(keys[i].key_sta==1)
					{
						keys[i].judge_sta=0;
						keys[i].single_flag=0;
					}
					break;
				}
			}
		}
	}
}

char rxdata[30];
uint p=0;
uint8_t data;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	rxdata[p++]=data;
	HAL_UART_Receive_IT(&huart1,&data,1);
}

myadc.c:

#include "myadc.h"

double getADC(ADC_HandleTypeDef *hadc)
{
	uint adc;
	HAL_ADC_Start(hadc);
	adc=HAL_ADC_GetValue(hadc);
	return adc*3.3/4096;
}

  ----THE END-----

有关蓝桥杯嵌入式的模块知识请参考如下:

蓝桥杯嵌入式模块学习系列

【蓝桥杯嵌入式学习G431】模块一:LED-CSDN博客

【蓝桥杯嵌入式学习G431】模块二:LCD-CSDN博客

【蓝桥杯嵌入式学习G431】模块三:KEY-CSDN博客

【蓝桥杯嵌入式学习G431】模块四:PWM-CSDN博客

【蓝桥杯嵌入式学习G431】模块五:USART-CSDN博客

【蓝桥杯嵌入式学习G431】模块六:ADC-CSDN博客

(还有几个模块没更新~)


有关蓝桥杯嵌入式历届真题请参考如下:

蓝桥杯嵌入式历届真题系列

蓝桥杯嵌入式第十二届省赛--程序设计部分-CSDN博客

蓝桥杯嵌入式第十三届省赛第一场--程序设计部分-CSDN博客

蓝桥杯嵌入式第十五届模拟赛--程序设计部分-CSDN博客

蓝桥杯嵌入式第十四届模拟赛第一期--程序设计部分-CSDN博客

蓝桥杯嵌入式第十三届省赛第二场——程序设计部分-CSDN博客  

  • 17
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值