IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 蓝桥杯嵌入式STM32G431——第八届省赛真题模拟升降控制器 -> 正文阅读

[嵌入式]蓝桥杯嵌入式STM32G431——第八届省赛真题模拟升降控制器

第八届省赛真题

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

主函数部分代码

#include "main.h"
#include "rcc.h"
#include "led_key.h"
#include "lcd.h"
#include "rtc.h"
#include "tim.h"
//***执行速度控制变量
__IO uint32_t uwTick_LED_Speed_Ctrl;
__IO uint32_t uwTick_KEY_Speed_Ctrl;
__IO uint32_t uwTick_LCD_Speed_Ctrl;



//***全局变量区
uint8_t ucLED;

uint8_t key_value,key_up,key_down;
static uint8_t key_old;	//按键三行代码

uint8_t LCD_String_Disp[21];

RTC_TimeTypeDef T;
RTC_DateTypeDef D;

uint8_t Current_platform = 1; //当前平台默认为1
uint8_t Set_platform; //只使用该变量的低四位 按键B1-B4对应设置的需要到达的平台对应LD1-LD4 

__IO uint32_t uwTick_Time_Count; //用于时间计数

uint8_t State_Num; //状态号变量,默认为0
uint8_t Direction; //1表示上行 2表示下行
uint8_t Flow_LED = 0x10; //流水灯 只使用高四位

//***子函数声明区
void SystemClock_Config(void);
void LED_Proc(void);
void KEY_Proc(void);
void LCD_Proc(void);
void Lift_State_Proc(void);


//***主函数区
int main(void)
{
  HAL_Init();
	
  SystemClock_Config();
	
	//*函数初始化区
	LED_KEY_Init();
	
	LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(Magenta);
	
	RTC_Init();
	
	TIM3_Init();
	//__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,800);
	HAL_TIM_PWM_Start(&htim3 , TIM_CHANNEL_1);
	
	TIM17_Init();
	HAL_TIM_PWM_Start(&htim3 , TIM_CHANNEL_1);
	
  while (1)
  {
		Lift_State_Proc();
		LED_Proc();
		KEY_Proc();
		LCD_Proc();
  }

}

void LED_Proc(void)
{
	if((uwTick - uwTick_LED_Speed_Ctrl)<100) return;
		uwTick_LED_Speed_Ctrl = uwTick; //100ms执行一次

	
	LED_Disp(ucLED);
}


void KEY_Proc(void)
{
	if((uwTick - uwTick_KEY_Speed_Ctrl)<100) return;
		uwTick_KEY_Speed_Ctrl = uwTick; //100ms执行一次
	
	key_value = KEY_Scan();
	key_up = key_value & (key_value ^ key_old);
	key_down = ~key_value & (key_value ^ key_old);
	key_old = key_value;
	
	if(State_Num == 0)
	{
		if(key_down == 1) //B1按下
		{
			if(Current_platform != 1) Set_platform |= 0x01; //当前楼层按下不起作用
		}
		
		else if(key_down == 2)	//B2按下
		{
			if(Current_platform != 2) Set_platform |= 0x02;
		}
		
		else if(key_down == 3)	//B3按下
		{
			if(Current_platform != 3) Set_platform |= 0x04;
		}
		
		else if(key_down == 4)	//B4按下
		{
			if(Current_platform != 4) Set_platform |= 0x08;
		}
	}
	ucLED &= 0xF0; //使用与等于 将低四位清理 高四位保持
	ucLED |= Set_platform; //使用或等于 保持高四位不变
	
	if(key_down != 0) //当没有按键按下时,开始计数
	{
		uwTick_Time_Count = uwTick; //更新计时初始时间,开始计时
	}
}

void LCD_Proc(void)
{
	if((uwTick - uwTick_LCD_Speed_Ctrl)<100) return;
		uwTick_LCD_Speed_Ctrl = uwTick; //100ms执行一次
	
	
	memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
	sprintf((char*)LCD_String_Disp , "  Current platform        ");
	LCD_DisplayStringLine(Line1 , LCD_String_Disp);
	
	if(State_Num != 5)
	{
		memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
		sprintf((char*)LCD_String_Disp , "          %1d            ",(unsigned int)Current_platform);
		LCD_DisplayStringLine(Line4 , LCD_String_Disp);
	}

	
	HAL_RTC_GetTime(&hrtc , &T ,RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc , &D ,RTC_FORMAT_BIN);
	memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
	sprintf((char*)LCD_String_Disp , "      %02d-%02d-%02d ",T.Hours,T.Minutes,T.Seconds);
	LCD_DisplayStringLine(Line6 , LCD_String_Disp);
	
	if(State_Num == 0)
	{
		memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
		sprintf((char*)LCD_String_Disp , "    Open door         ");	//升降机默认为打开
		LCD_DisplayStringLine(Line8 , LCD_String_Disp);
	}
	
}

void Lift_State_Proc(void) //升降机状态处理函数
{
	if(Set_platform) //当有按键按下设置了需要到达的平台执行此程序,否则不执行
	{
		switch(State_Num)
		{
			case 0:
				if((uwTick - uwTick_Time_Count)>=1000) //如果等待时间超过1秒,进入下一状态-状态1
					State_Num = 1;
				else
					break;
		
			case 1:  //控制升降机关门,配置PA7关门PWM信号 PA7     ------> TIM17_CH1
				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); //PA5 = 0
				__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1,250); // PA7 关门 - 2khz 占空比 50% - 250
				HAL_TIM_PWM_Start(&htim17 , TIM_CHANNEL_1); 
			
				memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
				sprintf((char*)LCD_String_Disp , "    Closing door         ");
				LCD_DisplayStringLine(Line8 , LCD_String_Disp);
			
				uwTick_Time_Count = uwTick; //更新计时初始时间,开始计时
				State_Num = 2;
			
			case 2: //等待4s关门时间是否到达,
				if((uwTick - uwTick_Time_Count)>4000) //如果关门时间大于4s,停止关门PWM进入下一状态
				{
					HAL_TIM_PWM_Stop(&htim17 , TIM_CHANNEL_1); 
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "    Close door         ");
					LCD_DisplayStringLine(Line8 , LCD_String_Disp);					
					
					HAL_Delay(1000);
					
					State_Num = 3;
				}
				else
					break;
		
			case 3:	//	判断升降机是上行还是下行,配置PA6上下行PWM信号 PA6    ------> TIM3_CH1
				if(Set_platform > ( 1<<(Current_platform-1) ) ) //如果设置的平台大于当前平台——上行 
				{
					Direction = 1;
					
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //PA4 = 1
					__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,800); // PA6 上行 - 1khz 占空比 80% - 800
					HAL_TIM_PWM_Start(&htim3 , TIM_CHANNEL_1);

					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "    Lift Up         ");
					LCD_DisplayStringLine(Line8 , LCD_String_Disp);					
				
				}
				else if(Set_platform < ( 1<<(Current_platform-1) ) ) //如果设置的平台小于当前平台——下行 
				{
					
					Direction = 2;
					
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //PA4 = 0
					__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,600); // PA6 下行 - 1khz 占空比 60%- 600
					HAL_TIM_PWM_Start(&htim3 , TIM_CHANNEL_1); 
					
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "    Lift Down         ");
					LCD_DisplayStringLine(Line8 , LCD_String_Disp);						
				}
				
				uwTick_Time_Count = uwTick; //更新计时初始时间,开始计时
				State_Num = 4;
				
			case 4:	//等待6s升降机上行或下行时间是否到达
				if((uwTick - uwTick_Time_Count)>=6000) //如果时间到达 控制当前平台变量加一或减一,流水灯关闭和恢复初始状态,进入下一状态
				{
					if(Direction == 1) //上行 当前平台加一个单位
					{
						Current_platform += 1;
					}
					else if(Direction == 2) //下行 当前平台减一个单位
					{
						Current_platform -= 1;
					}
					ucLED &= 0x0F;
					Flow_LED = 0x10;
					State_Num = 5;
					
				}
				else //产生流水灯的效果,左至右 上行 右至左 下行,退出,继续等待6秒的到来
				{
					if(Direction == 1) //上行 流水灯从左到右
					{
						Flow_LED = Flow_LED>>1; //右移1位 0001 0000 -> 0000 1000
						if(Flow_LED == 0x08) //0001 0000 - 0000 1000
							Flow_LED = 0x80;
						ucLED &= 0x0F;						
						ucLED |= Flow_LED;
					}
					else if(Direction == 2) //下行 流水灯从右到左
					{
						ucLED &= 0x0F;
						ucLED |= Flow_LED;						
						Flow_LED = Flow_LED<<1;	
						if(Flow_LED  == 0x00)	//1000 0000 - 0001 0000
							Flow_LED = 0x10;
					}
					HAL_Delay(300);
					break;
				}
				
			case 5://判断当前到达的平台是否是对应需要到达的平台
				if(( 1<<(Current_platform-1) ) == Set_platform)	//是,停止上下行PWM信号,开门(open door)配置PA7 
				{
					HAL_TIM_PWM_Stop(&htim3 , TIM_CHANNEL_1);
					HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); //PA5 = 1
					__HAL_TIM_SET_COMPARE(&htim17, TIM_CHANNEL_1,300); // PA7 开门 - 2khz 占空比 60% - 300
					HAL_TIM_PWM_Start(&htim17 , TIM_CHANNEL_1); 
			
					
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "    Opening door            ");
					LCD_DisplayStringLine(Line8 , LCD_String_Disp);	

					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "                         ");
					LCD_DisplayStringLine(Line4 , LCD_String_Disp);
					HAL_Delay(250);
					
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "          %1d            ",(unsigned int)Current_platform);
					LCD_DisplayStringLine(Line4 , LCD_String_Disp);
					HAL_Delay(250);
					
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "                         ");
					LCD_DisplayStringLine(Line4 , LCD_String_Disp);
					HAL_Delay(250);
					
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "          %1d            ",(unsigned int)Current_platform);
					LCD_DisplayStringLine(Line4 , LCD_String_Disp);
					HAL_Delay(250);
					
					uwTick_Time_Count = uwTick; //更新计时初始时间,开始计时
					State_Num = 6;
				}
				else
				{
					State_Num = 3;
					break;
				}
				
			case 6 : //等待开门时间4s到来
				if((uwTick - uwTick_Time_Count)>=4000) //等待4s开门,关闭开门PWM信号
				{
					HAL_TIM_PWM_Stop(&htim17 , TIM_CHANNEL_1); 
					
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "    Open door            ");
					LCD_DisplayStringLine(Line8 , LCD_String_Disp);	
					
					Set_platform &= (~(1<<(Current_platform-1)));  //到达设置的目标平台,将此目标平台清除
					ucLED &= 0xF0;
					ucLED |= Set_platform;
					LED_Disp(ucLED);
					State_Num = 7;		
					
				}
				else
					break;
				
			case 7: //判断是否还有其他目标平台
				if( Set_platform != 0 ) //还有其他设置平台,进入状态8
				{
					uwTick_Time_Count = uwTick; //更新计时初始时间,开始计时
					State_Num = 8;	
				}
				else	//没有其他设置平台,进入状态0
				{
					
					memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
					sprintf((char*)LCD_String_Disp , "    Get it %1d floor           ",(unsigned int)Current_platform);
					LCD_DisplayStringLine(Line8 , LCD_String_Disp);	
					HAL_Delay(1000);
					
					State_Num = 0;
					break;
				}
				
			case 8: //

				if((uwTick - uwTick_Time_Count)>=2000) //等待2s
				{
					State_Num = 1;
					break;
				}
				else
					break;
		}
	}
	
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-02-14 21:20:17  更:2022-02-14 21:22:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:53:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码