目录
LED、LCD、KEY模块为必考模块
考题总结
一、LCD模块
1.把Inc和Src文件中的几个.h文件和.c文件复制到相应文件夹里
2.由产品手册可知LCD模块和LED模块公用PC8-PC15引脚,为了避免引起冲突,需要对以下三个函数做一下修改:
3.LCD高亮显示
//LCD processing function
void LCD_Proc(void)
{
if(Show_Flag == 1){
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line1, (uint8_t *)" Data");
LCD_DisplayStringLine(Line3, (uint8_t *)Show_CNBR);
LCD_DisplayStringLine(Line5, (uint8_t *)Show_VNBR);
LCD_DisplayStringLine(Line7, (uint8_t *)Show_IDLE);
}else if(Show_Flag == 2){
if(HiLi_Flag == 0){
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line1, (uint8_t *)" Para");
LCD_DisplayStringLine(Line3, (uint8_t *)Show_CNBR_Price);
LCD_DisplayStringLine(Line5, (uint8_t *)Show_VNBR_Price);
LCD_DisplayStringLine(Line7, (uint8_t *)" ");
}else if(HiLi_Flag == 1){//
LCD_SetBackColor(White);
LCD_SetTextColor(Black);
LCD_DisplayChar(Line3,(320-(16*10)),Show_CNBR_Price[10]);
LCD_DisplayChar(Line3,(320-(16*11)),Show_CNBR_Price[11]);
LCD_DisplayChar(Line3,(320-(16*12)),Show_CNBR_Price[12]);
LCD_DisplayChar(Line3,(320-(16*13)),Show_CNBR_Price[13]);
if(C_Dot_Flag == 1)//做了一个位数的变化,比如3.50变成10.50,判断一下最后一位要不要高亮,如果不要就用空格来代替
LCD_DisplayChar(Line3,(320-(16*14)),Show_CNBR_Price[14]);
else{
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_DisplayChar(Line3,(320-(16*14)),' ');
}
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line5, (uint8_t *)Show_VNBR_Price);
}else if(HiLi_Flag == 2){
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line3, (uint8_t *)Show_CNBR_Price);
LCD_SetBackColor(White);
LCD_SetTextColor(Black);
LCD_DisplayChar(Line5,(320-(16*10)),Show_VNBR_Price[10]);
LCD_DisplayChar(Line5,(320-(16*11)),Show_VNBR_Price[11]);
LCD_DisplayChar(Line5,(320-(16*12)),Show_VNBR_Price[12]);
LCD_DisplayChar(Line5,(320-(16*13)),Show_VNBR_Price[13]);
if(V_Dot_Flag == 1)
LCD_DisplayChar(Line5,(320-(16*14)),Show_VNBR_Price[14]);
else{
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LCD_DisplayChar(Line5,(320-(16*14)),' ');
}
}
}
}
二、LED模块
1.led.h文件用模板就可以
#include "stm32g4xx_hal.h"
#define ON 1
#define OFF 0
#define LED1 GPIO_PIN_8
#define LED2 GPIO_PIN_9
#define LED3 GPIO_PIN_10
#define LED4 GPIO_PIN_11
#define LED5 GPIO_PIN_12
#define LED6 GPIO_PIN_13
#define LED7 GPIO_PIN_14
#define LED8 GPIO_PIN_15
#define LEDALL GPIO_PIN_All
void LED_Ctrl(uint16_t LED, uint8_t LED_Status);
2.led.c文件----直接用模板,闪烁、亮灭都用那一个函数
如果要闪烁的话:灯亮了之后加一个HAL_DLAY()函数就行
#include "led.h"
void LED_Ctrl(uint16_t LED, uint8_t LED_Status)
{
if(LED_Status == ON){ //ÁÁµÆ
HAL_GPIO_WritePin(GPIOC,LED,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
else{ //ÃðµÆ
HAL_GPIO_WritePin(GPIOC,LED,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
}
三、KEY模块
1.key.h-----用模板(不管是中断的方式还是while循环的方式查找是否有按键,都统一了)
#include "stm32g4xx_hal.h"
#define Press(x) (HAL_GPIO_ReadPin(x))
#define KB1 GPIOB, GPIO_PIN_0
#define KB2 GPIOB, GPIO_PIN_1
#define KB3 GPIOB, GPIO_PIN_2
#define KB4 GPIOA, GPIO_PIN_0
uint8_t Key_Scan(void);
2.key.c这个文件只保留了短按
#include "key.h"
uint8_t Key_Scan(void)
{
char key_value = 0;
if(Press(KB1) == 0) { //key1
HAL_Delay(10); //È¥¶¶
if(Press(KB1) == 0){
key_value = 1;
while(Press(KB1) == 0); //°´¼üËÉ¿ªÐ§¹û
}
}else if(Press(KB2) == 0) { //key2
HAL_Delay(10);
if(Press(KB2) == 0){
key_value = 2;
while(Press(KB2) == 0);
}
}
else if(Press(KB3) == 0) { //key3
HAL_Delay(10);
if(Press(KB3) == 0){
key_value = 3;
while(Press(KB3) == 0);
}
}
else if(Press(KB4) == 0) { //key4
HAL_Delay(10);
if(Press(KB4) == 0){
key_value = 4;
while(Press(KB4) == 0);
}
}
return key_value;
}
四、KEY.it模块---按键通过中断的方式实现
1.key_it.h文件
#include "stm32g4xx_hal.h"
#define Press(x) (HAL_GPIO_ReadPin(x))
#define KB4 GPIOA, GPIO_PIN_0
#define KB1 GPIOB, GPIO_PIN_0
#define KB2 GPIOB, GPIO_PIN_1
#define KB3 GPIOB, GPIO_PIN_2
//¿ÉÐÞ¸Ä
#define SHORT_DELAY 2 // ¶Ì°´ÑÓʱ
#define LONG_DELAY 80 // ³¤°´ÑÓʱ
#define CONTINUE_DELAY 10 // Á¬Ðø´¥·¢ÑÓʱ
typedef struct {
uint8_t scan_flag; //°´¼ü¶¨Ê±É¨Ãè±êʶ
uint16_t last_key; //Éϴΰ´¼üÖµ
uint8_t pressed; //°´¼üÊÇ·ñÒÑ°´Ï±êʶ
uint16_t cnt; //°´¼ü°´ÏÂʱ¼ä³¤¶Ì¼ÆʱÆ÷
}KeyScan_t;
uint8_t Key_Scan(void);
2.key_it.c文件
#include "key_it.h"
// ¼ì²âÄĸö°´¼ü°´ÏÂ
uint8_t Key_Scan(void){
if(Press(KB1) == 0){
return 1;
}
else if(Press(KB2) == 0){
return 2;
}
else if(Press(KB3) == 0){
return 3;
}
else if(Press(KB4) == 0){
return 4;
}
return 0;
}
五、主函数---主要是KEY模块有所变动
注意:LCD初始化放在LED初始化前边
1.key_it.h文件
#include "stm32g4xx_hal.h"
#define Press(x) (HAL_GPIO_ReadPin(x))
#define KB4 GPIOA, GPIO_PIN_0
#define KB1 GPIOB, GPIO_PIN_0
#define KB2 GPIOB, GPIO_PIN_1
#define KB3 GPIOB, GPIO_PIN_2
//¿ÉÐÞ¸Ä
#define SHORT_DELAY 2 // ¶Ì°´ÑÓʱ
#define LONG_DELAY 80 // ³¤°´ÑÓʱ
#define CONTINUE_DELAY 10 // Á¬Ðø´¥·¢ÑÓʱ
typedef struct {
uint8_t scan_flag; //°´¼ü¶¨Ê±É¨Ãè±êʶ
uint16_t last_key; //Éϴΰ´¼üÖµ
uint8_t pressed; //°´¼üÊÇ·ñÒÑ°´Ï±êʶ
uint16_t cnt; //°´¼ü°´ÏÂʱ¼ä³¤¶Ì¼ÆʱÆ÷
}KeyScan_t;
uint8_t Key_Scan(void);
2.key_it.c文件
3.
#include "key_it.h"
// ¼ì²âÄĸö°´¼ü°´ÏÂ
uint8_t Key_Scan(void){
if(Press(KB1) == 0){
return 1;
}
else if(Press(KB2) == 0){
return 2;
}
else if(Press(KB3) == 0){
return 3;
}
else if(Press(KB4) == 0){
return 4;
}
return 0;
}
3.main.c文件中的Key_It_Pro()函数---里面有三种情况(短按、长按和持续按)
//Key processing function
void Key_It_Proc(void){
if(key.scan_flag == 1){
key.scan_flag = 0;
uint8_t cur_key = Key_Scan(); // »ñÈ¡µ±Ç°°´¼üÖµ
uint8_t key_down = cur_key & (cur_key ^ key.last_key); // ¼ì²âϽµÑØ£¬Ö»ÓеÚÒ»´Î°´¼ü°´ÏÂʱ²»µÈÓÚ0
uint8_t key_up = ~cur_key & (cur_key ^ key.last_key); // ¼ì²âÉÏÉýÑØ£¬±ØÐëÏÈÓа´¼ü°´Ï£¬ÔÙÊÍ·Åʱ²»µÈÓÚ0
if(key_down != 0){ // °´¼ü°´ÏÂʱ´¥·¢
key.pressed = 1; // °´Ï±êʶÖÃ1
key.cnt = 0; // ¼ÆʱÇå0
}
if(key_up != 0){ // °´¼üÊÍ·Åʱ´¥·¢
key.pressed = 0;
}
if(key.pressed == 1){ // °´¼ü´¦ÓÚ°´ÏÂ״̬
key.cnt++;
if(key.cnt == LONG_DELAY){ // ³¤°´
switch(cur_key){
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
default:
break;
}
}else if(key.cnt >= LONG_DELAY+CONTINUE_DELAY){ // ³ÖÐø³¤°´
switch(cur_key){
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
default:
break;
}
}
}else {
if(key.last_key != 0 && key.cnt >= SHORT_DELAY && key.cnt < LONG_DELAY){ //¶Ì°´
switch(key.last_key){ // ÓÉÓÚÕâ´Î°´¼üÒѾ̧Æ𣬼üֵΪNOKEY£¬ËùÒÔÖ»ÓÐÅжÏÉϴεļüÖµ
case 1:
Show_Flag++;
if(Show_Flag == 3)
Show_Flag = 1;
break;
case 2:
if(Show_Flag == 2)
{
CNBR_Price += 0.5f;
VNBR_Price += 0.5f;
}
break;
case 3:
if(Show_Flag == 2)
{
CNBR_Price -= 0.5f;
VNBR_Price -= 0.5f;
if(CNBR_Price < 0)
CNBR_Price = 0.0f;
if(VNBR_Price < 0)
VNBR_Price = 0.0f;
}
break;
case 4:
break;
default:
;
}
}
}
key.last_key = cur_key;
}
}
void Led_Proc(void)
{
if(IDEL_Size > 0)
LED_Ctrl(LED1, ON);
else
LED_Ctrl(LED1, OFF);
}
注意:如果只有短按的话还是用三的KEY模块的代码