Aprendiendo a programar la Mini-STM32 con LCD táctil a color

Todo cuanto tiene que ver con la obtención, almacenamiento y proceso de la información digital, sus aplicaciones y el software y hardware utilizado.
Responder
Mensaje
Autor
Avatar de Usuario
Anilandro
Mensajes: 4905
Registrado: Dom Feb 11, 2007 10:16 pm
Ubicación: Islas Baleares, España
Contactar:

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#31 Mensaje por Anilandro »

En realidad 1Jabato1 tiene razón, podemos dejar este hilo como común para microcontroladores, especialmente si son para ARM - ST, porque teniendo el esquema, las cosas se pueden modificar sin demasiados problemas (y así practicamos más).

En referencia al IDE, el que estoy utilizando es el Keil, pero reconozco que el Coocox vale la pena, porque además de ser libre y gratuito suministra mucha información. Ahora estoy mirando de cómo adaptar los proyectos del Keil al Coocox, porque la función automática de conversión que éste tiene, genera tantos errores que luego la cosa no funciona.

Yo sigo trabajando en la próxima entrega del tutorial y la página web correspondiente, que supongo acabaré este semana.

Un saludo a todos
La VIDA sólo es energía que ha aprendido a defenderse... (Anilandro)

*** La Web de Anilandro *** http://sites.google.com/site/anilandro

Avatar de Usuario
1jabato1
Mensajes: 8
Registrado: Dom Oct 02, 2011 11:27 pm
País: España
Ciudad: Toledo

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#32 Mensaje por 1jabato1 »

Hola Anilandro.
Se puede portar de keil a Coocox copiando el main y modificando la configuracion de los archivos,aunque por alguna razon,que no he conseguido ver, me va mas lento en Coocox, alguna configuracion se me ha pasado.
Animo!!! que esto arranca.

Un saludo.
Javi.
La ignorancia me persigue desde que nací, siempre acaba encontrándome,la muy p.......... El menda

Avatar de Usuario
Anilandro
Mensajes: 4905
Registrado: Dom Feb 11, 2007 10:16 pm
Ubicación: Islas Baleares, España
Contactar:

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#33 Mensaje por Anilandro »

Portando el main.c y las librerías ha de funcionar, naturalmente, el problema es que estos ejemplos de Keil son muy enrevesados, y sus dependencias tienen a su vez otras dependencias, y estas otras, y llegas perderte entre un montón de librerías que se llaman casi lo mismo. El importador automático de Keil a Coocox no va bien, o al menos con estos proyectos de ejemplo, y te deja un montón de avisos en rojo, de que no ha encontrado esto o aquello.

Otra cosa que he de comprobar es si incluso las mismas librerías que utilizan ambos programas tienen exactamente el mismo contenido, porque en caso contrario las órdenes pueden tener distinta sintaxis... en fin, que hay trabajo por delante... pero también estoy seguro que una vez vencidos los primeros problemas luego se avanza muy rápido. Un compañero ha pedido la placa Smart-STM32, también con el mismo display, pero que tiene incluso circuitería para entrarle señales de una cámara y también para grabar y reproducir mp3.

Hoy he soldado 100 pines a la placa Mini-STM32, para poder conectarle cosas exteriores con un simple conector, en vez del peligro que implica el tener que utilizar cada vez el soldador en contacto con los pines del microcontrolador, pese a que mi BJC Pulsmatic tiene toma de tierra.

Imagen

Y también he recibido la STM32-Discovery

Imagen

Un saludo
La VIDA sólo es energía que ha aprendido a defenderse... (Anilandro)

*** La Web de Anilandro *** http://sites.google.com/site/anilandro

Avatar de Usuario
1jabato1
Mensajes: 8
Registrado: Dom Oct 02, 2011 11:27 pm
País: España
Ciudad: Toledo

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#34 Mensaje por 1jabato1 »

Tienes razón, los ejemplos complejos debe ser muy difícil portarlos,esta es mi placa de pruebas,también soldé unas tiras de pines para acceder a todo el pinout.


Imagen

Saludos.
La ignorancia me persigue desde que nací, siempre acaba encontrándome,la muy p.......... El menda

Avatar de Usuario
Anilandro
Mensajes: 4905
Registrado: Dom Feb 11, 2007 10:16 pm
Ubicación: Islas Baleares, España
Contactar:

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#35 Mensaje por Anilandro »

Programando la placa de desarrollo Mini-STM32 - II
Los entornos IDE y haciendo parpadear los LED


Conseguir el parpadeo de uno o varios LED suele ser de las primeras pruebas que se llevan a cabo cuando se aprende a programar una placa microcontrolada, y en eso vamos a meternos en esta página, pero antes es necesario hablar un poco sobre programación, recordar cuatro generalidades y también presentar el programa que utilizaremos para llevarla a cabo.

Otra cosa que debemos tener en cuenta es que una placa de desarrollo no se parece demasiado a un ordenador corriente, del cual los usuarios podemos desconocer por completo su estructura interna y en cambio manejar a la perfección los programas a través del teclado y la pantalla. Un módulo de este tipo es totalmente dependiente de la circuitería asociada, de tal forma que para realizar el simple ejercicio de encender un LED será imprescindible saber donde y cómo está conectado, y tanto en las pruebas como en el desarrollo de proyectos más de una vez será necesario diseñar y construir pequeños circuitos auxiliares para adaptar los sensores o los actuadores a las características y limitaciones del microcontrolador.

Por todos estos motivos, es necesario que quien quiera meterse en el tema conozca los rudimentos de la programación en C, pero también deberá tener algunos conocimientos de electrónica y de manejo de las herramientas e instrumentos asociados a esta disciplina.

======================================================

Consideremos por un momento que hemos resuelto el problema de la conexión del LED y sabemos perfectamente a que pin de salida del microcontrolador está conectado, y pensemos ahora como podía ser un programa capaz de hacerlo parpadear. Sin duda deberemos escribir una orden para dar tensión a dicho pin, mantenerla durante un cierto tiempo, tras este lapso quitarle la tensión, esperar el mismo tiempo y volver a repetir el ciclo desde el principio.

Secuencia de un programa para hacer parpadear un LED

Orden --- Acción --- Resultado
1 --- Suministrar tensión al LED (El LED se enciende)
2 --- Esperar un poco (El LED permanece encendido)
3 --- Cortar tensión al LED (El LED se apaga)
4 --- Esperar un poco (El LED permanece apagado)
5 --- Regresar al punto 1 (Se repite todo el ciclo anterior)

Estas órdenes son lógicas y fáciles de entender para nosotros... pero por desgracia no hay manera de cargarlas en la placa para que el microcontrolador las ejecute, ya que estos chips poseen un juego de órdenes muy determinado y mucho más preciso que nuestras formas corrientes de expresión. Las órdenes o instrucciones que puede ejecutar un dispositivo semejante se agrupan en lo que llamamos un "lenguaje de programación".

¿Y cómo sería programar con un lenguaje semejante...? Pues en la práctica como entrar en la Torre de Babel, ya que cada modelo de microcontrolador tiene el suyo propio, que a lo sumo será similar entre chips evolucionados de modelos anteriores, pero puede ser muy diferente al cambiar de tipo, de marca o de tecnología de fabricación.

Esto podría ser algo preocupante, y es el problema con que se encontraban los programadores de los primeros ordenadores. Por este motivo se trabajó para encontrar una solución hasta desarrollar los denominados "compiladores". Expliquemos cuatro cosas al respecto.

======================================================

Lenguajes de bajo y alto nivel

Hay muchos lenguajes de programación. Seguro que todos habréis oído hablar en alguna ocasión del Código Máquina, del Asembler, del Fortran, del Basic, del Visual Basic, del Pascal, del Java o del C, pero hay un factor determinante que diferencia los dos primeros de todos los demás.

El Código Máquina y el Asembler son calificados como lenguajes de bajo nivel, y están formados por órdenes muy escuetas, operaciones de deplazamiento en números binarios, conteos ascendentes o descendentes, escritura o lectura de bits en memorias-registro, comparaciones booleanas tipo OR, AND o NOT, etc. De hecho el Código Máquina y el Asembler son lo mismo, simplemente que el primero adopta la forma de listas interminables de números binarios y el segundo los sustituye por una representación algo más amable mediante iniciales, palabras abreviadas y números hexadecimales, que conocemos como lenguaje Asembler o Ensamblador.

Ejemplo de un corto fragmento de lenguaje ensamblador correspondiente a un microcontrolador PIC

org 0x00 ; aquí comienza el micro.-
goto Inicio ; salto a inicio del programa.-
org 0x05 ; origen del código del programa.-
bsf STATUS,RPO ; pasamos de Banco 0 a Banco 1
movlw b' 11111' ; Muevo 11111 a W.-
movwf TRISA ; cargo en TRISA
movlw b' 11111'
movlw TRISB
bcf STATUS,RPO ; Paso del Banco 1 al Banco 0
bcf PORTB,Led ; Comienza el apagado


Estos lenguajes no entienden de frases escritas ni procesadores de texto, ni de operaciones con números decimales o de mover una imagen en una pantalla o conectarse a Internet, sólo tratan con bits de información, con señales en un punto que representan un 1 si hay tensión eléctrica y un 0 si no la hay.

El Código Máquina y su alter ego el Asembler son los lenguajes primarios de los microprocesadores y microcontroladores, y la dificultad que implica su uso no sólo deriva de la complejidad o la extensión de sus programas cuando necesita efectuar funciones gráficas o matemáticas, sino también porque son exclusivos para cada modelo de chip. En contrapartida, su ventaja es la gran velocidad y el ahorro de memoria que permiten. Si necesitamos que un microcontrolador procese muy rápido la información que le entra, como por ejemplo la procedente de señales de audio o de vídeo, es necesario que no pierda tiempo en operaciones o comprobaciones inútiles, y eso se consigue con un código máquina eficiente y lo más reducido posible.

El resto de los lenguajes citados, desde el Fortran al C, son llamados "lenguajes de alto nivel", y poseen instrucciones capaces de realizar funciones muy complejas, como cargar un fichero desde un disco a una memoria, mostrar una imagen a color en una pantalla, o permitir que el usuario le entre un número, multiplicarlo por pi, efectuar su raíz cuadrada y escribir el resultado final en la ventana de un programa. Y aunque estos lenguajes también tienen sus dificultades, muchas de sus órdenes adoptan la forma de palabras que describen la acción, aunque por supuesto en inglés:

======================================================

Ejemplos de instrucciones de lenguajes de alto nivel

Instrucciones y acción que realizan

Load (Carga un archivo completo)
Save (Guarda un archivo completo)
Let A = 3 (Deja que la variable A tenga el valor 3)
IF X<6 Then Print "Hola" (Si X es menor que 6, entonces imprime "Hola")

La consecuencia es que mientras los lenguajes de bajo nivel están casi exclusivamente reservados a expertos, ya que su programación llega a ser compleja, tediosa y muy proclive a contener errores, los lenguajes de alto nivel pueden ser utilizados por la mayoría de las personas con una mínima formación.

Sin embargo, ya hemos dicho que sólo el lenguaje máquina es entendido por el microcontrolador, y por tanto, cualquier programa de alto nivel, que también llamaremos "código fuente", deberá ser "traducido" a bajo nivel antes de ser cargado. Esta función la efectúa el "compilador", con la ventaja adicional que no deberemos preocuparnos por los diferentes códigos máquina, porque el propio compilador ya dispone en su interior de los "diccionarios" adecuados para traducir el código fuente de entrada al código máquina de cada tipo de microcontrolador.

En la programación de alto nivel destinada a microprocesadores se utilizan todos los lenguajes antes citados y una veintena más para usos más específicos, pero en el caso de los microcontroladores el lenguaje utilizado es casi en exclusiva el C.

¿Y porqué en C y no en Visual Basic o en Pascal? Pues porque el C es un lenguaje algo especial, mediante el cual, con órdenes sencillas podemos cargar no sólo una imagen en pantalla o crear matrices de datos, sino que también efectuar funciones típicas del Código Máquina, como trabajar con bits individuales, con operaciones booleanas y acceder directamente a elementos del hardware o a posiciones de memoria. El C es potente y rápido a la vez, tal es así que muchos otros lenguajes están escritos interiormente en C, así como la mayor parte de los sistemas operativos como el Windows, el Linux o el Unix.

======================================================

Los IDE o Entornos Integrados de Desarrollo

Para programar en C utilizaremos programas llamados IDE (Entorno Integrados de Desarrollo), que consisten en una serie de herramientas unidas en un mismo paquete, que nos permiten escribir el código en C, corregir la sintaxis, añadir la librerías necesarias, compilar y depurar el código asembler resultante, e incluso cargarlo en el microcontrolador.

Hay bastantes programas IDE, la mayoría de pago, como el Keil uVision, el Atollic TrueStudio o el CrossWorks, aunque también pueden encontrarse soluciones de código libre como el Coocox o el Yagarto.

Para esta práctica del tutorial utilizaré el Keil microVisión en su versión gratuita de evaluación, que pese a estar reducida a compilaciones de 34 KBytes, nos basta perfectamente para nuestros propósitos, y el motivo es que todos los ejemplos de software que suministra el vendedor de la placa están en este formato de proyectos. Otro IDE que también veremos en futuras páginas será el Coocox, más sencillo de utilizar y que además suministra mucha información útil sobre órdenes y librerías.

======================================================

Instalación del Keil uVisión V4.22

El Keil uVision es otro de los archivos que habremos bajado de la web de Micro4you en el "Ejercicio 1", en concreto el archivo "mdk422.exe", de 414 Mbytes. Este considerable tamaño, teniendo incluso en cuenta que es un fichero comprimido autoextraible, es debido a que contiene muchas herramientas, información y librerías para los distintos microcontroladore ARM.

Sin perder más tiempo clicamos sobre el fichero mdk422.exe y procedemos a instalarlo en nuestro ordenador.

Anagrama de arranque del IDE Keil uVision 4.22
Imagen

Una vez instalado, vemos que la interface es clásica y discreta, pero eso es tan engañoso como puede serlo en el Photoshop, ya que el uVision V4 es un programa complejo y de grandes posibilidades, la mayoría de las cuales no utilizaremos pero otras las iremos descubriendo a lo largo de las próximas páginas. Así que ahora no vamos a meternos en grandes explicaciones, porque lo siguiente será cargar el primer ejemplo y comenzar a trabajar.

======================================================

Cargando el primer ejemplo

Los ejemplos están contenidos en los archivos...

- Mini STM32 V4 Code.rar
- Mini STM32 V4 2011.1.5.rar
- Mini STM32 V4 2011.1.18.rar

...Que también habíamos bajado en la página anterior de este tutorial. De ellos elegiremos el Mini STM32 V4 2011.1.5.rar que parece el más actualizado, lo descomprimimos y abrimos la carpeta resultante HY-MiniSTM32V 2011.1.5, cuyo contenido son las 19 subcarpetas siguientes:

- WWDG, USB-Mass_Storage-SD Card, USART, uCOSII2.91+UCGUI3.90A(FSMC), uCOSII2.91, TouchPanel, TIM, Temp, SysTick, RTC+USART, PWR, IWDG, ID, GPIO, FreeRTOSV6.1.0, Flash, FATFS V0.08A-SD Card, EXTI+USART

Elegiremos la GPIO, la abrimos, seleccionamos MDK-ARM y el archivo Project.uvproj. Al instante se nos abrirá el Keil uVision mostrándonos una estructura de carpetas a la izquierda y otra mucho más ancha a la derecha con un fichero de texto ilegible. Esto no nos ha de preocupar, porque posiblemente dicho archivo está escrito originalmente en ideogramas chinos y nuestro sistema no lo sabe interpretar, así que lo cerramos apretando sobre la pestaña superior "readme.txt", con botón derecho del ratón y Close. Después, en la columna de la izquierda abrimos la carpeta USER y el archivo main.c , el cual nos aparecerá con su propia pestaña en la ventana derecha.

Interface del Keil uVisión 4.22, con el primer programa de ejemplo que hará parpadear un LED
Imagen

La palabra "main", en inglés, significa "principal" y de hecho el listado así denominado representa el "programa principal" que va a ejecutarse, aunque este "main.c" también depende de otros archivos que contienen las definiciones de las órdenes que va a usar. Estos archivos se denomina "librerías" y tienen la forma de un nombre seguido de la extensión .h

A causa de esta dependencia, cuando se escribe un "main" en necesario incluir las librerías de que depende. Por ejemplo, en el "main" que estamos viendo, la instrucción #include "stm32f10x.h" indica en esta librería están las órdenes que después van a usarse, de manera que cuando arranquemos la compilación, no sólo va a procesarse el "main", sino también el "stm32f10x.h" , y ambos serán después "linkados" o unidos para formar el archivo ejecutable final.

Sigamos. El texto completo de "main.c",después de limpiarlo un poco de comentarios (escritos en verde entre los indicadores /* y */) para que no nos ocupe tanto espacio, tiene el siguiente aspecto.

======================================

#include "stm32f10x.h"
/*--------------Private functions ---------------*/
void GPIO_Configuration(void);
void Delay (uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/*----------------------- main -------------------------*/
int main(void)
{
GPIO_Configuration();
/* Infinite loop */
while (1)
{
/* LED1-ON LED2-OFF */
GPIO_SetBits(GPIOB , GPIO_Pin_0);
GPIO_ResetBits(GPIOB , GPIO_Pin_1);
Delay(0xfffff);
Delay(0xfffff);
Delay(0x5ffff);
/* LED1-OFF LED2-ON */
GPIO_ResetBits(GPIOB , GPIO_Pin_0);
GPIO_SetBits(GPIOB , GPIO_Pin_1);
Delay(0xfffff);
Delay(0xfffff);
Delay(0x5ffff);
}
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
/* LED1 -> PB0 LED2 -> PB1 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
#ifdef USE_FULL_ASSERT

======================================

Sin meternos ahora en explicaciones del cómo y el porqué, veo que este programa activará y desactivará de forma alternativa los Pins 0 y 1 del bus B del STM32. Entonces, abrimos el archivo "Mini STM32 STM32F103 TFT LCD Board V4.pdf" que contiene el esquema de la placa Mini-STM32 (archivo que ya habíamos bajado anteriormente de la web del vendedor), y en la parte del diagrama de las páginas 2 y 3 que reproducimos debajo, observamos que estos pins están conectados respectivamente a las etiquetas LED1 y LED2, que a su vez, a través de sendas resistencias alimentan los leds serigrafiados en la placa como LD3 y LD4, los cuales, evidentemente, también centellearán.

Parte del esquema de la placa Mini-STM32, que muestra las conexiones desde los Pines 0 y 1 del bus B, hasta los leds LD3 y LD4
Imagen

Imagen

Ahora que ya sabemos que hace, vamos a compilar el programa y después lo cargaremos en la placa siguiendo esta secuencia:

1) De la etiqueta Projet apretamos Build Target (o F7). Vemos que se abre una ventana en la parte inferior y comienza a compilar una serie de ficheros.

2) La primera vez tarda bastante, ya que no solo ha de hacerlo con el main.c sino con todas las librerías que éste utiliza. Después, cuando acaba, la penúltima fila nos indica "FromELF: creating hex file..." y la última si ha habido errores o avisos, en este caso "0" en ambas cosas.
El compilador nos ha creado un archivo ejecutable para el microcontrolador y lo ha guardado en la carpeta Obj del proyecto que hemos abierto. Antes de compilar por primera vez, esta carpeta estaba vacía, pero ahora hay muchos archivos, y entre ellos uno denominado Project.hex, que es ni más ni menos el ejecutable que hemos de cargar en nuestra placa.

3) Ahora conectamos nuestra MiniSTM32 al ordenador, la colocamos en modo de carga de programas (ver la página anterior para hacerlo) y abrimos el Flash Loader Demostrator.

4) Las dos primeras pantallas de la ventana del programa serán iguales que cuando borramos el programa Demo de la Mini-STM32, pero al llegar a la tercera hemos de marcar "Download to device" y después seleccionar ficheros tipo ".hex" y en concreto " el fichero Project.hex que hemos creado antes.

Imagen

Imagen

5) Le damos al "Next". La siguiente pantalla nos indicará el origen y tamaño del archivo cargado (1,2 KB) y la indicación en verde "Download operation successfuly" que la carga ha sido correcta.

Imagen

6) Ahora apretaremos el botón Reset de la placa y... Oh maravilla... ya tenemos a los dos LEDS de la parte inferior destelleando de forma alternativa.

======================================================

Continua en el siguiente mensaje
La VIDA sólo es energía que ha aprendido a defenderse... (Anilandro)

*** La Web de Anilandro *** http://sites.google.com/site/anilandro

Avatar de Usuario
Anilandro
Mensajes: 4905
Registrado: Dom Feb 11, 2007 10:16 pm
Ubicación: Islas Baleares, España
Contactar:

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#36 Mensaje por Anilandro »

Mejorando lo presente, vamos a crear nuestro primer programa

Antes he dicho que el programa anterior me parecía enrevesado, y no es que sea incorrecto bajo el punto de vista de un programador, es solamente que como ejemplo parece hecho a propósito para despistar a quienes no tengan un buen nivel de C. Por este motivo, sin que en ningún momento tenga interés en iniciar un curso de programación de este lenguaje, he decidido crear mi propio programa para luego poder explicar más fácilmente algunas órdenes concretas para manejar este microcontrolador.

Borro el contenido de main.c y escribo este nuevo listado:

======================================

/*Mini-STM32 encendido alternativo de dos leds*/
/* by Anilandro, octubre 2011*/

#include "stm32f10x.h" /*incluye la librería "stm32f10x.h"*/
GPIO_InitTypeDef GPIO_InitStructure;

int main(void){ /*inicio del programa principal*/

int cont; /*definimos una variable llamada "cont", de tipo entero*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*establece velocidad a 50 Mhz*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*establece modo de salida digital*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; /*aplicar lo anterior a PIN 0 y 1*/
GPIO_Init(GPIOB, &GPIO_InitStructure); /*cerrar*/

while (1){ /*bucle infinito*/
GPIO_SetBits(GPIOB , GPIO_Pin_0); /*coloca el PIN 0 a valor alto (enciende el LED 1)*/
GPIO_ResetBits(GPIOB , GPIO_Pin_1); /*coloca el PIN 0 a valor bajo (apaga el LED 2)*/
for(cont=0; cont<1000000; cont++); /*bucle de espera que cuenta un millón de pasos*/
GPIO_ResetBits(GPIOB , GPIO_Pin_0); /*coloca el PIN 0 a valor bajo (apaga el LED 1)*/
GPIO_SetBits(GPIOB , GPIO_Pin_1); /*coloca el PIN 0 a valor alto (enciende el LED 2)*/
for(cont=0; cont<1000000; cont++); /*bucle de espera que cuenta un millón de pasos*/
} /*final de bucle "while" que vuelve al principio*/
} /*final del programa principal*/

======================================

Una vez acabado, coloco la placa en modo boot-loader, arranco el Flash Loader Demonstrator y cargo el nuevo programa, que funciona a la primera. Los leds parpadean de forma alternativa, aunque con una cadencia algo más rápida que la anterior debido a los diferentes valores de los bucles de espera.

Para quien desee repetir la prueba, lo cual aconsejo si sigue este tutorial, bastará que seleccione el texto del recuadro y lo copie en su espacio "main.c" una vez borrado el texto anterior. Como estos ficheros son sólo de texto, a partir de este momento es igual que si lo hubiéramos escrito directamente en la ventana del Keil

======================================================

Explicando el funcionamiento del nuevo programa

Con los comentarios contenidos entre /*...*/ del programa anterior creo que ya es posible hacerse una idea de cómo actúa el programa, pero la cosa estará más clara si concretamos un poco más.

El programa está escrito en varios bloques claramente diferenciados:

#include "stm32f10x.h"
GPIO_InitTypeDef GPIO_InitStructure;
int main(void){


La primera línea incluye la librería que contiene las órdenes a usar, la segunda una llamada a una estructura de órdenes y la tercera el comienzo de la rutina principal. La primera instrucción "#include "stm32f10x.h" incluye la librería donde están las órdenes que vamos a utilizar, aunque ello no significa que tales órdenes estén físicamente dentro de esta librería, porque a su vez ésta también puede tener otros "#include". La línea GPIO_"InitTypeDef GPIO_InitStructure;" se refiere a una estructura de variables (no preguntemos ahora que es una estructura), las cuales serán utilizadas a continuación. Y "int main(void){" inicia la parte principal del programa.

int cont;

A continuación viene la declaración de variables. En este caso una sola que llamaremos "cont", y que es de tipo "int" o entera. Lo cual significa que dicha variable podrá contener números enteros entre -2.147.483.648 a 2.147.483.647. Dicha variable la utilizaremos como puntero de los contadores que nos permitirán establecer un tiempo de encendido y otro de apagado de los leds.

Ahora viene la parte que configura los "pins" del microcontrolador:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);


El STM32 dispone de 3 buses utilizables para periféricos:

- Advanced High-Performance Bus (AHB)
- Advanced Peripheral Bus (APB1) de velocidad hasta 36 MHz
- Advanced Peripheral Bus (APB2) de velocidad hasta 72 MHz

Normalmente estos buses están desconectados para que no consuman corriente. En este caso sólo usaremos pines del APB2, y para ello introduciremos la orden "RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);" que proporciona la adecuada señal de reloj.
Las tres siguientes órdenes establecen la velocidad a 50 Mhz, que el pin actuará como una salida en Push-Pull, y la tercera a que pines afectarán estos parámetros, en concreto vemos que afecta a Pin = GPIO_Pin_0|GPIO_Pin_1; , es decir, al Pin_0 y al Pin_1.

Esta parte se cierra con GPIO_Init(GPIOB, &GPIO_InitStructure); tras la cual ya no podemos seguir asignando pines, excepto que de nuevo cerremos con la misma instrucción, por ejemplo, las órdenes:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; /*asigna pin 0 y 1*/
GPIO_Init(GPIOB, &GPIO_InitStructure); /*cierra*/


Son equivalentes a:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; /*asigna pin 0*/
GPIO_Init(GPIOB, &GPIO_InitStructure); /*cierra*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; /*asigna pin 1*/
GPIO_Init(GPIOB, &GPIO_InitStructure); /*cierra*/


Y finalmente encontramos las órdenes que encienden y apagan los LED, encerradas dentro de un bucle while (1){.......} que se repite infinitamente

while (1){
GPIO_SetBits(GPIOB , GPIO_Pin_0);
GPIO_ResetBits(GPIOB , GPIO_Pin_1);
for(cont=0; cont<1000000; cont++);
GPIO_ResetBits(GPIOB , GPIO_Pin_0);
GPIO_SetBits(GPIOB , GPIO_Pin_1);
for(cont=0; cont<1000000; cont++);
}


Aquí vemos las órdenes de encendido tipo GPIO_SetBits .... y las órdenes de apagado tipo GPIO_ResetBits . Formando dos grupos que encienden un LED y apagan el otro, e intercaladas entre los grupos la línea for(cont=0; cont<1000000; cont++); Que es un contador desde 0 a 1.000.000, y el tiempo que tarda en hacerlo es el que permanece encendido un LED y apagado el otro.

La sentencia for(cont=0; cont<1000000; cont++); hace lo siguiente:

1) Toma la variable cont y le asigna el valor 0 (cont=0;)
2) Comprueba si el valor de la variable es menor de 1.000.000 (cont<1000000;), si es menor, pasa al paso 3), si es igual o mayor sale del "for" y salta a la siguiente instrucción
3) Le suma 1 a cont y salta de nuevo al paso 2) (cont++)

Entonces, si nosotros alteramos el valor de la comparación de (cont<1000000;), y ponemos 2.000.000 ó 500.000, el tiempo de conteo, y por tanto de encendido de un LED y de apagado de otro, subirá al doble o bajará a la mitad.

La secuencia total de esta parte es:

1) - Activamos Pin_0 y por tanto encendemos el LED_1
2) - Desactivamos el Pin_1 y por tanto apagamos el LED_2
3) - Esperamos el tiempo de conteo
4) - Desactivamos Pin_0 y por tanto apagamos el LED_1
5) - Activamos el Pin_1 y por tanto encendemos el LED_2
6) - Esperamos el tiempo de conteo
7) - Volvemos al paso 1)

====================================================

Probando algunas variaciones


Las órdenes GPIO_SetBits(GPIOB , GPIO_Pin_x); y GPIO_ResetBits(GPIOB , GPIO_Pin_x); (siendo "x" cualquier número de Pin válido) No son las únicas posibles para poner los pins a 0 y a 1, también podemos utilizar:

GPIO_WriteBit(GPIOB, GPIO_Pin_x,Bit_SET); /*coloca el PIN 0 a valor alto (enciende el LED 1)*/
GPIO_WriteBit(GPIOB, GPIO_Pin_x,Bit_RESET); /*coloca el PIN 0 a valor bajo (apaga el LED 1)*/


A la vez, la librería "stm32f10x.h" es muy general, pero también podemos utilizar las librerías particulares para las órdenes GPIO, y por tanto podemos sustituir la orden #include "stm32f10x.h" por:

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"


Aplicando estos cambios, nuestro programa "main.c" quedaría como:

======================================
/*Mini-STM32 encendido alternativo de dos leds*/
/* by Anilandro, octubre 2011*/

#include "stm32f10x_gpio.h" /*incluye la librería "stm32f10x_gpio.h"*/
#include "stm32f10x_rcc.h" /*incluye la librería "stm32f10x_rcc.h"*/
GPIO_InitTypeDef GPIO_InitStructure;

int main(void){ /*inicio del programa principal*/

int cont; /*definimos una variable llamada "cont", de tipo entero*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*establece velocidad a 50 Mhz*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*establece modo de salida digital*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; /*aplicar lo anterior a PIN 0 y 1*/
GPIO_Init(GPIOB, &GPIO_InitStructure); /*cerrar*/

while (1){ /*bucle infinito*/
GPIO_WriteBit(GPIOB, GPIO_Pin_0,Bit_SET); /*coloca el PIN 0 a valor alto (enciende el LED 1)*/
GPIO_WriteBit(GPIOB, GPIO_Pin_1,Bit_RESET); /*coloca el PIN 1 a valor bajo (apaga el LED 2)*/
for(cont=0; cont<1000000; cont++); /*bucle de espera que cuenta un millón de pasos*/
GPIO_WriteBit(GPIOB, GPIO_Pin_0,Bit_RESET); /*coloca el PIN 0 a valor bajo (apaga el LED 1)*/
GPIO_WriteBit(GPIOB, GPIO_Pin_1,Bit_SET);; /*coloca el PIN 1 a valor alto (enciende el LED 2)*/
for(cont=0; cont<1000000; cont++); /*bucle de espera que cuenta un millón de pasos*/
} /*final de bucle "while" que vuelve al principio*/
} /*final del programa principal*/

======================================

En la próxima entrega de este tutorial mostraremos otro entorno de programación IDE, el Coocox, veremos como utilizar botones para entrar órdenes al programa y montaremos alguna experiencia práctica algo más útil que encender y apagar un par de LEDs.

Continuará...
La VIDA sólo es energía que ha aprendido a defenderse... (Anilandro)

*** La Web de Anilandro *** http://sites.google.com/site/anilandro

maverick_007
Mensajes: 14
Registrado: Mar Sep 27, 2011 3:27 am
País: chile
Ciudad: concepcion

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#37 Mensaje por maverick_007 »

Hola anilandro, muy buena explicacion sobre el programa de ejemplo muy sensillo y facil de implementar e ideal para iniciarse, el programa que abia subido es muy similar solo que hace una secuencia de con leds, las sentencias son las mismas creo que eso se deve a que el keil esta usando las librerias del fabricante (ST Microelectronics). pero tengo una duda para cargar el programa al micro ago lo mismo que haces tu, compilo y abro el Flash Loader y cargo el .hex y lo envio al microcontrolador, y automaticamente se inicia el programa, porque los leds conectados a la placa comienzan a encenderse, pero cuando ago el reset tengo que volver a enviar el programa al micro para que funcione ........ ¿no te paso ese problema ?....

saludos.

Avatar de Usuario
1jabato1
Mensajes: 8
Registrado: Dom Oct 02, 2011 11:27 pm
País: España
Ciudad: Toledo

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#38 Mensaje por 1jabato1 »

Hola Anilandro.
Una pregunta,en algún ejemplo he visto este código que actúa directamente sobre los pines del puerto seleccionado.
En mi caso los leds están en GPIOF(6,7,8,9,y 10),por lo tanto
0x00000000000000000000011111000000=0x00000FC0

GPIOF->BSRR(Set bits)
GPIOF->BRR(Resetbits)

Código: Seleccionar todo

/***************************************LEDS***************************************/

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"


/* Private functions ---------------------------------------------------------*/
void GPIO_Configuration(void);

void  Delay (uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

/*******************************************************************************/

int main(void)
{
	GPIO_Configuration();
    /* Infinite loop */
    while (1){
	
	
	GPIOF->BSRR=0X0FC0;
		Delay(0x1fffff);
	GPIOF->BRR=0X0FC0;
		Delay(0x1fffff);
	GPIOF->BSRR=0X0FC0;
		Delay(0x1fffff);
	GPIOF->BRR=0X0FC0;
		Delay(0x1fffff);
	GPIOF->BSRR=0X0FC0;
		Delay(0x1fffff);
    GPIOF->BRR=0X0FC0;
		Delay(0x1fffff);
	GPIOF->BSRR=0X0FC0;
		Delay(0x1fffff);
		
		
	/*	GPIO_ResetBits(GPIOF , GPIO_Pin_6);
		Delay(0x3fffff);
			
        GPIO_ResetBits(GPIOF , GPIO_Pin_7);
		Delay(0x3fffff);
		
		GPIO_ResetBits(GPIOF , GPIO_Pin_8);
		Delay(0x3fffff);
		
		GPIO_ResetBits(GPIOF , GPIO_Pin_9);
		Delay(0x3fffff);
		
		GPIO_ResetBits(GPIOF , GPIO_Pin_10);
		Delay(0x3fffff);
		

	 GPIOF->BSRR=0X0FC0;
		Delay(0x3fffff);
		
		GPIO_ResetBits(GPIOF , GPIO_Pin_10);
		Delay(0x3fffff);
			
        GPIO_ResetBits(GPIOF , GPIO_Pin_9);
		Delay(0x3fffff);
		
		GPIO_ResetBits(GPIOF , GPIO_Pin_8);
		Delay(0x3fffff);
		
		GPIO_ResetBits(GPIOF , GPIO_Pin_7);
		Delay(0x3fffff);
		
		GPIO_ResetBits(GPIOF , GPIO_Pin_6);
		Delay(0x3fffff);
		
		GPIOF->BSRR=0X00000FC0;
		Delay(0x3fffff); */

					
    }
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configure GPIO Pin
* Input          : None
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOF , ENABLE); 						 
  					
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 |GPIO_Pin_9 | GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
  GPIO_Init(GPIOF, &GPIO_InitStructure);
}
Excelente tutorial,un saludo
Javi
La ignorancia me persigue desde que nací, siempre acaba encontrándome,la muy p.......... El menda

Avatar de Usuario
Anilandro
Mensajes: 4905
Registrado: Dom Feb 11, 2007 10:16 pm
Ubicación: Islas Baleares, España
Contactar:

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#39 Mensaje por Anilandro »

Maverick-007
Pues no sé que debe suceder, porque cuando cargas el fichero .hex o el .bin la placa ha de esta en modo "boot loader", y cuando acabas de cargarlo no tiene porqué salir de él hasta que no aprietas "reset", y por tanto el programa no debería arrancar solo. Al menos esto es lo que hace la Mini-STM32. Y el hecho que al hacer "reset" tengas que volver a cargar el programa es más extraño aún, como si se hubiera cargado en la RAM en vez de en la memoria FLASH. ¿Es posible que tengas el Flash Loader Demo mal configurado...? Hasta el momento, de este programa sólo he utilizado "erase" y "download" y sin cambiar ningún parámetro, así que realmente no sé que posibilidades tiene.

1jabato1
La verdad es que aún no he llegado a estas funciones y por tanto sólo puedo suponer la forma en que actúan, pero me imagino que afectan a los bits a nivel de registro.

GPIOF->BRR(Resetbits) es "Port bit reset register.", y por tanto pone a cero los bits de todo el registro (y por tanto los pins correspondientes), o bien con una orden tipo GPIOF->BRR=0X0FC0; sólo afecta a los bits que especifique el valor que le asignas en hexadecinal.

Sobre la instrucción GPIOF->BSRR(Set bits) no lo tengo tan claro, porque la definición es "Port bit set/reset register", entonces si sirve para "set" y "reset", se supone que "fuerza" los bits a 1 o a 0 dependiendo de la palabra (Set bits) o (Reset bits), o bien dependiendo del número binario equivalente al hexadecimal.

¿Dices que tienes registros hasta el F (es decir 6), qué tipo de microcontrolador utiliza tu placa...?

Un saludo
La VIDA sólo es energía que ha aprendido a defenderse... (Anilandro)

*** La Web de Anilandro *** http://sites.google.com/site/anilandro

Avatar de Usuario
1jabato1
Mensajes: 8
Registrado: Dom Oct 02, 2011 11:27 pm
País: España
Ciudad: Toledo

Re: Aprendiendo a programar la Mini-STM32 con LCD táctil a c

#40 Mensaje por 1jabato1 »

¿Dices que tienes registros hasta el F (es decir 6), qué tipo de microcontrolador utiliza tu placa...?
Es el STM32F103ZE

En mi caso los leds se activan con 0(están conectados a resistencias pull-up), BSRR los apaga y BRR los enciende,He buscado estos registros y no los he encontrado,también he visto en algún ejemplo ODR e IDR para salidas y entradas de los puertos, por eso mi pregunta,¿puede ser ASM?

Saludos.
La ignorancia me persigue desde que nací, siempre acaba encontrándome,la muy p.......... El menda

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado