2017年嵌入式第八届省赛真题解析

一、题目

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 

二、分析

题目各个外设的使用比较简单,但是整个题的逻辑比较复杂。所以,引入状态机,将整个应用程序分为多个状态机,每个状态机都控制该应用程序的特点部件。这些状态机都拥有自己的内部状态和状态转换,从中可以看成软件如何与各种激励相互作用。状态机(state machine)有 5 个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)

状态:系统在某一时刻所存在的稳定的工作情况,系统在整个工作周期中存在有多个状态

迁移:系统从一个状态转移到另一个状态的过程,迁移不会自动发生的,需要外界对系统施加影响,即在相应的条件,才会迁移

事件:某一时刻发生的对系统有意义的事,状态机发生状态迁移,就是因为出现了事件

动作:在状态机的迁移过程中,状态机会做出一些其它的行为,这些行为就是动作,动作是状态机对事件的响应

条件:状态机对事件并不是有求必应的,有了事件,状态机还要满足一定的条件才能发生状态迁移

注:一个状态机需要在状态集合中选取一个状态作为初始状态

也有人将它分为4类:状态,事件,动作,变换。

状态:一个状态机至少要包含两个状态

事件:事件就是执行某个操作的触发条件或者口令

动作:事件发生后执行的动作

变换:也从一个状态变化为另一个状态
 

不管是哪一种,其核心还是不变的。

通过以状态图的方式展示整个程序的流程图

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 各个状态的动作:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 在写程序前一定要将各个状态机的动作,变换以流程图的方式表示。上述状态机在裸机上选择switch...case语句实现整个程序的运行

整个程序以以各个状态为主体实现程序的逻辑,按键和显示界面进行输入与输出。

1.按键


//***按键扫描子函数
void Key_Proc(void)
{
	if((uwTick -  uwTick_Key_Set_Point)<50)	return;//减速函数
		uwTick_Key_Set_Point = uwTick;

	ucKey_Val = Key_Scan();
	unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val); 
	ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val);	
	ucKey_Old = ucKey_Val;
	
	if(state == 0)  //状态0,按键才有效
	{
		if(unKey_Down == 1)
		{
			if(platform != 1)
			{
				//先将第一位清0,然后置1
				layer_set &= ~(1<<0);
				layer_set |= (1<<0);
			}
		}
		if(unKey_Down == 2)
		{
			if(platform != 2)
			{
				//先将第二位清0,然后置1
				layer_set &= ~(1<<1);
				layer_set |= (1<<1);
			}
		}	
		if(unKey_Down == 3)
		{
			if(platform != 3)
			{
				//先将第三位清0,然后置1
				layer_set &= ~(1<<2);
				layer_set |= (1<<2);
			}
		}
		if(unKey_Down == 4)
		{
			if(platform != 4)
			{
				//先将第四位清0,然后置1
				layer_set &= ~(1<<3);
				layer_set |= (1<<3);  
			}
		}	
		// ucled低四位赋值
		ucLed &=  (0xf0);
		ucLed |= layer_set;
		if(unKey_Down != 0) //按键按下进行计时,超过1s进入状态1,
		{
			uwTick_Set_Point = uwTick;
		}
	}
}

按键主要是在初始状态下对目标层数的设置。

对一个8位变量的某一位进行操作:

清0(将第n位清0,n:[0-7]):layer_set &= ~(1<<n)
置1(将第n位置1,n:[0-7]):layer_set |= (1<<2)

第4位清0:layer_set &= 0xf0

2.状态机

整个逻辑其实参考现实中的电梯的运行,先从低到高方向处理对应的层数,当最高层处理完后,在处理比原来的当前层较低的层数。在其基础了添加了状态变换需要的条件和该状态下对应的动作。


void run(void)
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);// 默认高电平
	if(layer_set) // 按键按下,执行
	{
		switch(state)
		{
			case 0:
				if(uwTick - uwTick_Set_Point >= 1000)
					state = 1; //  1s后,进入状态1
				else
					break;
			case 1:
				//升降机关门:PA =1,关门时间4s
				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
				uwTick_Set_Point = uwTick;
				//开电机,准备启动:PA7输出PWM 2khz 占空比60%
				HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);		//PA7
				__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,300);  //设置PWM占空比300
				state = 2;
				sprintf((char *)Lcd_Disp_String, " Door Closing          ");
				LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
			
			case 2:
				if(uwTick - uwTick_Set_Point >= 4000)
				{
					HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1);		//PA7
					state = 3;
					sprintf((char *)Lcd_Disp_String, " Door Closed          ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
				}
				else
					break;
			case 3:
				// 判断电梯是上升还是下降,
				// platform :1-4(0001,0010,0100,1000)  layer_set :0000 _ _ _ _ 
			    // platform :2 ,layer_set: 0000 1001  上
			    // 1001 > 0010(第二层)   (1<<(platform-1)) = 0x10
				if(layer_set > (1<<(platform-1))) //设置的层数大小与当前层的比较 
				{
					dir = 1;//上行
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);// 上行
					HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);		//PA7
					__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,800);  //设置PWM占空比300
					
					sprintf((char *)Lcd_Disp_String, "Elev Upping          ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
				}
				//platform 2 ,layer_set 0000 0001 
				if(layer_set < (1<<(platform-1)))  
				{
					dir = 2;//下行
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);// 下行
					HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);		//PA7
					__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,600);  //设置PWM占空比300
					
					sprintf((char *)Lcd_Disp_String, "Elev Downing           ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);				
				}
				uwTick_Set_Point = uwTick;
				state = 4;
			case 4: // 两层之间运行6s
				if(uwTick - uwTick_Set_Point >= 6000)
				{
					HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);		//PA7停止
					if(dir == 1) platform++;  //层数变化
					else if(dir == 2) platform--;
					ucLed &= 0x0f;LED_Disp(ucLed);//高四为清0
					
					sprintf((char *)Lcd_Disp_String, "         %d   ",platform);
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);					

					sprintf((char *)Lcd_Disp_String, "Elev Runned 1 Floor        ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					state = 5;
				}
				else  // 产生流水灯 0x1000 =led_set 0001 0000
				{
					if(dir == 1) //上,左->右
					{
						if(led_set == 0x08)led_set = 0x80;
						ucLed = led_set;
						LED_Disp(ucLed);HAL_Delay(300);
						led_set = led_set>>1;
						
					} 
					else if(dir==2) //下,右->左
					{
						
						if(led_set2 == 0x00)led_set2 = 0x10; //led_set只有8位,溢出为0
						ucLed = led_set2;
						LED_Disp(ucLed);HAL_Delay(300);
						led_set2 = led_set2<<1;	
					}
					break;
				}
			case 5:  //判断是否为目标层 :当前层 与设置层进行按位与,非0,则为目标层
				// platform 2(0010) layer_set: 0000 0010
				if(1<<(platform-1) & layer_set)//不为0,到了目标层
				{
					// 闪烁2次
					
					sprintf((char *)Lcd_Disp_String, "              ");
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
					HAL_Delay(300);
					sprintf((char *)Lcd_Disp_String, "         %d   ",platform);
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
					HAL_Delay(300);
					sprintf((char *)Lcd_Disp_String, "              ");
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
					HAL_Delay(300);
					sprintf((char *)Lcd_Disp_String, "         %d   ",platform);
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);					
					
					
					HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);		//PA7停止
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);// 开门
					HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);		//电机控制信号
					__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,300);  //设置PWM占空比300
					
					sprintf((char *)Lcd_Disp_String, "Comed , Door Opening            ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					
					uwTick_Set_Point = uwTick;
					state = 6;
				}
				else //没有到达目标层,继续到下一层,直到到达目标层
				{
					uwTick_Set_Point = uwTick;
					state = 4;
					break;
				}
			case 6: //开门时间4s
				if(uwTick - uwTick_Set_Point >= 4000)
				{
					HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1);		//PA7
					
					sprintf((char *)Lcd_Disp_String, "Door Opened           ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					
					//到达目标层,该层灯灭,相应层清零
					layer_set &= ~(1<<(platform-1));
					ucLed &= 0xF0;
					ucLed |= layer_set;					
					LED_Disp(ucLed);					
					state = 7;	
				}
				else
					break;
			case 7: //判断是否还有别的目标层,有等待2s
				if(layer_set)
				{
					uwTick_Set_Point = uwTick;
					sprintf((char *)Lcd_Disp_String, "Waitting 2s           ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);						
					
					state = 8;	
				}
				else //没有就结束,等待按键按下重新开始
				{
					state = 0;
					sprintf((char *)Lcd_Disp_String, "                  ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					break;
				}
			case 8://2s后,电梯继续运行,重复从state1动作
				if((uwTick - uwTick_Set_Point) >= 2000)
				{		
					sprintf((char *)Lcd_Disp_String, "                  ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);
					
					state = 1; 										
				}		
		}
	}
}

以上都是根据状态机的流程图写的。

设置PWM的频率与占空比:这里我的主频是80Mhz,经过(79+1)分频得到1mhz,然后周期也即是STM32CubeMX里的自动重装载值设置的是(1000-1),所以周期为0.001,频率为1Khz。设置占空比就是要设置比较值Pluse。300,占空比就是30%

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57yW56iL5bCP54aK,size_20,color_FFFFFF,t_70,g_se,x_16

 也可以通过__HAL_TIM_SET_COMPARE修该占空比

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);        //PA7
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,300);  //设置PWM占空比30%

判断是否为目标层,将设置的层数与当前层(第二层 0010)进行按位与,若第二次为目标层,1 & 1 = 1。判断电梯是上行还是下行,将设置的层数与该层(第二层0010)进行比较即可。

注意:当一个8位的变量:0x10,进行左移四位后,发生溢出就变成0了。

其他部分基本上没有什么难点,完整程序贴在后面

 

三、程序

#include "main.h"
#include "RCC\bsp_rcc.h"
#include "KEY_LED\bsp_key_led.h"
#include "LCD\bsp_lcd.h"
#include "UART\bsp_uart.h"
#include "TIM\bsp_tim.h"
#include "RTC\bsp_rtc.h"

//***全局变量声明区
//*减速变量
__IO uint32_t uwTick_Key_Set_Point = 0;//控制Key_Proc的执行速度
__IO uint32_t uwTick_layer_set_Point = 0;//控制Led_Proc的执行速度
__IO uint32_t uwTick_Lcd_Set_Point = 0;//控制Lcd_Proc的执行速度
__IO uint32_t uwTick_Set_Point = 0;//控制系统延时的执行速度

//*按键扫描专用变量
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;

//*LED专用变量
uint8_t ucLed=0;

//*LCD显示专用变量
uint8_t Lcd_Disp_String[21];//最多显示20个字符

//*rtc相关变量
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};

uint8_t platform = 1; // 平台层数
uint8_t layer_set = 0x0;// state = 0:按下按键,设置层,对应的led亮
uint8_t state = 0;  // 状态机,将电梯的运行分为多个状态
uint8_t dir;//电梯运行方向变量 0 -没运行,1-上,2-下
uint8_t led_set =0x80;//上行流水灯
uint8_t led_set2 = 0x10; //下行流水灯

//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_Proc(void);
void run(void);


//***系统主函数
int main(void)
{

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

	/*bsp资源的初始化*/
	KEY_LED_Init();
	
	LCD_Init();
	LCD_Clear(White);
	LCD_SetBackColor(White);
	LCD_SetTextColor(Blue);	

	PWM_OUTPUT_TIM3_Init();
	PWM_OUTPUT_TIM17_Init();
	RTC_Init();
  while (1)
  {
		Key_Proc();
		Led_Proc();
		Lcd_Proc();
		run();
  }
}


//***按键扫描子函数
void Key_Proc(void)
{
	if((uwTick -  uwTick_Key_Set_Point)<50)	return;//减速函数
		uwTick_Key_Set_Point = uwTick;

	ucKey_Val = Key_Scan();
	unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val); 
	ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val);	
	ucKey_Old = ucKey_Val;
	
	if(state == 0)  //状态0,按键才有效
	{
		if(unKey_Down == 1)
		{
			if(platform != 1)
			{
				//先将第一位清0,然后置1
				layer_set &= ~(1<<0);
				layer_set |= (1<<0);
			}
		}
		if(unKey_Down == 2)
		{
			if(platform != 2)
			{
				//先将第二位清0,然后置1
				layer_set &= ~(1<<1);
				layer_set |= (1<<1);
			}
		}	
		if(unKey_Down == 3)
		{
			if(platform != 3)
			{
				//先将第三位清0,然后置1
				layer_set &= ~(1<<2);
				layer_set |= (1<<2);
			}
		}
		if(unKey_Down == 4)
		{
			if(platform != 4)
			{
				//先将第四位清0,然后置1
				layer_set &= ~(1<<3);
				layer_set |= (1<<3);  
			}
		}	
		// ucled低四位赋值
		ucLed &=  (0xf0);
		ucLed |= layer_set;
		if(unKey_Down != 0) //按键按下进行计时,超过1s进入状态1,
		{
			uwTick_Set_Point = uwTick;
		}
	}
}


void run(void)
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);// 默认高电平
	if(layer_set) // 按键按下,执行
	{
		switch(state)
		{
			case 0:
				if(uwTick - uwTick_Set_Point >= 1000)
					state = 1; //  1s后,进入状态1
				else
					break;
			case 1:
				//升降机关门:PA =1,关门时间4s
				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
				uwTick_Set_Point = uwTick;
				//开电机,准备启动:PA7输出PWM 2khz 占空比60%
				HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);		//PA7
				__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,300);  //设置PWM占空比300
				state = 2;
				sprintf((char *)Lcd_Disp_String, " Door Closing          ");
				LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
			
			case 2:
				if(uwTick - uwTick_Set_Point >= 4000)
				{
					HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1);		//PA7
					state = 3;
					sprintf((char *)Lcd_Disp_String, " Door Closed          ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
				}
				else
					break;
			case 3:
				// 判断电梯是上升还是下降,
				// platform :1-4(0001,0010,0100,1000)  layer_set :0000 _ _ _ _ 
			    // platform :2 ,layer_set: 0000 1001  上
			    // 1001 > 0010(第二层)   (1<<(platform-1)) = 0x10
				if(layer_set > (1<<(platform-1))) //设置的层数大小与当前层的比较 
				{
					dir = 1;//上行
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);// 上行
					HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);		//PA7
					__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,800);  //设置PWM占空比300
					
					sprintf((char *)Lcd_Disp_String, "Elev Upping          ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
				}
				//platform 2 ,layer_set 0000 0001 
				if(layer_set < (1<<(platform-1)))  
				{
					dir = 2;//下行
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);// 下行
					HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);		//PA7
					__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,600);  //设置PWM占空比300
					
					sprintf((char *)Lcd_Disp_String, "Elev Downing           ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);				
				}
				uwTick_Set_Point = uwTick;
				state = 4;
			case 4: // 两层之间运行6s
				if(uwTick - uwTick_Set_Point >= 6000)
				{
					HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);		//PA7停止
					if(dir == 1) platform++;  //层数变化
					else if(dir == 2) platform--;
					ucLed &= 0x0f;LED_Disp(ucLed);//高四为清0
					
					sprintf((char *)Lcd_Disp_String, "         %d   ",platform);
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);					

					sprintf((char *)Lcd_Disp_String, "Elev Runned 1 Floor        ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					state = 5;
				}
				else  // 产生流水灯 0x1000 =led_set 0001 0000
				{
					if(dir == 1) //上,左->右
					{
						if(led_set == 0x08)led_set = 0x80;
						ucLed = led_set;
						LED_Disp(ucLed);HAL_Delay(300);
						led_set = led_set>>1;
						
					} 
					else if(dir==2) //下,右->左
					{
						
						if(led_set2 == 0x00)led_set2 = 0x10; //led_set只有8位,溢出为0
						ucLed = led_set2;
						LED_Disp(ucLed);HAL_Delay(300);
						led_set2 = led_set2<<1;	
					}
					break;
				}
			case 5:  //判断是否为目标层 :当前层 与设置层进行按位与,非0,则为目标层
				// platform 2(0010) layer_set: 0000 0010
				if(1<<(platform-1) & layer_set)//不为0,到了目标层
				{
					// 闪烁2次
					
					sprintf((char *)Lcd_Disp_String, "              ");
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
					HAL_Delay(300);
					sprintf((char *)Lcd_Disp_String, "         %d   ",platform);
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
					HAL_Delay(300);
					sprintf((char *)Lcd_Disp_String, "              ");
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
					HAL_Delay(300);
					sprintf((char *)Lcd_Disp_String, "         %d   ",platform);
					LCD_DisplayStringLine(Line2, Lcd_Disp_String);					
					
					
					HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);		//PA7停止
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);// 开门
					HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);		//电机控制信号
					__HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,300);  //设置PWM占空比300
					
					sprintf((char *)Lcd_Disp_String, "Comed , Door Opening            ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					
					uwTick_Set_Point = uwTick;
					state = 6;
				}
				else //没有到达目标层,继续到下一层,直到到达目标层
				{
					uwTick_Set_Point = uwTick;
					state = 4;
					break;
				}
			case 6: //开门时间4s
				if(uwTick - uwTick_Set_Point >= 4000)
				{
					HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1);		//PA7
					
					sprintf((char *)Lcd_Disp_String, "Door Opened           ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					
					//到达目标层,该层灯灭,相应层清零
					layer_set &= ~(1<<(platform-1));
					ucLed &= 0xF0;
					ucLed |= layer_set;					
					LED_Disp(ucLed);					
					state = 7;	
				}
				else
					break;
			case 7: //判断是否还有别的目标层,有等待2s
				if(layer_set)
				{
					uwTick_Set_Point = uwTick;
					sprintf((char *)Lcd_Disp_String, "Waitting 2s           ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);						
					
					state = 8;	
				}
				else //没有就结束,等待按键按下重新开始
				{
					state = 0;
					sprintf((char *)Lcd_Disp_String, "                  ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);	
					break;
				}
			case 8://2s后,电梯继续运行,重复从state1动作
				if((uwTick - uwTick_Set_Point) >= 2000)
				{		
					sprintf((char *)Lcd_Disp_String, "                  ");
					LCD_DisplayStringLine(Line8, Lcd_Disp_String);
					
					state = 1; 										
				}		
		}
	}
}


//***LED扫描子函数
void Led_Proc(void)
{
	if((uwTick -  uwTick_layer_set_Point)<200)	return;//减速函数
		uwTick_layer_set_Point = uwTick;

	LED_Disp(ucLed);
}


void Lcd_Proc(void)
{
	if((uwTick -  uwTick_Lcd_Set_Point)<100)	return;//减速函数
		uwTick_Lcd_Set_Point = uwTick;
	
	
	sprintf((char *)Lcd_Disp_String, "         %d   ",platform);
	LCD_DisplayStringLine(Line2, Lcd_Disp_String);	
	
	//*RTC内容显示
	HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);//读取日期和时间必须同时使用
	HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
	sprintf((char *)Lcd_Disp_String, "   %02d-%02d-%02d",(unsigned int)sTime.Hours,(unsigned int)sTime.Minutes,(unsigned int)sTime.Seconds);
	LCD_DisplayStringLine(Line6, Lcd_Disp_String);		

}



void Error_Handler(void)
{
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
}

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super.Bear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值