蓝桥杯嵌入式点灯和按键

发布时间:2024年01月24日

前言

本实验历程均基于CT117E-M4系列,STM32CubeMX里面的STM32G431RBTx系列完成,本文的代码是基于基准时钟里面的1ms计时变量来进行定时操作,不了解的小伙伴可以看看我的上一篇关于Systick的文章。

标题程序设计步骤

1.编程前的准备:

为了与后续步骤统一,也为了赛场上节约时间,我们可以不用自己从CubeMX软件里面新建项目,我们可以从官方给的资源数据包里面复制一分LCD程序作为编程模板,在此基础上编程(官方给的程序不要给删除或者编辑!!!),可以再新建新的工程用来配置CubeMX,后面移植到之前复制的编程模板里面,这样可以防止后续改变CubeMX丢失了之前编写的代码。

2.GPIO的配置:

设置LED相关的GPIO为推挽输出模式;(PC8~PC15和PD2)
设置KEY相关的GPIO为输入模式(无需上下拉);(PA0,PB0,PB1,PB2)
STM32CubeMX设置将每个外设单独生成.c和.h文件,并生成代码

在这里插入图片描述
在这里插入图片描述
(插图为官方资料给的CT117E-M4产品手册)
在这里插入图片描述

在这里插入图片描述

3.准备下载程序环境:

下载程序时,需要设置Debug—Flash Download-添加STM32G4的下载算法(下载程序,看LCD是否显示正常)
在这里插入图片描述
事先下载好STM32G4xx的固件包(STM32官网有)

4.编写程序:

编写led.c和led.h,key.c和key.h文件,并添加到工程中,编写LED_Control函数和Key_Read读取按键函数,完成LED控制
1.led.h

#ifndef __LED_H
#define __LED_H

#include "main.h"

void LED_Control(u8 led_ctrl);


#endif

2.led.c

#include "led.h"

void LED_Control(u8 led_ctrl)
{
  
 // HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOC, 0xff00, GPIO_PIN_SET);        //关闭所有LED灯
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);    //打开锁存器
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);  //关闭锁存器
  
  HAL_GPIO_WritePin(GPIOC, led_ctrl<<8, GPIO_PIN_RESET); //打开相应LED灯
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);    //打开锁存器
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);  //关闭锁存器
}

3.key.h

#ifndef __KEY_H
#define __KEY_H

#include "main.h"

extern u8 Trg;
extern u8 Cont;
void Key_Read(void);


#endif

3.key.c

#include "key.h"

#define KB1  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) 
#define KB2  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB3  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB4  HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)

#define KEYPORT  KB1| (KB2<<1)| (KB3<<2)| (KB4<<3)| 0xf0

u8 Trg;
u8 Cont;

//1.^ 异或,不同为一  2.Trg单次触发  Cont 长按判断  3.用if(Trg & 0x01)可以按位判断
void Key_Read(void)
{
 u8 ReadData = (KEYPORT)^0xff;
 Trg = ReadData & (ReadData ^Cont);
 Cont = ReadData;  
}

//按下B1 按下 长按 松手
// 00    00     00
//KEYPORT = 0xfe   ReadData = 0x01;  01   01
//00   01
//00   00

5.功能实现

在main.c添加led.c和led.h,key.c和key.h文件,并调用LED_Control函数和Key_Read函数,完成按键控制LED亮灭
main.c编写部分

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "led.h"
#include "key.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO uint32_t ledTick = 0;
u8 led_ctrl = 0xff;

__IO uint32_t keyTick = 0;
u8 cnt_key_time;

void KEY_Process(void)
{
  if(uwTick - keyTick < 10)return; //十毫秒扫描
  keyTick = uwTick;
  Key_Read();  //读取按键
  //按键B1
  if(Trg & 0x01)
  {
   LED_Control(0x03);
  }
  //按键B2
    if(Trg & 0x02)
  {
   LED_Control(0x0C);
  }
  //按键B3
    if(Trg & 0x04)
  {
   LED_Control(0x30);
  }
  //按键B4
    if(Trg & 0x08)
  {
   LED_Control(0xC0);
  }
  //长按按键B1
  if(Cont & 0x01)
  {
     cnt_key_time++;
    if(cnt_key_time == 100)
    {
      LED_Control(0x00);
      cnt_key_time = 0;
     }
  }
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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();
  /* USER CODE BEGIN 2 */
 LED_Control(0x00);  //把所有LED先熄灭
	LCD_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	LCD_DisplayStringLine(Line0, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line1, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line2, (uint8_t *)"      LCD Test      ");
	LCD_DisplayStringLine(Line3, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line4, (uint8_t *)"                    ");
	
	LCD_SetBackColor(White);
	LCD_SetTextColor(Blue);

	LCD_DisplayStringLine(Line5, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line6, (uint8_t *)"       HAL LIB      ");
	LCD_DisplayStringLine(Line7, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line8, (uint8_t *)"         @80        ");
	LCD_DisplayStringLine(Line9, (uint8_t *)"                    ");
	
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
 
   // LED_Process();
    KEY_Process();
  }
  /* USER CODE END 3 */
}

本代码功能是按键B1打开LED1和LED2,B2打开LED3和LED4,B3打开LED5和LED6,B4打开LED7和LED8,长按按键B1,关闭所有LED。

功能展示:
在这里插入图片描述

文章来源:https://blog.csdn.net/Xingxingbuhuiye/article/details/134645984
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。