本实验历程均基于CT117E-M4系列,STM32CubeMX里面的STM32G431RBTx系列完成,本文的代码是基于基准时钟里面的1ms计时变量来进行定时操作,不了解的小伙伴可以看看我的上一篇关于Systick的文章。
为了与后续步骤统一,也为了赛场上节约时间,我们可以不用自己从CubeMX软件里面新建项目,我们可以从官方给的资源数据包里面复制一分LCD程序作为编程模板,在此基础上编程(官方给的程序不要给删除或者编辑!!!),可以再新建新的工程用来配置CubeMX,后面移植到之前复制的编程模板里面,这样可以防止后续改变CubeMX丢失了之前编写的代码。
设置LED相关的GPIO为推挽输出模式;(PC8~PC15和PD2)
设置KEY相关的GPIO为输入模式(无需上下拉);(PA0,PB0,PB1,PB2)
STM32CubeMX设置将每个外设单独生成.c和.h文件,并生成代码
(插图为官方资料给的CT117E-M4产品手册)
下载程序时,需要设置Debug—Flash Download-添加STM32G4的下载算法(下载程序,看LCD是否显示正常)
事先下载好STM32G4xx的固件包(STM32官网有)
编写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
在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。
功能展示: