Vamos a configurar dos botones y darle diferente funcionalidad a cada uno de ellos, con el objetivo de reforzar los conocimientos.
Para visualizar la funcionalidad del vamos a incluir una
variable de tipo entera que simplemente se verá afectada por los botones. En
caso de pulsar uno de los botones la variable aumentará su valor en uno y de
manera opuesta el otro botón restará uno al valor de la variable. Además se añaden unas condiciones que limitan a la variable a pertenecer entre el 1 y el 7.
Debemos entender primero con se configura físicamente nuestro pin GPIO. En el manual de referencia vamos a encontrar el diagrama
eléctrico básico de los pines GPIO.
Como podemos ver estos pines incluyen el circuito necesario.
Disponen tanto de una resistencia pull-up
como pull-down. Para identificarlas
se hace de manera intuitiva, la referencia es el punto medio que corresponde a
la señal IO del pin, luego la resistencia que está arriba conectada a la fuente
VDD es la resistencia pull-UP y la
que está conectada abajo a tierra es pull-DOWN.
Estas resistencias internar se activan mediante software y
solo se puede encontrar una de ella activada. Veremos cómo controlar estas
resistencias mediante software en este mismo tutorial más adelante.
El fabricante nos indica que la tensión máxima a la que se
debe conectar este pin IO es de máximo VDD + 0.3, en nuestro caso por lo tanto
sería de 3.6V (3.3V +0.3), pero de manera típica se debe conectar a 3.3V.
Por otro lado, existen los pines GPIO FT que corresponde a pone
denominados Five volts Tolerant, que
pueden soportar una tensión de 5V.
La ventaja de tener esta resistencia interna, tanto pull-up
como pull-down sobre todo la encontramos a la hora de diseñar hardware, estas
resistencias internas nos evitan la colocación de resistencias externas,
ahorrando tiempo de diseño, disminuyendo a la complejidad y ahorrando dinero,
tanto en material como en proceso de ensamblado.
Centrándonos en los GPIO base, los de 3.3V, la conexión mas
simple es conectar el botón en serie directamente a una fuente de 3.3V, sin
añadir ninguna resistencia extra ya que la resistencia interna hace todo el
trabajo. De esta manera estaremos utilizando la resistencia pull-down interna.
Y el microcontrolador estará leyendo en su estado estático o normal LOW, 0
binario o 0V. En el momento de pulsar el botón la corriente circulará por el
pin y en ese momento leerá HIGH, 1 binario o 3.3V.
Por otro lado, tenemos la opción de utilizar la resistencia interna pull-up que está conectada en
serie con la alimentación interna del microcontrolador VDD. De esta manera la
conexión mas normal sería conectar nuestro botón directamente a tierra. En este
caso nuestro microcontrolador detecta en esa entrada normalmente HIGH, 1 en
binario o 3.3V y en el momento de pulsar detectará LOW, 0 en binario o 0V.
Floating Input
Por último, tenemos la opción de floating input, en esta
opción ninguna de las resistencias internas del pin del microcontrolador estará
activadas. Y debemos ser nosotros los que añadimos las resistencias pull-up o
pull-down en cualquiera de los casos.
Es recomendable usar resistencia de resistencia de entre 1K
a 10K con el fin de minimizar la corriente y por tanto el consumo del
dispositivo.
CONEXIONES
El diagrama de conexiones es muy sencillo, simplemente necesitamos conectar uno de los lados de los botones a sus correspondientes pines, en este caso PB5 y PB6 y el otro lado a la fuente de 3.3V como se puede ver en el siguiente diagrama.![]() |
Diagrama de conexiones |
De igual manera que hemos visto cómo configurar un pin como
output podemos configurar un pin como tipo input. En este caso vamos a utilizar
la estructura GPIO_InitTypeDef que
nos permite configurar los pines de tipo GPIO.
GPIO_InitTypeDef GPIO_InitStruct_PB_B5;
GPIO_InitStruct_PB_B5.GPIO_Pin = GPIO_Pin_5;
A continuación, vamos
a indicar el modo en el que queremos que actúen las resistencias internas, como
hemos visto tenemos tres opciones:
- Pull-down
GPIO_InitStruct_PB_B5.GPIO_Mode = GPIO_Mode_IPD;
- Pull-up
GPIO_InitStruct_PB_B5.GPIO_Mode = GPIO_Mode_IPU;
- Floating
GPIO_InitStruct_PB_B5.GPIO_Mode = GPIO_Mode_IN_FLOATING;
Por último, inicializamos
el pin con la estructura de datos creados.
GPIO_Init(GPIOB,
&GPIO_InitStruct_PB_B5);
En este caso vamos a configurar nuestro pin GPIO como input pull-down. Para declarar ambos botones, por lo tanto:
GPIO_InitTypeDef GPIO_InitStruct_PB_B5;
GPIO_InitStruct_PB_B5.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct_PB_B5.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStruct_PB_B5);
GPIO_InitTypeDef GPIO_InitStruct_PB_B6;
GPIO_InitStruct_PB_B6.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct_PB_B6.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStruct_PB_B6);
Por último, para detectar
estas pulsaciones vamos a utilizar una función que acede al registro de del
estado del pin.
GPIO_ReadInputDataBit(GPIOB,
GPIO_Pin_5)
Esta función devuelve 0 y 1
dependiendo de estado del pin. De esta manera incluiremos esta función en una condición
if y podremos saber el estado del pin.
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5)){
//El botón está pulsado
}else{
//El botón no está pulsado
}
Por lo tanto, el código
completo
#include "stm32f10x.h"
#include <stdio.h>
void delay(long cycles);
void GPIOext_Init(void);
void led_blink(void);
int main(void)
{
int gear = 1;
GPIOext_Init();
while(1){
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5)){
if(gear < 7){
gear++;
}else{
led_blink();
}
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6)){
if(gear > 2){
gear--;
}else{
led_blink();
}
}
}
}
/***************************************************
* Initialize GPIOC and pin13 as PP y max speed
V1
***************************************************/
void GPIOext_Init (void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*Configure
GPIO pin : Input_Pin_C13 */
GPIO_InitTypeDef GPIO_InitStructure_PC13;
GPIO_InitStructure_PC13.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure_PC13.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure_PC13.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,
&GPIO_InitStructure_PC13);
GPIOC -> BSRR |= GPIO_BSRR_BS13;
//** PUSH
BUTTONS
/*Configure
GPIO pin : PushButton_Pin_B5 */
GPIO_InitTypeDef GPIO_InitStruct_PB_B5;
GPIO_InitStruct_PB_B5.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct_PB_B5.GPIO_Mode = GPIO_Mpde_IPD;
GPIO_Init(GPIOB,
&GPIO_InitStruct_PB_B5);
/*Configure
GPIO pin : PushButton_Pin_B6 */
GPIO_InitTypeDef GPIO_InitStruct_PB_B6;
GPIO_InitStruct_PB_B6.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct_PB_B6.GPIO_Mode = GPIO_Mpde_IPD;
GPIO_Init(GPIOB,
&GPIO_InitStruct_PB_B6);
}
/*******************************************
* Blink led_blink macro
*******************************************/
void led_blink(void){
//clear pin
set to 0
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
//reset 0010
0000 0000 0000 |set 0000 0000 0000 0000
delay(2000000);
//set pin to
1
GPIO_SetBits(GPIOC, GPIO_Pin_13);
//reset 0000
0000 0000 0000 |set 0010 0000 0000 0000
delay(2000000);
}
/*******************************************
* Delay
*******************************************/
void delay (long cycles){
while (cycles > 0)
cycles--;
}
0 comentarios:
Publicar un comentario