【STM32G4】备战蓝桥杯嵌入式---实战---第十一届嵌入式模拟赛


前言

为了减少篇幅,各模块的初始化均在模块配置中,可以随时去翻看博客,还有function里面的函数,将不再罗列出来,只是截图展示。

一、题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、模块初始化以及功能分析

1.模块的初始化

需要用的模块:LCD、IIC、四个按键、LED、USART2

2.模块功能分析

LCD:显示-----》Display();
IIC:读取和存储信息到EEPROM-----》EEPROM_Write();EEPROM_Read();
按键:对参数进行调整-----》KEY_Handle();KEY_Scan();
LED:提示作用-----》LED();
USART2:与PC机交互

三、函数实现

1.void Display(void);

mode表示页面显示的三种状态
location表示设置某个位(时分秒),被选定为红色

void Dispaly(void)
{
	if(mode == 0)
	{
		LCD_DisplayStringLine(Line1,"      MAIN        ");
	}else if(mode == 1)
	{
		LCD_DisplayStringLine(Line1,"    RTC-SETTING     ");
	}else if(mode == 2)
	{
		LCD_DisplayStringLine(Line1,"   ALARM-SETTING     ");
	}
	
	if(mode == 0)
	{
		sprintf((char *)str,"  RTC:%.2d:%.2d:%.2d     ",Time[0],Time[1],Time[2]);
		LCD_DisplayStringLine(Line3,str);
	}
	else if(mode == 1)
	{
		if(location == 0)
		{
			LCD_SetTextColor(Black);
			sprintf((char *)str,"  RTC:  :%.2d:%.2d     ",Time[1],Time[2]);
			LCD_DisplayStringLine(Line3,str);
			LCD_SetTextColor(Red);
			LCD_DisplayChar(Line3,225, Time[0]/10 + '0');
			LCD_DisplayChar(Line3,210, Time[0]%10 + '0');
		}
		else if(location == 1)
		{
			LCD_SetTextColor(Black);
			sprintf((char *)str,"  RTC:%.2d:  :%.2d     ",Time[0],Time[2]);
			LCD_DisplayStringLine(Line3,str);
			LCD_SetTextColor(Red);
			LCD_DisplayChar(Line3,180, Time[1]/10 + '0');
			LCD_DisplayChar(Line3,165, Time[1]%10 + '0');
		}
		else if(location == 2)
		{
			LCD_SetTextColor(Black);
			sprintf((char *)str,"  RTC:%.2d:%.2d:         ",Time[0],Time[1]);
			LCD_DisplayStringLine(Line3,str);
			LCD_SetTextColor(Red);
			LCD_DisplayChar(Line3,130, Time[2]/10 + '0');
			LCD_DisplayChar(Line3,110, Time[2]%10 + '0');
		}
	}
	else if(mode == 2)
	{
		if(location == 0)
		{
			LCD_SetTextColor(Black);
			sprintf((char *)str,"Alarm:  :%.2d:%.2d     ",Alarm_Time[1],Alarm_Time[2]);
			LCD_DisplayStringLine(Line3,str);
			LCD_SetTextColor(Red);
			LCD_DisplayChar(Line3,225, Alarm_Time[0]/10 + '0');
			LCD_DisplayChar(Line3,210, Alarm_Time[0]%10 + '0');
		}
		else if(location == 1)
		{
			LCD_SetTextColor(Black);
			sprintf((char *)str,"Alarm:%.2d:  :%.2d     ",Alarm_Time[0],Alarm_Time[2]);
			LCD_DisplayStringLine(Line3,str);
			LCD_SetTextColor(Red);
			LCD_DisplayChar(Line3,180, Alarm_Time[1]/10 + '0');
			LCD_DisplayChar(Line3,165, Alarm_Time[1]%10 + '0');
		}
		else if(location == 2)
		{
			LCD_SetTextColor(Black);
			sprintf((char *)str,"Alarm:%.2d:%.2d:         ",Alarm_Time[0],Alarm_Time[1]);
			LCD_DisplayStringLine(Line3,str);
			LCD_SetTextColor(Red);
			LCD_DisplayChar(Line3,130, Alarm_Time[2]/10 + '0');
			LCD_DisplayChar(Line3,110, Alarm_Time[2]%10 + '0');
		}
	}
	LCD_SetTextColor(Black);
}

2.void EEPROM_Read(void);void EEPROM_Write(void);

IIC的读写函数在模块配置iic那一小节
分别存储当前时间、设定时间、报警次数、设置次数

void EEPROM_Read(void)
{
	Time[0] = IIC_Read(0x00);HAL_Delay(10);
	Time[1] = IIC_Read(0x01);HAL_Delay(10);
	Time[2] = IIC_Read(0x02);HAL_Delay(10);
	Alarm_Time[0] = IIC_Read(0x03);HAL_Delay(10);
	Alarm_Time[1] = IIC_Read(0x04);HAL_Delay(10);
	Alarm_Time[2] = IIC_Read(0x05);HAL_Delay(10);
	Alarm_num = IIC_Read(0x06);HAL_Delay(10);
	Set_RTC = IIC_Read(0x07);HAL_Delay(10);
}
void EEPROM_Write(void)
{
	IIC_Write(0x00,Time[0]);HAL_Delay(10);
	IIC_Write(0x01,Time[1]);HAL_Delay(10);
	IIC_Write(0x02,Time[2]);HAL_Delay(10);
	IIC_Write(0x03,Alarm_Time[0]);HAL_Delay(10);
	IIC_Write(0x04,Alarm_Time[1]);HAL_Delay(10);
	IIC_Write(0x05,Alarm_Time[2]);HAL_Delay(10);
	IIC_Write(0x06,Alarm_num);HAL_Delay(10);
	IIC_Write(0x07,Set_RTC);HAL_Delay(10);
}

3.uint8_t KEY_Scan(uint8_t mode);

由于有长按和短按,所以对于长按有B3_B4函数进行操作(操作代码一样,调用函数更省空间)

uint8_t KEY_Scan(void)
{
	uint8_t sum;//计数个数
	static uint8_t flag = 1;
	sum = 0;
	if(flag &&(KEY_B1 == 0 || KEY_B2	== 0 || KEY_B3 == 0 ||	KEY_B4== 0 ))
	{
		flag = 0;
		HAL_Delay(10);
		if (KEY_B1 == 0)	return B1_Press;
		else if (KEY_B2 == 0) return B2_Press;
		while(!KEY_B3)
		{
			HAL_Delay(200);
			sum++;
			if(sum > 5 )
			{
				 B3_B4(B3_Press);
			}	
		}
		if (sum < 5 && sum != 0) return B3_Press;
		while(!KEY_B4)
		{
			HAL_Delay(200);
			sum++;
			if(sum>5)
			{
				 B3_B4(B3_Press);
			}
		}
		if (sum < 5 && sum != 0) return B4_Press;
	}else if(KEY_B1 == 1 && KEY_B2	== 1 && KEY_B3 == 1 &&	KEY_B4== 1) flag = 1;
	return 0;
}

4.void KEY_Handle(uint8_t key);void B3_B4(uint8_t key)

在B1按下时显示页面切换(mode变化)
在B2按下时切换参数选择的地址(location变化)
在B3按下时对应参数加1
在B4按下时对应参数减1

void KEY_Handle(uint8_t key)
{
	if(key == B1_Press)
	{
		if(mode == 0)
		{
			run = 0;
			mode = 1;
		}
		else if(mode == 1)
		{
			Set_RTC++;
			run = 1;
			mode = 0;
			EEPROM_Write();
		}
		else if(mode == 2)
		{
			location++;
			location = location % 3 ;
		}
	}
	else if(key == B2_Press)
	{
		if(mode == 0)
		{
			run = 0;
			mode = 2;
		}
		else if(mode == 2)
		{
			run = 1;
			mode = 0;
			EEPROM_Write();
		}
		else if(mode == 1)
		{
			location++;
			location = location % 3 ;
		}
	}
	else if(key == B3_Press)	B3_B4(B3_Press);
	else if(key == B4_Press)	B3_B4(B4_Press);
}
void B3_B4(uint8_t key)
{
	if(key == B3_Press)
	{
		if(mode == 1)
		{
			Time[location]++;
			Time[location] = Time[location] % 60;
			Time[0] = Time[0] % 24;
		}
		else if(mode == 2)
		{
			Alarm_Time[location]++;
			Alarm_Time[location] = Alarm_Time[location] % 60;
			Alarm_Time[0] = Alarm_Time[0] % 24;
		}
	}
	else if(key == B4_Press)
	{
		if(location == 0)
		{
			if(mode == 1)
			{
				if(!Time[0]) Time[0] = 23;
				Time[0]--;
			}
			else if(mode == 2)
			{
				if(!Alarm_Time[0]) Alarm_Time[0] = 23;
				Alarm_Time[0]--;
			}
		}
		else
		{
			if(mode == 1)
			{
				if(!Time[location]) Time[location] = 59;
				Time[location]--;
			}
			else if(mode == 2)
			{
				if(!Alarm_Time[location]) Alarm_Time[location] = 59;
				Alarm_Time[location]--;
			}
		}
	}
}

5.int main(void);

初始化;

在这里插入图片描述

I2CInit();
LCD_Init();

LCD_Clear(White);

LCD_SetTextColor(Black);
mode = 0;
IIC_Write(0x00,11);HAL_Delay(10);
IIC_Write(0x01,59);HAL_Delay(10);
IIC_Write(0x02,50);HAL_Delay(10);
IIC_Write(0x03,12);HAL_Delay(10);
IIC_Write(0x04,00);HAL_Delay(10);
IIC_Write(0x05,00);HAL_Delay(10);
IIC_Write(0x06,0);HAL_Delay(10);
IIC_Write(0x07,0);HAL_Delay(10);

EEPROM_Read();
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_10
												|GPIO_PIN_9|GPIO_PIN_11|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);

while(1);

在这里插入图片描述
在这里插入图片描述

		Dispaly();//显示
		key = KEY_Scan();
		KEY_Handle(key);
		if(count == 1 && run && mode == 0)//计数 
		{
			Time[2]++;
			if(Time[2] >= 60)
			{
				Time[2] = 0;
				Time[1]++;
			}
			if(Time[1] >= 60)
			{
				Time[1] = 0;
				Time[0]++;
			}
			if(Time[0] >= 24)	Time[0] = 0;
			count = 0;
			
//		  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
			if(i++%2)
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
			else
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|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);
		}
		if(Alarm_Time[0] == Time[0] && Alarm_Time[1] == Time[1] && Alarm_Time[2] == Time[2])//报警
		{
			Alarm_num++;
			IIC_Write(0x06,Alarm_num);HAL_Delay(10);
			Dispaly();
			HAL_Delay(3000);
			num = 0;
			EEPROM_Read();
			printf("NEW RTC:%.2d:.%.2d:%.2d\r\n",Time[0],Time[1],Time[2]);
			printf("NEW Alarm:%.2d:%.2d:%.2d\r\n",Alarm_Time[0],Alarm_Time[1],Alarm_Time[2]);
		}
		if(mode == 1)
		{
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_10|GPIO_PIN_11|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);
		}
		else if(mode == 2)
		{
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_11|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);
		}

6.void SysTick_Handler(void);

上面的time和count在哪变了,在哪计时呢?
就在滴答定时器里面咯。
大家打开stm32g4xx_it.c
在这里插入图片描述

	if(run) num++;
	if(num >= 1000)
	{
		count = 1;
		num = 0;
	}

运行的时候才开始计数,一秒的计数。


总结

以上就是本次模拟赛的程序设计部分(变量定义部分,本人没有罗列出来嗷),在代码简洁方面本人做的不是很好,如有更好的设计方法可以在评论区留言。互相学习。👍

还等什么,赶快自己写一下,测试一下代码。本人亲测有效、嘿嘿

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值