Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
muy buen tutorial cosme ! algun dia voy a continuar el de ARM7 lo abande un poco por falta de tiempo!
A vos tu código te funciona perfectamente?
configura_timer0(25000,1000); //Pre-escaler 250000 => 25MHz/250000=1000Hz => 1000cuentas => 1000Hz/1000cuentas=1Hz=1Seg
iniciar_adc(0,0); //Inicio el ADC en el canal 0 sin offset
Cosmefulanito, yo probé el código tal cual lo bajé de tu ejemplo. Las cosas que fui probando fue
PHP:configura_timer0(25000,1000); //Pre-escaler 250000 => 25MHz/250000=1000Hz => 1000cuentas => 1000Hz/1000cuentas=1Hz=1Seg iniciar_adc(0,0); //Inicio el ADC en el canal 0 sin offset
cambiarle el 1000 por 500 para que haga la conversión más rápido, otra cosa que cabié fué probar iniciar el canal 2 en lugar del 0. Nada más
if(convertir_adc(0,250,&valor_adc)>0) //Convierto en el canal 0, con un pre-escaler=250
{
....
}
En realidad no necesito 12 bit de resolución con 8 alcanzaría. pero varía demasiado
cosmefulanito04 dijo:Por otro lado se puede ver que la cantidad de cuentas para generar 1uS es de solo 25, por lo que se obtendrá un error de cuantización de 1/25=0,04 cuentas. Para mejorar ese inconveniente, se podría aumentar el Pclk a 100MHz, logrando así que se necesiten 100 cuentas para obtener 1uS y bajando el error de cuantización a 1/100=0,01 cuentas.
/*----------------------------------------------------------------------------
* Name: SYSTICK_interrupt.c
*----------------------------------------------------------------------------*/
#include "LPC17xx.H"
uint32_t pulsador;
uint32_t SystemFrequency=100000000;
volatile uint32_t msTicks=1; // Contadores de Ticks de x ms
uint32_t LED1_18=0;
uint32_t LED1_29=0;
uint32_t contador=0;
uint32_t k=1;
void SysTick_Handler (void) // Rutina (ISR) de atención...
//... a la excepción 15 -del SYSTICK-
{
if (pulsador==0){ // pulsador pulsado
if(msTicks==1){
LED1_29=1; // enciendo LED P1.29
LED1_18=0; // apago LED P1.18
}
if(msTicks>=100 && msTicks<200){
LED1_29=0; // apago LED P1.29
LED1_18=1; // enciendo LED P1.18
}
if(msTicks>=200){
LED1_18=0; // apago LED P1.18
msTicks=0;
}
}
else{ // pulsador sin pulsar
if(msTicks==1){
LED1_29=1; // enciendo LED P1.29
LED1_18=0; // apago LED P1.18
}
if(msTicks>=200 && msTicks<400){
LED1_29=0; // apago LED P1.29
LED1_18=1; // enciendo LED P1.18
}
if(msTicks>=400){
LED1_18=0; // apago el LED P1.18
msTicks=0;
}
}
if(LED1_18==1){
LPC_GPIO1->FIOPIN &= ~(1<<18); // enciendo LED P1.18
LPC_GPIO1->FIOPIN &= ~(1<<29); // apago LED P1.29
}
if(LED1_18==0){
LPC_GPIO1->FIOPIN |= (1<<18); // apago LED P1.18
LPC_GPIO1->FIOPIN |= (1<<29); // enciendo LED P1.29
}
if(msTicks==k*100){
contador++;
k++; // Indicador de que ha llegado a 1 segundo
}
msTicks++; // Incrementar contadores cada 10ms y cada 1s
}
static __INLINE uint32_t SysTick_Configuracion(uint32_t prio_SysTick)
{
SysTick->CTRL |= (1<<2); //Selecciono la fuente de reloj interna
SysTick->CTRL |= (1<<0); //Habilito la cuenta de SysTick
SysTick->CTRL |= (1<<1); //Habilito su posibilidad de generar interrupción
SysTick->LOAD = SysTick->CALIB; //Genera una interrupción de 10ms, los cuales los coge del registro de Calibración
SysTick->VAL = 0;
NVIC_SetPriority(SysTick_IRQn, prio_SysTick); //Establece la prioridad que le llega como parametro
return(0);
}
int main (void)
{
LPC_GPIO1->FIODIR |= (1<<18); // P1.18 definido como salida
LPC_GPIO1->FIODIR |= (1<<29); // P1.29 definido como salida
LPC_GPIO2->FIODIR &= ~(1<<12); // P2.12 definido como entrada
SysTick_Configuracion((1<<__NVIC_PRIO_BITS) - 1);
// SystemInit (); // Inicializar relojes " clocks"
//SysTick_Config (SystemFrequency/100); // Configurar SYSTICK
while (1) pulsador=((LPC_GPIO2->FIOPIN & (1<<12))>>12);
}
markisrodrigo dijo:¡Vale, genial! Ya veo lo que quería decirme el profesor con esa frecuencia jaja, una última cosilla, ¿Cómo calculo el valor del registro de SYSTICK que realiza la cuenta atrás (TENMS) para que en lugar de los 10ms sea de 15us? ¿He de tantearlo o hay alguna forma de calcularlo? Gracias!
markisrodrigo dijo:...pero no nos explican casi nada en clase y luego de leerme el manual de LPC17xx sigo con bastantes dudas...
void convertir_digitos_u32_serie(uint8_t digitos[],uint32_t value)
{
uint8_t aux;
for(aux=4;aux>0;aux--)
{
digitos[aux]=(value%10)+0x30;
value=(int)(value/10);
}
digitos[0]=value+0x30;
}
UINT32 value;
UINT8 result[4];
result[0] = (value & 0x000000ff);
result[1] = (value & 0x0000ff00) >> 8;
result[2] = (value & 0x00ff0000) >> 16;
result[3] = (value & 0xff000000) >> 24;
void convertir_digitos_u32_serie(uint8_t digitos[],uint32_t value)
{
uint8_t aux;
for(aux=9;aux>0;aux--)
{
digitos[aux]=(value%10)+0x30;
value=(int)(value/10);
}
digitos[0]=value+0x30;
}
u8 vector_digitos[10];
convertir_digitos_u32_serie(vector_digitos,32000);
for(cont=10;cont>0;cont--)
envia_dato_uart0(vector_digitos[cont-1]);
Salida uart dijo:'0'-'0'-'0'-'0'-'0'-'3'-'2'-'0'-'0'-'0'
case MOSTRAR_CONVERSION_ADC:
{
if(convertir_adc(0,125,&valor_adc)>0) //Convierto en el canal 0, con un pre-escaler=125
{ valor_adc=valor_adc*0.805860;
contador=contador + 1;
valoradc=(valor_adc + valoradc)/contador;
if (contador==8)
{ enviar_string_uart0(" Conversion= \n");
envia_u16_string_uart0(valoradc);
contador=0;
}
valor_adc=0;
}
}
gracias capo!!
Estoy "debbugueando" para ver porque me muestre ese valor tan errado.
#define MUESTRAS_MAX 16
int main()
{
...
//--------- Vectores de muestreo --------------//
u16 muestra_adc[MUESTRAS_MAX];
u8 indice_muestra_adc=0;
u32 promedio_movil=0;
//--------- Vectores de muestreo --------------//
....
iniciar_adc(0,0); //Inicio el ADC en el canal 0 sin offset
// Inicializo timers, puerto serie, etc
....
while(1)
{
if(flag_timer0) //Configuro el timer0 (o cualquier timer disponible), para que c/cierto tiempo tome una muestra del ADC.
{
if(convertir_adc(0,250,&valor_adc)>0) //Convierto en el canal 0, con un pre-escaler=250
{
muestra_adc[indice_muestra_adc]=valor_adc;
indice_muestra_adc++;
if(indice_muestra_adc==MUESTRAS_MAX)
indice_muestra_adc=0;
}
}
if(flag_timer1) //Configuro el timer1 (o cualquier timer disponible), para que c/cierto tiempo envíe el promedio móvil por uart (ej. c/1 seg).
{
promediar_datos(muestra_adc,&promedio_movil); //Funcion que promedia las muestras
enviar_string_uart0(" Conversion promediada= \n");
envia_u16_string_uart0((u16)(promedio_movil));
}
}
}
void promediar_datos(u16 muestras[],unsigned long int *promedio_movil)
{
u8 cont;
*promedio_movil=0;
for(cont=0;cont<MUESTRAS_MAX;cont++)
*promedio_movil+=muestras[cont];
*promedio_movil=(u16)(*promedio_movil/MUESTRAS_MAX);
}