STM32-Day06(单片机C语言补充&按键控制小灯)
3.3.4 C语言知识补充
C语言数据类型:

注意:在51单片机中int是占16位的,但是在STM32中int是占32位的,如果要用16位的数据,要用short来表示
因为编程习惯以及各种原因,C语言和ST给左边的变量换了名字,换为了右边的名字,C语言提供了stdint这个头文件,使用了新的名字,新版本库函数使用stdint这一列的关键字命名即可
C语言宏定义:
关键字:#define
用途:用一个字符串代替一个数字,便于理解,防止出错;提取程序中经常出现的参数,便于快速修改
定义宏定义:#define ABC 12345
引用宏定义:int a = ABC;
C语言typedef:
关键字:typedef
用途:讲一个比较长的变量类型名换个名字,便于使用
定义typedef:typedef unsigned char unit8_t;
引用typedef:unit8_t a;等效于unsigned char a;
C语言结构体
关键字:struct
用途:数据打包,不同类型变量的集合
定义结构体变量:struct{char x;int y;float z;}StructName;因为结构体变量类型较长,所以通常用typedef更改变量类型名:typedef struct {char x……} StructName_t;因此GPIO当时定义结构体也是库函数中打包好了typedef的功能,在main.c中直接使用即可
引用结构体成员:
StructName.x = 'A';
StructName.y = 66;
或pStructName->x = ‘A’;pStructName为结构体的地址
C语言枚举
关键字:enum
用途:定义一个取值受限制的整型变量,用于限制变量的取值范围;枚举同时也是一个宏定义的集合
定义枚举变量:enum{FALSE = 0,TRUE = 1} EnumName;
因为枚举变量类型较长,所以通常用typedef更改变量类型名
引用枚举成员:EnumName = FALSE;
3.3.5 按键控制LED
接线图:

需要将按键驱动控制代码单独进行封装,新建一个文件夹-HardWare,用来存放硬件驱动

上图是添加了LED驱动的HardWare文件夹
LCD.c文件:
#include "stm32f10x.h" // Device header
void LED_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);
}
void LED1_On(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
void LED1_Off(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
void LED2_On(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
void LED2_Off(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
接下来完成按键读取的文件
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
需要用到以上四个GPIO.h中的函数
GPIO_ReadInputDataBit:用于读取输入数据寄存器某一个端口的输入值,参数是指定端口,返回值是uint8_t,代表这个端口的高低电平
GPIO_ReadInputData:用于读取整个输入数据寄存器,返回值是一个十六位的数据
GPIO_ReadOutputDataBit:用来读取输出数据寄存器的某一个位,其并不是用来读取端口的输入数据,这个函数一般用于输出模式下,用来看一下自己输出的是什么
GPIO_ReadOutputData:用于读取整个输出寄存器
Key.c文件:
#include "stm32f10x.h" // Device header
#include "Delay.h"
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_11;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
{
Delay_ms(20);//消除按下抖动
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);//判断松手的情况
Delay_ms(20);//消除松开抖动
KeyNum = 1;
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0)
{
Delay_ms(20);//消除按下抖动
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0);//判断松手的情况
Delay_ms(20);//消除松开抖动
KeyNum = 2;
}
return KeyNum;
}
同时需要用到LED反转函数,在LED.c中添加即可
void LED1_Turn(void)
{
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) == 0)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
}
void LED2_Turn(void)
{
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2) == 0)
{
GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
}
完整按键控制小灯主函数代码如图所示:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
uint8_t KeyNum;//存键码的返回值
int main()
{
LED_Init();
Key_Init();
while(1)
{
KeyNum = Key_GetNum();
if(KeyNum ==1)
{
LED1_Turn();
}
if(KeyNum ==2)
{
LED2_Turn();
}
}
}
更多推荐

所有评论(0)