蓝桥杯嵌入式第十三届第一场程序题

文章介绍了如何在嵌入式项目中,利用C语言实现定时器(systick)控制标志位,处理按键输入并更新LED状态,同时使用LCD和UART进行显示,以及如何通过中断管理定时任务和字符转换。
摘要由CSDN通过智能技术生成

题目

新建工程 

参考零基础蓝桥杯嵌入式教程-CSDN博客

编程框架

key3的功能较多,需要判定密码正确与否,所以key3设置一个标志位,进入标志位改变函数来控制其他模块,但是需要定时操作,所以使用systick来延时,延时结束后再次设置变量和标志位。 

其中显示@和显示数字都要求,但是定义为uint8_t 类型的话@会存储为255,显示时需要用%d和%c不断切换显示@和数字,但是数字字符也是以编码形式存储,所以直接定义为char,统一显示格式为%c,而且字符加一也会是和数字加一是一样的效果。

主要代码

my_main.c

#include "my_main.h"

bool view=0;
char text[30];
uchar B1='@';
uchar B2='@';
uchar B3='@';
char mima[3]={'1','2','3'};

uint16_t frq=1000;
uint8_t duty=50;

typedef struct keys
{
	bool status;
	bool shortdown;
	bool longdown;
	uint8_t times;
}KEY;
 
KEY key[4];

uint8_t err=0;

bool key3_flag=0;
bool led_flag1=0;
bool led_flag2=0;
bool pwm_flag=0;
bool time5000_start_f=0;
bool time2000_start_f=0;

char uart_rx[30];
char uart_tx[30];
char text1[3];
char text2[3];
//
void setup(void)
{
	LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	
	HAL_TIM_Base_Start_IT(&htim4);
	
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);

	HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t *)uart_rx,30);
}
lcd
void lcd_proce(void)
{
	if(view==0)
	{	
		sprintf(text,"       PSD      ");
		LCD_DisplayStringLine(Line1,(uint8_t*)text);
		sprintf(text,"    B1:%c     ",B1);
		LCD_DisplayStringLine(Line3,(uint8_t*)text);
		sprintf(text,"    B2:%c     ",B2);
		LCD_DisplayStringLine(Line4,(uint8_t*)text);
		sprintf(text,"    B3:%c     ",B3);
		LCD_DisplayStringLine(Line5,(uint8_t*)text);
	}
	if(view==1)
	{	
		sprintf(text,"       STA      ");
		LCD_DisplayStringLine(Line1,(uint8_t*)text);
				sprintf(text,"    F:%dHz     ",frq);
		LCD_DisplayStringLine(Line3,(uint8_t*)text);
				sprintf(text,"    D:%d%%     ",duty);
		LCD_DisplayStringLine(Line4,(uint8_t*)text);
	}
}
///key
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM4)
	{
		key[0].status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		key[1].status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[2].status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[3].status=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
	}
	for(int i=0;i<4;i++)
	{
		if(key[i].status==0)
		{
			key[i].times++;
		}
		if(key[i].status==1)
		{
			if(key[i].times>40)key[i].longdown=1;
			else if((key[i].times>2)&&(key[i].times<40))key[i].shortdown=1;
			key[i].times=0;
		}
	}
}

void key_proce(void)
{
	if(key[0].shortdown==1)
	{
		key[0].shortdown=0;
		if(view==0)
		{
			if((B1=='9')||(B1=='@'))
			{
				B1='0';
			}
			else B1++;
		}
	}
	if(key[1].shortdown==1)
	{
		key[1].shortdown=0;
		if(view==0)
		{
			if((B2=='9')|(B2=='@'))
			{
				B2='0';
			}
			else B2++;
		}
	}
	if(key[2].shortdown==1)
	{
		key[2].shortdown=0;
		if(view==0)
		{
			if((B3=='9')|(B3=='@'))
			{
				B3='0';
			}
			else B3++;
		}
	}
	if(key[3].shortdown==1)
	{
		key[3].shortdown=0;
		key3_flag=1;
	}
}
///led
void LED_disp(uint lednumb,bool on_off)
{
 static uint8_t mmry=0x00;
	if(on_off==1) mmry|=lednumb;
	if(on_off==0) mmry&=~lednumb;
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);//GPIO_PIN_All,只有A大写
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//打开锁存器PD2
	HAL_GPIO_WritePin(GPIOC,mmry<<8,GPIO_PIN_RESET);//mmry左移八位到要控制的高八位
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//关闭锁存器PD2
}

void led_proce(void)
{
	LED_disp(1,led_flag1);
	LED_disp(2,led_flag2);
}
/flag_change
void flag_change_proce(void)
{
	if(key3_flag==1)
	{
		key3_flag=0;
		if(B1==mima[0]&&B2==mima[1]&&B3==mima[2])
		{
			err=0;
			view=1;
			LCD_Clear(Black);
			led_flag1=1;
			pwm_flag=1;
			time5000_start_f=1;
		}
		else
		{
			B1='@';
			B2='@';
			B3='@';
			err++;
			if(err>=3)
			{
				time2000_start_f=1;
			}
		}
	}	
}
pwm
void pwm_proce(void)
{
	if(pwm_flag==0)
	{
		frq=1000;
		duty=50;
		__HAL_TIM_SetAutoreload(&htim2,10000-1);
	}
	else if(pwm_flag==1)
	{
		frq=2000;
		duty=10;
		__HAL_TIM_SetAutoreload(&htim2,500-1);
		__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,50);
	}
}
//uart
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	sscanf(uart_rx,"%3s-%3s",text1,text2);
	if(text1[0]==mima[0]&&text1[1]==mima[1]&&text1[2]==mima[2])
	{
		mima[0]=text2[0];
		mima[1]=text2[1];
		mima[2]=text2[2];
		sprintf(uart_tx,"ok");
		HAL_UART_Transmit(&huart1,(uint8_t *)uart_tx,strlen(uart_tx),50);
		HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t *)uart_rx,30);
	}
}
/loop
void loop(void)
{
	lcd_proce();
	key_proce();
	led_proce();
	pwm_proce();
	flag_change_proce();
}

my_main.h

#ifndef _MY_MAIN_H_
#define _MY_MAIN_H_

#include "main.h"
#include "lcd.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

#include "stdbool.h"
#include "stdio.h"
#include "string.h"

void loop(void);
void setup(void);
void lcd_proce(void);
void led_proce(void);
void flag_change_proce(void);
void pwm_proce(void);

#endif

systick 




#include "my_main.h"
extern bool time5000_start_f;
extern bool time2000_start_f;
extern bool view;
extern bool pwm_flag;
extern bool led_flag1;
extern bool led_flag2;
extern uchar B1;
extern uchar B2;
extern uchar B3;
uint32_t time5000=0;
uint32_t time2000=0;



void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
if(time5000_start_f==1)
{
	time5000++;
	if(time5000>5000)
	{
		time5000_start_f=0;
		time5000=0;
		
		led_flag1=0;
		view=0;
		//pwm_flag=0;
		B1='@';
		B2='@';
		B3='@';
	}
}

if(time2000_start_f==1)
{
	led_flag2=!led_flag2;
	time2000++;
	if(time2000>2000)
	{
		time2000_start_f=0;
		led_flag2=0;
	}
}
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}


  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Nemophilist12

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

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

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

打赏作者

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

抵扣说明:

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

余额充值