本人刚不久参加了蓝桥杯电子赛嵌入式组,想要记录一下之前的学习成果,如有不正确的地方,欢迎大家交流与评论
目录
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
第一种情况:符合某一个条件之后,让某个灯亮,否则,灭,这是最简单的情况
第二种情况:符合某一个条件之后,让某个灯100ms的时间闪烁,否则灭
第三种情况:符合某一个条件之后,让某个灯100ms的时间闪烁,5s之后灭
试题题目
试题完整代码
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2024 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "stdio.h"
#include "string.h"
#include "i2c_hal.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void LED_Set(unsigned char ucled)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,ucled << 8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
u8 Key_Scan(void)
{
u8 keynum=0;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
keynum=1;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)
keynum=2;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)
keynum=3;
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
keynum=4;
return keynum;
}
#define SHOP 0 //商品购买界面
#define PRICE 1 //商品价格界面
#define REP 2 //库存信息界面
u8 LCD_JM = SHOP;
u8 LCD_Buffer[20];
u8 X=0,Y=0,Z=0;
double X_Price=1.0;
double Y_Price=1.0;
u16 X_rep=0;
u16 Y_rep=0;
u8 change_flag1=0;
u8 change_flag2=0;
u8 change_flag3=0;
u8 change_flag4=0;
u8 x=0;
u8 y=0;
u8 ucled=0;
uint32_t uwTick_LED1_Point=0;
uint32_t uwTick_LED2_Point=0;
u8 led1_flag=0;
u8 pwm_flag=0;
void LED_Proc(void)
{
//LED1
if(led1_flag==1)
{
if(uwTick - uwTick_LED1_Point<5000)
{
ucled|=0x01;
}
else{
ucled&=~0x01;
led1_flag=0;
}
}
//LED2
if(X_rep == 0 && Y_rep == 0)
{
if(uwTick - uwTick_LED2_Point >100)
{
uwTick_LED2_Point = uwTick;
ucled^=0x02;
}
}
else
{
ucled&=~0x02;
}
LED_Set(ucled);
}
void LCD_Proc(void)
{
//EEPROM
//测试
// write_eeprom(5,X_rep);
// HAL_Delay(10);
// write_eeprom(6,Y_rep);
// HAL_Delay(10);
// x=read_eeprom(5);
// y=read_eeprom(6);
// sprintf((char*)LCD_Buffer," x:%d ",x);
// LCD_DisplayStringLine(Line9,(unsigned char*)LCD_Buffer);
// sprintf((char*)LCD_Buffer," y:%d ",y);
// LCD_DisplayStringLine(Line8,(unsigned char*)LCD_Buffer);
//
X_rep = read_eeprom(0);
Y_rep = read_eeprom(1);
X_Price = read_eeprom(2)/10.0;
Y_Price = read_eeprom(3)/10.0;
if(LCD_JM == SHOP)//商品购买界面
{
sprintf((char*)LCD_Buffer," SHOP ");
LCD_DisplayStringLine(Line1,(unsigned char*)LCD_Buffer);
sprintf((char*)LCD_Buffer," X:%d ",X);
LCD_DisplayStringLine(Line3,(unsigned char*)LCD_Buffer);
sprintf((char*)LCD_Buffer," Y:%d ",Y);
LCD_DisplayStringLine(Line4,(unsigned char*)LCD_Buffer);
}
else if(LCD_JM == PRICE) //商品价格界面
{
sprintf((char*)LCD_Buffer," PRICE ");
LCD_DisplayStringLine(Line1,(unsigned char*)LCD_Buffer);
sprintf((char*)LCD_Buffer," X:%.1lf ",X_Price);
LCD_DisplayStringLine(Line3,(unsigned char*)LCD_Buffer);
sprintf((char*)LCD_Buffer," Y:%.1lf ",Y_Price);
LCD_DisplayStringLine(Line4,(unsigned char*)LCD_Buffer);
}
else if(LCD_JM == REP)库存信息界面
{
sprintf((char*)LCD_Buffer," REP ");
LCD_DisplayStringLine(Line1,(unsigned char*)LCD_Buffer);
sprintf((char*)LCD_Buffer," X:%d ",X_rep);
LCD_DisplayStringLine(Line3,(unsigned char*)LCD_Buffer);
sprintf((char*)LCD_Buffer," Y:%d ",Y_rep);
LCD_DisplayStringLine(Line4,(unsigned char*)LCD_Buffer);
}
}
u8 key_value,key_down,key_up,key_old;
uint32_t uwTick_key_point=0;
void Key_Proc(void)
{
if(uwTick-uwTick_key_point<50)return;
uwTick_key_point = uwTick;
key_value = Key_Scan();
key_down = key_value & (key_value ^ key_old);
key_up = ~ key_value & (key_value ^ key_old);
key_old = key_value;
if(key_down == 1)
{
LCD_JM = (LCD_JM+1)%3;
LCD_Clear(Black);
}
else if(key_down == 2)
{
if(LCD_JM == SHOP)
{
X++;
if(X > X_rep)
X=0;
}
else if(LCD_JM ==PRICE)
{
change_flag3=1;
X_Price +=0.1f;
if(X_Price>2.1f)
X_Price=1.0f;
}
else if(LCD_JM==REP)
{
change_flag1=1;
X_rep++;
}
}
else if(key_down == 3)
{
if(LCD_JM == SHOP)
{
Y++;
if(Y > Y_rep)
Y=0;
}
else if(LCD_JM ==PRICE)
{
change_flag4=1;
Y_Price +=0.1f;
if(Y_Price>2.1f)
Y_Price=1.0f;
}
else if(LCD_JM==REP)
{
change_flag2=1;
Y_rep++;
}
}
else if(key_down == 4) //确认按键
{
if(LCD_JM == SHOP)
{
pwm_flag=1;
led1_flag=1;
uwTick_LED1_Point = uwTick;
printf("X:%d,Y:%d,Z:%.1lf",X,Y,(X*X_Price)+(Y*Y_Price));
change_flag2=1;
change_flag1=1;
X_rep=X_rep-X;
Y_rep=Y_rep-Y;
X=0;
Y=0;
}
}
}
void E2PROM_Proc(void)
{
if(change_flag1==1)
{
write_eeprom(0,X_rep);
HAL_Delay(10);
change_flag1=0;
}
if(change_flag2==1)
{
write_eeprom(1,Y_rep);
HAL_Delay(10);
change_flag2=0;
}
if(change_flag3==1)
{
write_eeprom(2,(int)(X_Price*10));
HAL_Delay(10);
change_flag3=0;
}
if(change_flag4==1)
{
write_eeprom(3,(int)(Y_Price*10));
HAL_Delay(10);
change_flag4=0;
}
}
u8 res_buf[2];
u8 rev_buf[2];
u8 rx_index=0;
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xfff);
return ch;
}
void RX_Proc(void)
{
if(rx_index==1)
{
if(res_buf[0] == '?')
{
printf("X:%.1lf,Y:%.1lf",X_Price,Y_Price);
}
rx_index=0;
memset(res_buf,'\0',sizeof(res_buf));
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
res_buf[rx_index++]=rev_buf[0];
RX_Proc();
HAL_UART_Receive_IT(&huart1,rev_buf,1);
}
void PWM_Proc(void)
{
if(pwm_flag==1)
{
pwm_flag=0;
TIM2->ARR = 1000000/2000;
TIM2->CCR2 = (1000000/2000)*0.3;
}
else{
TIM2->ARR = 1000000/2000;
TIM2->CCR2 = (1000000/2000)*0.05;
}
}
/* 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();
MX_USART1_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
LCD_Init();
I2CInit();
HAL_UART_Receive_IT(&huart1,rev_buf,1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
LED_Set(0X00);
while (1)
{
E2PROM_Proc();
LCD_Proc();
Key_Proc();
LED_Proc();
PWM_Proc();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
RCC_OscInitStruct.PLL.PLLN = 20;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
由于该试题使用到了EEPROM(掉电不丢失存储器),所以加入了i2c_hal.c/.h的文件,并且手写可以直接往EEPROM写数据的函数,和从EEPROM中读数据的函数,这是模板记住就行,地址就是0-255,都可以,value值的话一定要是整形
需要注意的是,write_eeprom()之后一定要延时再read_eeprom()或者write_eeprom(),不能连续写读,或者是写写,否则你得到的数据就会有问题,写入的数据也有可能有问题
//eepromд void write_eeprom(unsigned char addr,unsigned char value) { I2CStart(); I2CSendByte(0xa0); I2CWaitAck(); I2CSendByte(addr); I2CWaitAck(); I2CSendByte(value); I2CWaitAck(); I2CStop(); delay1(500); } unsigned char read_eeprom(unsigned char addr) { unsigned char value=0; I2CStart(); I2CSendByte(0xa0); I2CWaitAck(); I2CSendByte(addr); I2CWaitAck(); I2CStart(); I2CSendByte(0xa1); I2CWaitAck(); value=I2CReceiveByte(); I2CSendNotAck(); I2CWaitAck(); I2CStop(); delay1(500); return value; }
代码之底层函数
void LED_Set(u8 ucled)
void LED_Set(unsigned char ucled) { HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC,ucled << 8,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); }
void KEY_Scan(void)
u8 Key_Scan(void) { u8 keynum=0; if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) keynum=1; if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) keynum=2; if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) keynum=3; if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) keynum=4; return keynum; }
int fputc(int ch,FILE *f)
int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xfff); return ch; }
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { res_buf[rx_index++]=rev_buf[0]; RX_Proc(); HAL_UART_Receive_IT(&huart1,rev_buf,1); }
代码之基本功能函数
void LCD_Proc(void)
void LCD_Proc(void) { //EEPROM //测试 // write_eeprom(5,X_rep); // HAL_Delay(10); // write_eeprom(6,Y_rep); // HAL_Delay(10); // x=read_eeprom(5); // y=read_eeprom(6); // sprintf((char*)LCD_Buffer," x:%d ",x); // LCD_DisplayStringLine(Line9,(unsigned char*)LCD_Buffer); // sprintf((char*)LCD_Buffer," y:%d ",y); // LCD_DisplayStringLine(Line8,(unsigned char*)LCD_Buffer); // X_rep = read_eeprom(0); Y_rep = read_eeprom(1); X_Price = read_eeprom(2)/10.0; Y_Price = read_eeprom(3)/10.0; if(LCD_JM == SHOP)//商品购买界面 { sprintf((char*)LCD_Buffer," SHOP "); LCD_DisplayStringLine(Line1,(unsigned char*)LCD_Buffer); sprintf((char*)LCD_Buffer," X:%d ",X); LCD_DisplayStringLine(Line3,(unsigned char*)LCD_Buffer); sprintf((char*)LCD_Buffer," Y:%d ",Y); LCD_DisplayStringLine(Line4,(unsigned char*)LCD_Buffer); } else if(LCD_JM == PRICE) //商品价格界面 { sprintf((char*)LCD_Buffer," PRICE "); LCD_DisplayStringLine(Line1,(unsigned char*)LCD_Buffer); sprintf((char*)LCD_Buffer," X:%.1lf ",X_Price); LCD_DisplayStringLine(Line3,(unsigned char*)LCD_Buffer); sprintf((char*)LCD_Buffer," Y:%.1lf ",Y_Price); LCD_DisplayStringLine(Line4,(unsigned char*)LCD_Buffer); } else if(LCD_JM == REP)库存信息界面 { sprintf((char*)LCD_Buffer," REP "); LCD_DisplayStringLine(Line1,(unsigned char*)LCD_Buffer); sprintf((char*)LCD_Buffer," X:%d ",X_rep); LCD_DisplayStringLine(Line3,(unsigned char*)LCD_Buffer); sprintf((char*)LCD_Buffer," Y:%d ",Y_rep); LCD_DisplayStringLine(Line4,(unsigned char*)LCD_Buffer); } }
void Key_Proc(void)
u8 key_value,key_down,key_up,key_old; uint32_t uwTick_key_point=0; void Key_Proc(void) { if(uwTick-uwTick_key_point<50)return; uwTick_key_point = uwTick; key_value = Key_Scan(); key_down = key_value & (key_value ^ key_old); key_up = ~ key_value & (key_value ^ key_old); key_old = key_value; if(key_down == 1) { LCD_JM = (LCD_JM+1)%3; LCD_Clear(Black); } else if(key_down == 2) { if(LCD_JM == SHOP) { X++; if(X > X_rep) X=0; } else if(LCD_JM ==PRICE) { change_flag3=1; X_Price +=0.1f; if(X_Price>2.1f) X_Price=1.0f; } else if(LCD_JM==REP) { change_flag1=1; X_rep++; } } else if(key_down == 3) { if(LCD_JM == SHOP) { Y++; if(Y > Y_rep) Y=0; } else if(LCD_JM ==PRICE) { change_flag4=1; Y_Price +=0.1f; if(Y_Price>2.1f) Y_Price=1.0f; } else if(LCD_JM==REP) { change_flag2=1; Y_rep++; } } else if(key_down == 4) //确认按键 { if(LCD_JM == SHOP) { pwm_flag=1; led1_flag=1; uwTick_LED1_Point = uwTick; printf("X:%d,Y:%d,Z:%.1lf",X,Y,(X*X_Price)+(Y*Y_Price)); change_flag2=1; change_flag1=1; X_rep=X_rep-X; Y_rep=Y_rep-Y; X=0; Y=0; } } }
void LED_Proc(void)
void LED_Proc(void) { //LED1 if(led1_flag==1) { if(uwTick - uwTick_LED1_Point<5000) { ucled|=0x01; } else{ ucled&=~0x01; led1_flag=0; } } //LED2 if(X_rep == 0 && Y_rep == 0) { if(uwTick - uwTick_LED2_Point >100) { uwTick_LED2_Point = uwTick; ucled^=0x02; } } else { ucled&=~0x02; } LED_Set(ucled); }
代码之复杂功能函数
void E2PROM_Proc(void)
void E2PROM_Proc(void) { if(change_flag1==1) { write_eeprom(0,X_rep); HAL_Delay(10); change_flag1=0; } if(change_flag2==1) { write_eeprom(1,Y_rep); HAL_Delay(10); change_flag2=0; } if(change_flag3==1) { write_eeprom(2,(int)(X_Price*10)); HAL_Delay(10); change_flag3=0; } if(change_flag4==1) { write_eeprom(3,(int)(Y_Price*10)); HAL_Delay(10); change_flag4=0; } }
void RX_Proc(void)
void RX_Proc(void) { if(rx_index==1) { if(res_buf[0] == '?') { printf("X:%.1lf,Y:%.1lf",X_Price,Y_Price); } rx_index=0; memset(res_buf,'\0',sizeof(res_buf)); } }
void PWM_Proc(void)
void PWM_Proc(void) { if(pwm_flag==1) { pwm_flag=0; TIM2->ARR = 1000000/2000; TIM2->CCR2 = (1000000/2000)*0.3; } else{ TIM2->ARR = 1000000/2000; TIM2->CCR2 = (1000000/2000)*0.05; } }
总结:本次的模拟并没有什么难度,只要将对应的模板记住就好,然后唯一需要注意的地方就是关于调用write_eeprom()之后要进行延时,出现的错误通常都是读出来的数值为255
关于LED灯的小技巧
在众多的试题中,关于LED灯的考核通常情况下就是四种,目前我做过的试题就是这四种
1.符合某一个条件之后,让某个灯亮,否则,灭
2.符合某一个条件之后,让某个灯100ms的时间闪烁,否则灭
3.符合某一个条件之后,让某个灯100ms的时间闪烁,5s之后灭
4.符合某一个条件之后,让某一个灯亮5s,然后灭
首先我们对这两行代码进行剖析以下
void LED_Set(unsigned char ucled)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,ucled << 8,GPIO_PIN_RESET);
//加入这两行代码是由于LED灯和LCD显示屏共用了一些引脚,为了避免互相影响,
//所以写下下面这两行代码,PD2是关于锁存器的知识点,暂不讲解
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
首先我们要知道的就是LED1-8对应的引脚PC8-PC15
先了解一下这个函数HAL_GPIO_WritePin(GPIOC,ucled << 8,GPIO_PIN_RESET);
ucled代表的就是某个引脚,比如我想要LED1亮,
那么正常情况下,我应该这样写HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
相当于 HAL_GPIO_WritePin(GPIOC,0x0100,GPIO_PIN_RESET);
LED2亮
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
相当于 HAL_GPIO_WritePin(GPIOC,0x0200,GPIO_PIN_RESET);
LED3亮
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);
相当于 HAL_GPIO_WritePin(GPIOC,0x0400,GPIO_PIN_RESET);
就这样依次亮
.......
LED8亮
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);
相当于 HAL_GPIO_WritePin(GPIOC,0x8000,GPIO_PIN_RESET);
LED1 0X0100 ----pc8
LED2 0X0200 -----PC9
LED3 0X0400 -----PC10
....
LED8 0X80 -----PC15
相信大家已经看出来了这两这之间的关系
只要我填入对应的0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,就对应LED1-LED8(这是使用二进制的写法,8421)
但是由于0X0100是16进制的高位,所以,要对传入的参数进行左移8位,0x01<<8就等于0x0100,就对应了LED1
HAL_GPIO_WritePin(GPIOC,ucled << 8,GPIO_PIN_RESET);
以上是对基础函数的操作与理解
接下来就是对于LED的控制
在这之前,让我们先了解以下以下三个函数
LED |=0X01;(置一操作)
LED &=~0X01;(置零操作)
LED ^=0X01;(反转操作)
第一种情况:符合某一个条件之后,让某个灯亮,否则,灭,这是最简单的情况
if(flag1 == 1) { ucled |=0x01;//如果符合情况,就LED1亮 } else { ucled&=~0x01;//否则就是灭; }
第二种情况:符合某一个条件之后,让某个灯100ms的时间闪烁,否则灭
uint32_t uwTick_point_LED2=0; //这是系统滴答计数器的标志位 if(falg2==1) //如果符合条件 { //第一次一定会进入这个条件,因为uwTick是系统计数器,数值很大,uwTick_point_LED2=0; if(uwTick - uwTick_point_LED2>100) { uwTick_point_LED2 = uwTick ; //表示重新计数 ucled ^=0x02; //LED2亮灭闪烁,周期100ms } } else { ucled &=~0x02; }
第三种情况:符合某一个条件之后,让某个灯100ms的时间闪烁,5s之后灭
uint32_t uwTick_point_LED3=0; //这是系统滴答计数器的标志位 u8 cnt=0; if(falg3==1) //如果符合条件 { //第一次一定会进入这个条件,因为uwTick是系统计数器,数值很大,uwTick_point_LED2=0; if(uwTick - uwTick_point_LED3>100) { uwTick_point_LED3 = uwTick ; //表示重新计数 ucled ^=0x04; //LED3亮灭闪烁,周期100ms cnt++; } if(cnt>50)//说明计数50次100MS,就是说5S过去了 { ucled &=~0x04; //LED3灭 falg3=0; cnt=0; } } else { ucled &=~0x02; }
第四种情况:符合某一个条件之后,让某一个灯亮5s,然后灭
假若某个条件符合之后,此时,要让LED4亮了,那么在那个位置 falg4=1; uwTick_point_LED4 = uwTick ; uint32_t uwTick_point_LED4=0; //这是系统滴答计数器的标志位 if(falg4==1) //如果符合条件 { if(uwTick - uwTick_point_LED4<5000) //在计数的5S内 { //表示重新计数 ucled |=0x08; //LED4亮 } else//在计数的5S外 { //超过5s之后 ucled &=~0x08; //LED4灭 falg4=0;//注意使用标志位之后要置位,给下一次用 } } else { ucled &=~0x08; }