[Aporte] Tutorial ARM Cortex-M3 - LPC1768

Estuve variando la velocidad de conversión, pero no me dio buen resultado, ya que lo que logré es que el valor siga oscilando pero que dicho valor cambie de una forma mas lenta.
Pero eso es un proble ya que no responde rapido a los cambios de peso. Estuve viendo que otra solución es mandar todas las entradas de ADC a tierra. Pero no se si puede afectar mucho en la medición.
Lo que no me cierra es porque no oscila en los extremos? o sea cuando le inyecto 3.3v o 0v

Gracias
 
Estuve variando la velocidad de conversión, pero no me dio buen resultado, ya que lo que logré es que el valor siga oscilando pero que dicho valor cambie de una forma mas lenta.

Es una medida mas que deberías tomar (importante), no la única.

Lo que no me cierra es porque no oscila en los extremos? o sea cuando le inyecto 3.3v o 0v.

Es bastante obvio, pensá que tanto los 3,3v como el GND forman parte de la referencia, es imposible obtener una medición distinta a esos niveles.

Volviendo un poco sobre tu problema, si la oscilación es de uno pocos niveles, por ej. 10, estamos hablando de variaciones de 8mV (muy cerca del piso de ruido que medís con un OCR), en cambio si ya la diferencia de nivel es de 100 unidades, ya hablamos de un posible ripple, ¿mediste la tensión con un OCR?.
 
Lo que me hace es lo siguiente: Si yo inyecto al adc 3.3v, el valor de adc es 4095 ok?. Bueno lo que yo hago es multiplicar el valor_adc por una constante 0.805669 que me da como resultado 3300, en lugar de 4095.

Cuando yo utilizo la celda de carga tengo variaciones de alrededor de 100mv en el dato que obtengo del adc, es muchísimo por ahora no probé con un filtro pasa bajo ni tampoco con un promediado del valor. Por eso te preguntaba si te había pasado algo similar. YO mido la entrada del la placa con un multímetro y no noto variaciones, se que no es lo mejor para medir pero en este momento no cuento con otro instrumental

Gracias!!
 
Cuando yo utilizo la celda de carga tengo variaciones de alrededor de 100mv en el dato que obtengo del adc, es muchísimo por ahora no probé con un filtro pasa bajo ni tampoco con un promediado del valor. Por eso te preguntaba si te había pasado algo similar. YO mido la entrada del la placa con un multímetro y no noto variaciones, se que no es lo mejor para medir pero en este momento no cuento con otro instrumental.

Para mí es lo que estás midiendo lo que te da esos 100mV de oscilación, descartando problemas de ruidos importantes en el PCB/circuitos de prueba.

Probá con lo siguiente, de una tensión bien regulada, conectala al operacional y fijate que medís, tratá de que la alimentación del operacional sea buena y no tengo un ripple excesivo (si podés regular su alimentación, mejor).

De todas formas lo ideal es saber que estas midiendo en la celda y eso lo haces con un OCR, el tester con el filtro pasa bajos te mata la alterna.
 
Última edición:
Se libero el LPCXPRESSO para C++. La nueva generacion de programadores.
Estuve trabajando todo el año con el LPC1769 y es una joya. El IDE anda de maravillas. Pude lograr una interfaz grafica sobre pantalla tactil, lectura de pendrive y reproduccion de musica sin ningun tipo de problema.
Solo queria dar un consejo: Si se quieren comprar un LPC, comprense el 1769 ya que el 68 tiene un problema al levantar la frecuencia de pll, sacando eso son iguales.
 
Desde mi humilde experiencia, ningún problema con el 1768 y el uso del PLL, enganchó perfecto en la frecuencia que quise, incluso a la máxima de 100MHz, no probé "overclockearlo", pero seguro que un par de MHz más se le puede sacar, por lo menos en los ARM7 5 MHz más se le podía sacar.
 
Cosmefulanito, ya solucioné el tema de la variación. Tenía mucha oscilación en el ampli diferencial y eso lo veia el ADC. Lo filtré con un RC, además hice un promediado de los valores con eso también mejoró.

Te hago una pregunta, en los archivos de ejemplo que vienen con el kit esta un easyweb, pero para que funcione con LAN 8720 hay que modificar dos archivos el EMAC.C Y EMAC.H. Estuve tratando de identificar que es lo que debo cambiar o que debo redefinir pero estoy perdido. Vos laburaste con esta configuración.

Muchas gracias
Slds
 
El 1769 llega hasta 120Mhz. En teoria el 1768 tambien pero tiene un bug que no se lo permite.
Para empezar a usar el USB recomiendo la utilización de librerias que vienen con la placa de desarrollo de Embedded Artist. Si desean Hostear un pendrive por ejemplo, les recomiendo las librerias de FAT16 del chinito CHAN:http://elm-chan.org/fsw/ff/00index_e.html (las cuales por suerte se encuentran para nuestro queridisimo LPC17xx) Si tengo tiempo, en unos dias subo unos programas para poder levantar un pendrive y poder leer y escribir archivos.
Para todo aquel que tiene experiencia con las funciones FILE tanto de linux como de windows les va a ser muy similar trabajar con esta libreria.
 
En teoria el 1768 tambien pero tiene un bug que no se lo permite.

Bue, pero de ahí a que falle el PLL a la fmax que recomienda la hoja es otra cosa :D.

Para empezar a usar el USB recomiendo la utilización de librerias que vienen con la placa de desarrollo de Embedded Artist. Si desean Hostear un pendrive por ejemplo, les recomiendo las librerias de FAT16 del chinito CHAN:http://elm-chan.org/fsw/ff/00index_e.html (las cuales por suerte se encuentran para nuestro queridisimo LPC17xx) Si tengo tiempo, en unos dias subo unos programas para poder levantar un pendrive y poder leer y escribir archivos.
Para todo aquel que tiene experiencia con las funciones FILE tanto de linux como de windows les va a ser muy similar trabajar con esta libreria.

Dibuje maestro, si podés subilo. (y)
 
Cosmefulanito, hay una cosa que no entiendo cuando planteas el programa con interrupciones. Yo reviso el main y veo que todas las condiciones están dentro de un while.
O sea entiendo que esta todo el tiempo encuestando, pej, si el pulsador fue presionado, si el ADC terminó la conversión etc.
Esto es así o hay algo que no estoy viendo.
Ahora estoy renegando para tratar de que las letras que salen por el LCD sean más grandes porque las que trajo la librería vienen de 8*16 jajaja no se ve nada

Gracias
 
Cosmefulanito, hay una cosa que no entiendo cuando planteas el programa con interrupciones. Yo reviso el main y veo que todas las condiciones están dentro de un while.
O sea entiendo que esta todo el tiempo encuestando, pej, si el pulsador fue presionado, si el ADC terminó la conversión etc.

Si y no.

Tenés dos formas de resolver una rutina de interrupción:

  1. Usando un flag (variable global) solamente para indicar que hubo una interrupción y luego resolver la acción fuera de la rutina de interrupción.
  2. Resolver la acción, si es corta, dentro de la rutina de interrupción.

En los ejemplos que subí, usé la primera forma, pero en combinación con la función " __wfi()" para no estar haciendo polling todo el tiempo, solo lo hago cuando se produjo una interrupción, el resto del tiempo el uC está durmiendo.
 
Muy buenas! Soy nuevo en el foro y la verdad es que te leí hace tiempo cosmefulanito y guarde la pagina en favoritos para futuras ocasiones y ahora me vendría de perlas un cable con la LPC1768... No he encontrado mucho sobre el tema por internet (la verdad es que si, pero no legible desde mis cocimientos jajaja) acerca de la interrupción SysTick, como configurar su prioridad, el retardo, etc... Adjunto un pdf con el trabajo con el que estoy teniendo problemas, concretamente con la actividad 6.2 ¿Podrías subir algún tipo de tutorial acerca de esta interrupción? Gracias!!
 

Adjuntos

  • Practica_6_System Tick Timer.pdf
    583.1 KB · Visitas: 65
Última edición:
Por lo que estuve viendo, es bastante sencillo de manejar.

Depende de los siguientes registros:
  • STCTRL: en este registro se habilita la cuenta regresiva, la interrupción (el System Tick no está dentro del vector de interrupción NVIC, por lo menos yo no lo encontré), el clock fuente (si es mediante el CCLK o un CLK externo mediante el pin P3.26).
  • STRELOAD: en este registro se fija la cuenta, dicha cuenta podrá ser de 24bits máximo.

La cuenta se calcula de la siguiente forma:

[LATEX]Cuenta=\frac{T_{mSeg}.Clock}{1000}-1[/LATEX]

Ejemplo de un Tick de 1mSeg usando los 100MHz del CCLK:

[LATEX]Cuenta=\frac{1.100000000}{1000}-1=99999[/LATEX]

Entonces, del ejercicio "Segunda Parte - PLL y timers (código)" para trabajar con el System Tick la modificaciones que haría son las siguientes:

perifericos.c

PHP:
//Todo lo anterior

//--------------------------------------- SysTick -------------------------------------------------------------//
#define SYSTICK_CLK					100000000

#define SYSTICK_DISABLE				0
#define SYSTICK_ENABLE				(1<<0)
#define SYSTICK_INT						(1<<1)
#define SYSTICK_CPU_CLK				0
#define SYSTICK_EXTERNAL_CLK	(1<<2)

void configura_systick(u8 configuracion,u32 recarga_ms)
{
	configuracion&=(SYSTICK_EXTERNAL_CLK|SYSTICK_INT|SYSTICK_ENABLE);	//Me aseguro que solo esté seteado el bit 2/1/0	
	
	SysTick->CTRL=configuracion;	
	
	SysTick->LOAD=((u32)((recarga_ms*SYSTICK_CLK)/1000)-1)&0xffffff;	//Me aseguro que sea de 24bits		
}
//--------------------------------------- SysTick -------------------------------------------------------------//

Donde se ve que:

  • Mediante la variable "configuracion" se habilita la cuenta, la interrupción y la fuente de clock, asegurandome que solo se modifiquen los 3 primeros bits.
  • Mediante la variable "recarga_ms" se realiza la cuenta que puse arriba y me aseguro que esa recarga sea de 24 bits.

interrupciones.c

PHP:
//--------- Rutina de la interrupcion SysTick ---------------------// 
void SysTick_Handler(void)
{
	u32 dummy=SysTick->CTRL;	//Lectura falsa para limpiar el flag "COUNTFLAG".
	flag_systick=1;
}	
//--------- Rutina de la interrupcion SysTick ---------------------//

Donde se ve que:

  • Limpieza del flag "COUNTFLAG" mediante una lectura falsa.
  • Mediante la variable global "flag_systick", dejo indicado que hubo una interrupción.

main.c

PHP:
#include <LPC17xx.H>

#include "defines.c"

#define LED_1 (1<<25)	//Puerto 3.25
#define LED_2 (1<<26)	//Puerto 3.26
#define TIEMPO_CAMBIO_DE_ESTADO	10000

//------- Variables globales para las interrupciones -------------//
u8 flag_timer0=0,flag_systick=0;
//------- Variables globales para las interrupciones -------------//

#include "interrupciones.c"
#include "configuracion_PLL.c"
#include "perifericos.c"

int main()
{	
	u16 cont=TIEMPO_CAMBIO_DE_ESTADO;
	
	configurar_pll(CLK_XTAL,25,2,3,0,0);	// Cristal de 12MHz => M=25 N=2 => FCCO => CPU-CLK=100MHz y P-CLK=25MHz 
	
	LPC_PINCON->PINSEL7=0;			//Declaro al puerto 3 como GPIO
	LPC_GPIO3->FIODIR|=LED_2|LED_1;		//Defino al puerto como salida 
	
	LPC_GPIO3->FIOSET=LED_1;		//Pongo en 1 el puerto => led apagado
	LPC_GPIO3->FIOCLR=LED_2;		//Pongo en 0 el puerto => led encendido
	
	configura_systick(SYSTICK_CPU_CLK|SYSTICK_INT|SYSTICK_ENABLE,1);	//Clock interno, interrupción habilitada c/1mSeg, SysTick habilitado
	
        //No necesito modificar el vector NVIC!

	while(1)
	{		
		if(!cont)
		{
			cont=TIEMPO_CAMBIO_DE_ESTADO;
			
			if(LPC_GPIO3->FIOPIN&LED_1)
				{LPC_GPIO3->FIOCLR|=LED_1; LPC_GPIO3->FIOSET|=LED_2;}
			else
				{LPC_GPIO3->FIOSET|=LED_1; LPC_GPIO3->FIOCLR|=LED_2;}
		}
		
		__wfi();	//Sleep-Mode				
		
		if(flag_systick)
		{
			flag_systick=0;
			cont--;
		}
		
	}
}

Solo llegué a probarlo con el debugger de keil y funcionaba bien, será cuestión de probarlo con el hard.

Otra alternativa que encontré que es más genérica, que es lo que propone Hellmut1956, donde se usa una función SysTick_Config (algo similar a la que hice). Por ejemplo en el FreeRtos creo que usan esa función para fijar el Tick.

Te subo el proyecto con el código que puse arriba.
 

Adjuntos

  • Led - interrupción Systick.zip
    196.5 KB · Visitas: 29
Cosmefulanito, sigo con el problema del ADC, estuve problando muchas cosas pero el problema sigue. Tengo gran variación en el dato que tengo en el registro del ADC. Al prinicipio pensé que era ruido de línea acoplado a la señal, pero probé con un divisor de tensión tomando los 3.3v de la placa del micro y referenciandolo a masa y obtuve el mismo resultado.
Estuve haciendo debugging con el Keil y veo que en cada conversión, el valor del registro del ADC es distinto, eso es lo que veo como variación. Estuve tratando de promediarlo haciendo un if tomando 20 muestras, pero se me hizo muy lento y me mostraba cualquier valor.

La verdad solo me queda probar por DMA, pero no debería ser así. Se te ocurre alguna otra cosa. Gracias
SAludos
!!
 
...Al prinicipio pensé que era ruido de línea acoplado a la señal, pero probé con un divisor de tensión tomando los 3.3v de la placa del micro y referenciandolo a masa y obtuve el mismo resultado.

Podría ser un problema de alimentación, que se te meta mucho ruido por ahí, tratá de evitar el usb de la PC y usá una fuente (si es que no hiciste antes eso).

...Estuve haciendo debugging con el Keil y veo que en cada conversión, el valor del registro del ADC es distinto, eso es lo que veo como variación. Estuve tratando de promediarlo haciendo un if tomando 20 muestras, pero se me hizo muy lento y me mostraba cualquier valor.

Subí el código que tenés así lo veo, hacelo usando las etiquetas "
PHP:
" o "
Código:
" del foro.

...La verdad solo me queda probar por DMA, pero no debería ser así. Se te ocurre alguna otra cosa.

Si ya venís mal con la conversión normal, usando DMA dudo que mejores en algo.

¿Probaste con otro canal?¿bajaste la velocidad de conversión? ¿cómo es el circuito que usas antes del ADC?
 
Probé cambair la velocidad de conversión, lo único que hace es que varía menos, pero también la respuesta ante los cambios es más lenta, o sea que nome sirve.

Vos me preguntas por el circuito anterior, pero va más alla de eso. La última prueba que hice es tomar los 3.3v de la placa y dividirlo por dos con resistencias, de modo de obtener 1.65v (fijo, libre de todo tipo de ruido). Así y todo cuando miro el registro del ADC el valor varía demasiado.

A vos tu código te funciona perfectamente? probé con el p0.23 y el p0.25. Los dos hacen lo mismo.

Gracias
 
Atrás
Arriba