[Aporte] Tutorial ARM Cortex-M3 - LPC1768

Bien!!!, entonces no era lo que yo decía sino lo que indicaste, el manejo del bit de máscara.
 
Tarde, pero bue, más vale tarde que nunca.

No sé bien como recibís esos datos, tal vez conviene tirarlo directamente a un vector ni bien te llegan, pero bueno ese no era el tema, otra opción al desplazamiento es usar "uniones" que son variables especiales a medida del usuario con el fin de compartir espacio de memoria con distintos tipos de variables estandar, ejemplo para tu caso:


Código:
#include <stdio.h>
#include <stdlib.h>

union CadenaBits
{
    unsigned long long dato; //Variable de 64 bits
    unsigned char rec_datos[8]; //Vector de 8 bytes
};

int main()
{
    union CadenaBits campo;
    unsigned int cont;
    campo.dato=0x1122334455667788; //8 bytes: 0x11 - 0x22 - 0x33 - 0x44 - 0x55 - 0x66 - 0x77 - 0x88

    for(cont=0;cont<8;cont++)
    {
        printf("Byte %d= 0x%x\n",cont+1,campo.rec_datos[cont]);
    }
    return 0;
}

Como se vé en el código, creo una unión, donde el peso en memoria será de 64bits (la variable más grande que tiene la unión) y donde el vector de 8 bytes compartirá ese mismo espacio de memoria.

El resultado en consola de ese código es el siguiente:

resultado dijo:
Byte 1= 0x88
Byte 2= 0x77
Byte 3= 0x66
Byte 4= 0x55
Byte 5= 0x44
Byte 6= 0x33
Byte 7= 0x22
Byte 8= 0x11

El ordenamiento que se obtiene es el de un little endian (lo ejecuté en PC), pero es lo mismo que obtuviste vos con ese desplazamiento.

Una tercera opción (y creo que la más fácil) es usar punteros:

Código:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int cont;
    unsigned long long int dato=0x1122334455667788;
    void *ptr=&dato; //El puntero tomará la dirección en memoria de la variable de 64 bits
    for(cont=0;cont<8;cont++)
    {
        printf("Byte %d= 0x%x\n",cont+1,*(unsigned char*)(ptr+cont)); //Simplemente uso esa dirección de memoria como si fuera un vector
    }

    return 0;
}

El resultado es el mismo.
 
Ya que estamos te pregunto cosme. La solución que proponés ¿funciona independientemente de que el {procesador + compilador} guarde los datos como little endian o big endian?.
 
Ya que estamos te pregunto cosme. La solución que proponés ¿funciona independientemente de que el {procesador + compilador} guarde los datos como little endian o big endian?.

Es igual, salvo que los bytes te vienen dados vuelta, es decir:

resultado dijo:
Byte 1= 0x11
Byte 2= 0x22
Byte 3= 0x33
Byte 4= 0x44
Byte 5= 0x55
Byte 6= 0x66
Byte 7= 0x77
Byte 8= 0x88

Esto mismo ocurre con cualquiera de los 3 métodos que uses.
 
Buen post sobre esta placa. Tengo un pequeño problema con del ADC. En la práctica que tengo que realizar, el sistema dispone de un detector de vehículos prioritarios VP (ambulancia, policía y bomberos) que detecta las señales sonoras de estos y envía un pulso de 20 ms al sistema de control del semáforo, para que detenga la secuencia anterior y ponga ambos semáforos con luz roja durante 30 segundos. Durante estos 30 s se debe emitr una señal sonora de 1 kHz.
La señal sonora la hago con el DAC y hasta ahí bien, pero no se como utilizar el ADC para que me detecte los vehiculos prioritarios.
Gracias por vuestro tiempo!
 
Compara el valor leído por el ADC con un valor establecido.
Si es > es un vehículo prioritario.
Si es <= es un vehículo común


Agregar una "Ventana" de tiempo de activación sería bueno
 
Última edición:
Gracias por la respuesta. Tengo una señal cuadrada de 1KHz guardada en un array, pero lo que no llego a entender es correctamente el funcionamiento del ADC. Me he leído el manual de la LPC1768 mil veces y sigo sin pillarlo... :cry:
¿Podrías ponerme un ejemplo de como sería el código para que cuando el ADC sea igual a lo guardado en el array, me salte la interrupción del ADC?
 
La idea sería tomar muchas muestras para luego comparar las señales.

Los pasos que yo haría son:

1- En papel (o cualquier herramienta de análisis), averiguo las componentes en frecuencia que tiene la señal patrón a comparar. En base a este análisis, sabés cual debería ser la frecuencia de muestro del ADC.

2- Fijás la frecuencia de muestreo en el ADC. Por ej. en una señal cuadrada, tenés infinitos armónicos, hasta 5 armónicos, más o menos obtenés la forma de la señal, pero no así sus flancos, es cuestión de ver exáctamente lo que buscás de esa señal, entonces al menos el ADC para tener la forma de la señal debería muestrear a 10kHz, como el ADC del ARM te permite muestrear hasta 200kHz en 12bits (y si no me equivoco hasta 1MHz en 8 bits llega, es cuestión de ver la hoja de datos), por lo tanto incluso lo podés configurar en 200kHz y estarías tomando hasta 100 armónicos (prácticamente no perdés información).

3- Tratá de usar algún trigger que fije un nivel para que la señal se muestree en una ventana parecida a tu vector patrón.

4- Convertí.

5- Compará.

Ahora volviendo un poco a la tierra, si la señal que intentás medir es una cuadrada, tal vez usando un puerto digital y comparando los tiempos te alcance (de esta forma te evitás el uso del ADC), pero es cuestión de ver que parte de la señal buscás.
 
Fantástico tutorial. Todo muy bien explicado tan solo me a quedado una duda cuando se defines los pines con PINSEL entiendo esto:
Código:
#define PINSEL_TX_UART1	(1<<4)	//Bit 5:4 PINSEL0 -> Funcionando como /TXD0
#define PINSEL_RX_UART1	(1<<6)	//Bit 7:6 PINSEL0 -> Funcionando como /RXD0

son los bits 5:4 y 7:6 pero lo siguiente no lo entiendo:

Código:
LPC_PINCON->PINSEL1&=~((3<<6)|(3<<4));


y esto:

Código:
LPC_PINCON->PINMODE1&=~((3<<6)|(3<<4));



3<<6 y 3<<4 ese 3 de que es? no seria 1<<6 y 1<<4?

te agradecería que me aclarases esa duda muchas gracias
 
Pensá que c/PIN puede tener hasta 4 modos, por eso los PINSEL los tenés que tomar de a 2 bits, es decir 2 bits definen como se comportará el PIN (o puerto).

Por ej:

Código:
#define PINSEL_TX_UART1	(1<<4)

Ese (1<<4) significá 1 desplazado 4 veces a la izquierda, por lo tanto de esto en binario:

(0b000001<<4) = 0b010000

Esos dos bits altos "01" son los que definen el funcionamiento del puerto como una Uart Tx.

Código:
LPC_PINCON->PINSEL1&=~((3<<6)|(3<<4));

(3<<4)= (0b000011<<4)= 0b00110000
(3<<6)= (0b000000011<<6)= 0b11000000

Hacer la OR (|) dá como resultado:

(3<<6)|(3<<4)= (0b11000000)|(0b0000110000 )= 0b11110000

Hacer la negación (~) dá como resultado:

~((3<<6)|(3<<4))= ~(0b000....11110000)= 0b11.......00001111 (número de 32 bits)

Hacer la AND (&) dá como resultado poner en 0 los bits del registro "PINSEL1" que fijamos previamente.

Es una cuestión de usar máscaras.
 
Buenas noches, recien he comprado la tarjeta, en super chino, pero tiene cargado un sistema operativo llamado micrium, como hago para quitarle este sistema y poder ejecutar algun programa?, cuando trato de correr el load del keil me arroja el mensaje de * JLink Info: Core is locked-up!
 
Buenos días, tengo una duda sobre interrupciones, necesito configurar dos pines como interrupciones a parte de los cuatro interrupciones que tenemos Eint (0,1,2,3) , se que cualquier pin en los puertos 0 y 2 se puede configurar como interrupción pero va a estar relacionada con Eint 3, y no sé cómo hacerlos porque en mi práctica necesito 6 interrupciones, 4 los tengo pero necesito configurar 2 más y no sé cómo hacerlo, me puede explicar cómo se hace esta configuración o un ejemplo?
Muchas gracias
 
Lo que vas a tener que hacer, es en la rutina de interrupción preguntar por el puerto que cambio de estado y en base a eso, usar un flag o una variable de estado, ejemplo así en el aire:

En la rutina de interrupción:

PHP:
void EINT1_IRQHandler (void)   
{  
    if(puerto...tal 1) //O usando un switch!
    {
        estado_interrupcion_1=1;  
    }
    else if(puerto...tal 2)
    {
        estado_interrupcion_1=2;
    }
      
    LPC_SC->EXTINT|=(1<<1);    // Limpio la interrupción externa 1 
}

En el main:

PHP:
int main()  
{  
    ....//inicialización 

    while(1) //Bucle principal
    {
         switch(estado_interrupcion_1)
         {
              case 0:{break;} //Sin interrupcion
              case 1:
              {
                 //Acción al detectar puerto 1
                 break;
              } //Se detectó interrupción del puerto 1
              case 2:
              {
                 //Acción al detectar puerto 2
                 break;
              } //Se detectó interrupción del puerto 2
              ....//etc
         }

         __wfi();    //Sleep-Mode
    }
}

Incluso para mejorar la detección, convendría usar máscaras para detectar varias interrupciones al mismo tiempo. ;)
 
Hla a todos!
un pregunta, es posible hacer una señal senoidal con 4 valores que incluyan negativos, entre 511 0 y -512?

Mucha Gracias

Juan C.
Directo desde la lpc, no. La placa se alimenta con 3.3v, por lo que generar un voltaje negativo es imposible, desde la placa.
Podes usar un amp operacional configurado como sumador, le pones -1.65v para bajar la tensión, y la salida de la lpc haces que el cerro este en 511 (1.65v).
Claro, para todo esto también vas a necesitar una fuente de tensión negativa.

 
Hola cosmefulanito04 y todos del foro mi nombre es Eduardo y disculpen si saco un poco de tema el hilo, estoy leyendo este tutorial ya que anteriormente incursionaba en Pics con lenguaje C y el compilador de CCS y quiero introducirme al mundo de los ARM por ello me compre una placa que traje de china la LANDTIGER que viene con un LPC1768 que es muy similar a la de las fotos con mas accesorios y por eso me pareció perfecto comenzar con este tutorial.
Por otro lado comento que estoy trabajando con el Keil 5 y al colocar el segundo ejemplo de tu tutorial para programar los pll me tira errores por todos lados, en el configuración_pll , periféricos , interrupciones y en delay , no se si sera un problema de configuración del keil o que otra cosa sera, así que si tienen una idea como solucionarlo para seguir adelante estaré muy agradecido.
Por otro lado agradecería que me sugieran algo para leer al respecto ya que estoy medio complicado con este tema, veo hay muchas cosas dando vuelta y no se por donde empezar, vi un poco de todo como uo/cos-iii, el mbed y el cmsis que creo que este ultimo es el mas viable así que agradecería cualquier ayuda.
Gracias.

Eduardo
 
Atrás
Arriba