按键
按键是常用的输入设备,按下导通,松手断开。由于是采用机械式弹簧片进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动。
传感器
传感器原件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外接的模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较值进行二值化即可得到数字电压输出。
C语言数据类型
关键字 | 位数 | 表示范围 | stdint关键字 | ST关键字 |
char | 8 | -128 ~ 127 | int8_t | s8 |
unsigned char | 8 | 0 ~ 255 | uint8_t | u8 |
short | 16 | -32768 ~ 32767 | int16_t | s16 |
unsigned short | 16 | 0 ~ 65535 | uint16_t | u16 |
int | 32 | -2147483648 ~ 2147483647 | int32_t | s32 |
unsigned int | 32 | 0 ~ 4294967295 | uint32_t | u32 |
long | 32 | -2147483648 ~ 2147483647 | ||
unsigned long | 32 | 0 ~ 4294967295 | ||
long long | 64 | -(2^64)/2 ~ (2^64)/2-1 | int64_t | |
unsigned long long | 64 | 0 ~ (2^64)-1 | uint64_t | |
float | 32 | -3.4e38 ~ 3.4e38 | ||
double | 64 | -1.7e308 ~ 1.7e308 |
在进行stm32的开发时,常用的是第四列的一些数据。
C语言宏定义
#define
C语言typedef
其和宏定义差不多,是将一个比较长的变量类型名换个名字,便于使用。
typedef unsigned char uint8_t;
和宏定义不一样的是,typedef的新名字在后面。
C语言结构体
其用途是数据打包,不同类型变量的集合。
用于结构体的变量:
struct{char x;int y;float z;} StructName;
因为结构体变量类型较长,所以通常用typedef更改变量类型名
C语言枚举
关键字:enum
其用途是定义一个取值范围受限制的整型变量取值范围;是宏定义的结合。因为枚举变量类型较长,所以通常用typedef更改变量类型名
enum{FALSE=0,TRUE=1}EnumName;
按键控制LED
在文件夹中创建Hardware目录,分别创建.c和.h文件。封装LED和按键的函数,在文件中.c文件是函数的主体内容.h是函数的声明文件。创建好各个模块的初始化文件。
按照之前的文件,创建好LED的初始化,接下来就准备进行按键文件的初始化了。
和初始化LED灯一样,要使GPIOB口时钟使能,然后按照结构体配置pin口的输入输出模式:
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
这里的输出模式,选择的是上拉输出,悬空默认高电平。
再对按键输入读取进行函数的编写:
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0)
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0);
Delay_ms(20);
KeyNum = 1;
}
return KeyNum;
}
这里选用的是ReadInputDataBit()函数,这个函数是用来读取输入数据寄存器某一个端口的输入值的。
还有相应的几个读取输入端口数据的函数需要了解:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//读取输入数据寄存器某一个端口的输入值的,返回是一个无符号的char,返回的是高低电平
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
//读取整个数据寄存器,返回一个16位数据,每一位代表一个端口值
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//读取输出数据寄存器的某一个位,一般用于输出模式下,看一下自己输出的是什么
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
//读取整个输出寄存器,意义同上
然后进行按键输入读取的操作:
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0)
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0);
Delay_ms(20);
KeyNum = 1;
}
return Keynum;
}
要提到的是,需要加上延时函数进行消抖。
在主main函数中,首先对LED和Key进行初始化,最后利用判断语句根据按键的动作实现LED灯的亮灭。主函数如下:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
uint8_t KeyNum;
int main(void)
{
LED_Init();
Key_Init();
while(1)
{
KeyNum = Key_GetNum();
if (KeyNum == 1)
{
LED1_Turn();
}
if (KeyNum == 2)
{
LED2_Turn();
}
}
}
还有可以利用GPIO_ReadOutputDataBit()读取输出端口的输出电平,加上判断条件,实现按键控制亮灭。
光敏传感器控制蜂鸣器
更改LED的一些相关函数即可,利用光敏电阻变化的IO口的电平变化进行读取,将其作为LED灯的一个亮灭判断条件。以后可根据上述代码修改实现,所以不再赘述。