目录
原理图
R1是限流电阻
PB5引脚 输出低电平0,相当于接地了,LED导通->发光二极管发光
不同的发光二极管压降也不同
发光二极管包括可见光、不可见光、激光等不同类型,这里只用到可见光发光二极管。发光二极管的发光颜色决定于所用材料,目前有红、绿、黄、橙等色,可以支撑各种形状,如长方形、圆形等。
发光二极管也具有单向导电性。只有外加的正向电压使得正向电流足够大时才发光,它的开启电压比普通二极管大,红色的在1.6~1.8V之间,绿色的约为2V,正向电流愈大,发光愈强。使用时,应特别注意不要超过最大功耗、最大正向电流和反向击穿电压等极限参数。
发光二极管因驱动电压低、功耗小、寿命长、可靠性高等优点广泛应用于显示电路中。目前已有高强度、颜色可变的新产品,用于装饰、显示屏、汽车尾灯、照明,等等。
根据编程习惯,先创建LED.c LED.h文件
LED.c 存放在 Public\src文件中
LED.h 存放在 Public\inc文件中
标准库代码
#include "LED.h"
void LED_Init(void)
{
//点亮PB5
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure; //初始化结构体
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB, GPIO_Pin_5); //置低电平
}
void LED_onoff(void)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_5);//低电平,亮
// GPIO_SetBits(GPIOB, GPIO_Pin_5);//低电平,灭
}
函数说明
HAL库 --- 硬件抽象层
先掌握两个GPIO输出的HAL库函数
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
GPIO电平输出HAL库函数
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
理解三个参数:
1 - GPIOx:目标引脚的端口号
2 - GPIO_Pin:目标引脚的引脚号
3 - PinState:高电平GPIO_PIN_SET;低电平GPIO_PIN_RESET
例:将PC13引脚输出高电平。
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
例:将PC13引脚输出低电平。
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
GPIO电平翻转HAL库函数
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
例:将PC13引脚输出电平翻转。
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); //翻转PC13
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); //翻转PA0
PC13引脚是STM32F103C8T6最小系统上靠近电源指示灯的另一个LED
不用接其他外设就可以看到现象
学习视频:
【【小蜜蜂笔记】基于STM32CubeMX的嵌入式开发基础教程】 STM32的按键开发基础_哔哩哔哩_bilibili
GPIO电平输入HAL库函数
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
例:判断PA5引脚的输入信号,若位低电平,则...
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET) //PA5按键 = 0 {}
用按键控制LED灯的开关
CubeMx时钟树的配置:
按键
然后写一个很Low的阻塞性延时按键消抖的函数
unsigned char Key_GetNum(void)
{
unsigned char KeyNum = 0;
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET) //PB1按键 = 0
{
HAL_Delay(20);
while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET);
HAL_Delay(20);
KeyNum = 1;
}
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET) //PB1按键 = 0
{
HAL_Delay(20);
while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET);
HAL_Delay(20);
KeyNum = 2;
}
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET) //PB1按键 = 0
{
HAL_Delay(20);
while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET);
HAL_Delay(20);
KeyNum = 3;
}
return KeyNum;
}
在while(1)里判断是哪个按键按下,然后执行对应的电平翻转函数
KeyNumber = Key_GetNum();
if (KeyNumber == 1)
{
// HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); //翻转PC13
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
}
else if (KeyNumber == 2)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
}
else if (KeyNumber == 3)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); //翻转PC13
}
温馨提示:不要用中文命名工程的名字,CubeMx对中文的兼容不好,路径也不可以出现中文和空格,不然就会出现莫名其妙的报错
蓝桥杯嵌入式组点灯大师
LED控制函数
//函数调用,传入的形参,那一位给1哪一位就点亮,state=0x00就是全灭
void LED_Disp(uchar state)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All, GPIO_PIN_SET); //全部拉高
HAL_GPIO_WritePin(GPIOC, state<<8, GPIO_PIN_RESET); //state左移8位,就是PC8~PC15,正好是8个LED,低电平点亮
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET); //锁存器置高,使能
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET); //锁存器置低,失能
}
main函数
/**
* @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_TIM3_Init();
/* USER CODE BEGIN 2 */
LED_Disp(0x00); //LED初始化
LCD_Init(); //LCD初始化
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 *)" ");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//LED_Disp(0x01); //点亮第一个LED
//HAL_Delay(500);
//LED_Disp(0x00); //熄灭第一个LED
//HAL_Delay(500);
//LED左右流水
for (unsigned char i = 0; i < 8; i ++)
{
LED_Disp(0x01 << i);
HAL_Delay(100);
}
for (unsigned char i = 0; i < 8; i ++)
{
LED_Disp(0x80 >> i);
HAL_Delay(100);
}
//积累流水灯,向左
for(unsigned char i = 0; i < 8; i ++)
{
for (unsigned char j = 0; j < 8-i; j++)
{
LED_display = 0x01 << j;
LED_display |= ( 0xFF << (8-i) );
LED_Disp(LED_display);
HAL_Delay(200);
}
}
//LED左右流水
for (unsigned char i = 0; i < 8; i ++)
{
LED_Disp(0x01 << i);
HAL_Delay(100);
}
for (unsigned char i = 0; i < 8; i ++)
{
LED_Disp(0x80 >> i);
HAL_Delay(100);
}
//积累流水灯,向右
for(unsigned char i = 0; i < 8; i ++)
{
for (unsigned char j = 0; j < 8-i; j++)
{
LED_display = 0x80 >> j;
LED_display |= ( 0xFF >> (8-i) );
LED_Disp(LED_display);
HAL_Delay(200);
}
}
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
sprintf(LCD_Show_text, "Number:%d ", numLED);
LCD_DisplayStringLine(Line3, (uint8_t *)LCD_Show_text);
numLED++;
}
/* USER CODE END 3 */
}