一、GPIO控制灯亮
- 原理图绘制
①
点“p”添加原件,有led灯和按键
②
添加led在PA1和PA11引脚上,这里led 的正极接了电源,所以这里只有引脚输出低电平时,灯才会点亮。
③
2.代码编写
①创建其他c文件的文件夹
在代码文件中新增一个文件夹“Hardware”,并添加到工程中,
右击绿色高光处,选择另外一个绿色高光处,点红色高光处,输入“Hardware”,点击ok
随后再按下面操作
②在Hardware文件夹下,创建led.c的文件,以便封装点亮led 的函数
同样创建.h文件
③
给LED.c添加头文件,给LED.h添加头文件对于LED.c,首先对它进行led的初始化,即初始化时钟,初始化端口,然后添加灯亮的指令函数
#include "stm32f10x.h" // Device header
void Led_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_1);//默认高电平,熄灭
}
void LED1_GO(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);//低电平,点亮
}
void LED1_OFF(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
在.h文件添加.c文件中的函数名
#ifndef __LED_H
#define __LED_H
void Led_Init(void);
void LED1_GO(void);
void LED1_OFF(void);
#endif
//在#endif后面要空一行
在main函数添加led的.h文件
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
int main(void)
{
//2忘记初始化灯了
Led_Init();
while (1)
{
LED1_GO();
Delay_ms(100);
LED1_OFF();
Delay_ms(100);
LED1_GO();
Delay_ms(100);
LED1_OFF();
Delay_ms(700);
}
}
④写入.hex文件
双击芯片
运行即可
错误汇总
1.
这里要写8M才能正常闪烁
2.在main函数中,忘记写入初始化led灯的函数了
二、按键控制led灯亮
需求:①按一下常亮,再按一下熄灭(led1)②按一下闪烁几下后常亮(led2)
1.原理图绘制:
按键接了地,所以在引脚为按下后,引脚为低电平,所以需要引脚读取电平信号判断是否按下,即按下,引脚电平为低,读取后,可进行判断,判断为低电平(按下状态),则点亮led灯
2.逻辑设计
创建一个检测按键的函数,如果按下①号按键返回给亮灯函数1,如果按下②号按键,返回给亮灯函数2;亮灯函数设置一个参数,如果检测传入的参数是多少;
参数为1,是对led1灯进行操作,先检测led1灯的状态(设置了一个led1灯的状态值,点亮为1,熄灭为0),如果为熄灭状态,就点亮然后置状态为1.
参数为2,调用led.c中的led闪烁函数,然后led闪烁函数让led保持常亮
3.代码编写
编辑Key的.c和.h文件
查看gpio的c文件
可以看到它的用法,是读取输出口的数据bit,如果在输出模式下,想看一下输出了什么,就可以用这个函数。
那么key.c现在需要使用
这个函数
主要代码如下
Key.c
//检测是否按下函数,供main调用
uint8_t Key_GetVal(void)
{
uint8_t key_data_1 = 0;
uint8_t led_status = 0;//默认灯熄灭
//按键开关led
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)//代表板子按下,低电平
{
//按键刚按下时,会有抖动,所以需要消抖
Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);
//如果按键一直按下不放,就一直卡在这里
Delay_ms(20);
key_data_1 = 1;
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5) == 0)//第2个按钮被按下,传递不同参数
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5) == 0);
Delay_ms(20);
key_data_1 = 2;
}
return key_data_1;
}
LED.c
void LED2_Blink(void)
{
for(int i =0 ; i<5;i++){
GPIO_ResetBits(GPIOA,GPIO_Pin_11);//低电平,点亮
Delay_ms(10000);
GPIO_SetBits(GPIOA,GPIO_Pin_11);
Delay_ms(10000);
GPIO_ResetBits(GPIOA,GPIO_Pin_11);//低电平,点亮
}
}
void LED_SET(uint8_t led_num)//led_num=1时点亮led1灯
{
if(led_num==1){
if(led1_status == 0){//led1_status为全局变量,检测此时灯是亮的还是熄灭状态,熄灭状态的话,按下按钮就要点亮
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
led1_status = 1;
Delay_ms(200);
}
else
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);//高电平,为灭
led1_status = 0;
Delay_ms(200);
}
}
if(led_num == 2){
LED2_Blink();
}
}
main.c
int main(void)
{
//test2:按键点亮led
Led_Init();
Key_Init();
while(1)
{
LED_SET(Key_GetVal());
}
}