目录
一.前言
材料:STM32F103VET6开发板,TS90A舵机。
写此文章作为学习笔记,如有不足请多指教。
二.主要知识点
1.按键
我所用的开发板上有两个按键,分别是K1和K2。要使用它们,首先需要搞清楚它们所在的位置。所以第一步就是查阅配套的原理图。
![](https://img-blog.csdnimg.cn/a0debd0ecc94430ebc18e2e609f9fbd4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6IOn6L2m,size_20,color_FFFFFF,t_70,g_se,x_16)
像是这样,从图1中可以看出K1对应的是PA0,K2对应的是PC13。
那么我们就要使能GPIOA和GPIOC,所以下一步就是查阅参考手册。
![](https://img-blog.csdnimg.cn/6c8c1e53216c4e5ea4f79252614be68e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6IOn6L2m,size_20,color_FFFFFF,t_70,g_se,x_16)
发现两者都是挂在APB2上,所以我们需要写下如下代码:
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA //可不写宏定义
#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC //将下方的变量名换成对应的就行
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);
RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK, ENABLE);
接着初始化PA0和PC13。
#define KEY1_GPIO_PIN GPIO_Pin_0
#define KEY1_GPIO_PORT GPIOA
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct);
#define KEY2_GPIO_PIN GPIO_Pin_13
#define KEY2_GPIO_PORT GPIOC
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct);
准备工作结束,最后写下按键扫描和松手检测就可以了。
#define KEY_ON 1
#define KEY_OFF 0
uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON)
{
while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON); //松手检测
return KEY_ON;
}
else return KEY_OFF;
}
这边解释一下Key_Scan函数:
(1)结合图1,当按键按下时对应引脚将会是高电平,即1,所以是KEY_ON,反之为0,即KEY_OF;
(2)GPIO_ReadInputDataBit返还高电平(1)或是低电平(0);
(3)当按键按下后送手,就跳出了while循环,返还KEY_ON,说明按键被按了一次。所以如果你一直按着不放,那就一直在while循环中,程序是不会进行下一个操作的。
2.按键代码
(1)key.h
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"
#define KEY1_GPIO_PIN GPIO_Pin_0
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA
#define KEY2_GPIO_PIN GPIO_Pin_13
#define KEY2_GPIO_PORT GPIOC
#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC
#define KEY_ON 1
#define KEY_OFF 0
void KEY1_GPIO_Config(void);
void KEY2_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
#endif /* __KEY_H */
(2)key.c
#include "key.h"
void KEY1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct);
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);
}
void KEY2_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct);
RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK, ENABLE);
}
uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON)
{
//松手检测
while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON);
return KEY_ON;
}
else return KEY_OFF;
}
3.舵机
所用代码都在上一篇文章STM32F1—舵机—PWM中,这里就不赘述了。
4.main.c
#include "stm32f10x.h"
#include "ts90a.h"
#include "delay.h"
#include "key.h"
int main(void)
{
PWM_TIM3CH2RE_Config();
KEY1_GPIO_Config();
KEY2_GPIO_Config();
while(1)
{
if(Key_Scan(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON)
{
TIM_SetCompare2(TIM3,195 - 90/9);
delay_ms(1000);
}
if(Key_Scan(KEY2_GPIO_PORT, KEY2_GPIO_PIN) == KEY_ON)
{
TIM_SetCompare2(TIM3,195 - 180/9);
delay_ms(1000);
}
}
}
三.感想
我所使用的两个开关,一个使舵机转到90°位置,另一个使舵机转到180°位置。
这个功能的目的是在寝室床上就可以开关寝室的灯了(灯的开关在门口)。只要线够长,完全不是梦想!待我多学学,下次搞一个无线的!