viernes, 27 de septiembre de 2013

Conversor analógico digital en la STM32F0Discovery

Siguiendo con la programación del ARM Cortex M0, una vez visto el manejo de los puertos, y como utilizar los temporizadores, lo siguiente es como adquirir señales analógicas del exterior, en este caso, nuestra señal externa será la tensión del cursor de un potenciometro. Para hacer un código un poco, solo un poco, más complejo, vamos a mezclar el ultimo código que os puse, en el cual controlábamos el ciclo de trabajo de una señal PWM, pero ahora el ciclo de trabajo lo controlaremos directamente desde una entrada analógica.

El conversor que lleva el Cortex M0 está muy completo, además de llevar lo que llevan casi todos los micros (diferentes canales, diferentes formas de disparo, diferentes formas de leer los canales...), dispone de otras características un poco más especiales, como por ejemplo, poder elegir la resolución que queremos, pudiendo aumentar la velocidad de adquisición para resoluciones bajas. Ademas de los canales externos, 16 para el STM32F0, dispone de 3 canales internos los cuales monitorizan un sensor de temperatura, la tensión de referencia del conversor, y la tensión de la batería, en caso de que alimentemos el sistema desde una pila por ejemplo.
A continuación os dejo un vídeo explicativo


Y a continuación os dejo el código completo.
//=============================================================================
// Autor: P.Trujillo
// mipsandchips.blogspot.com.es
// Lectura de un canal analógico sin interrupción
//=============================================================================
 
#include "stm32f0xx.h"
 
//=============================================================================
// aux functions
//=============================================================================


//=============================================================================
// global vars
//=============================================================================
int dc = 50;

//=============================================================================
// main function
//=============================================================================
int main(void)
{ 
   
  RCC->AHBENR |= RCC_AHBENR_GPIOCEN ;  //Habilitamos el reloj para el puerto C
 RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;  //Habilitamos el reloj para el timer 3
  RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //Habilitamos el reloj para el ADC
 
  GPIOC->MODER = GPIO_MODER_MODER8_1; //Puerto C8 como salida PWM
  GPIOA->MODER = GPIO_MODER_MODER0; // Puerto A0 como analógico
 
 TIM3->PSC = 12;
 TIM3->ARR = 4096; // Configuramos el valor de recarga con el valor máximo de la conversión
 TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE;
 TIM3->CCER = TIM_CCER_CC3E;
 TIM3->CR1 |= TIM_CR1_CEN;
 TIM3->CCR3 = 0;
 
 // Calibrar ADC
 ADC1->CR &= ADC_CR_ADCAL ;
 while(ADC1->CR &= ADC_CR_ADCAL);
 
 ADC1->CR = ADC_CR_ADEN;
 ADC1->CHSELR = ADC_CHSELR_CHSEL0; // Seleccionaoms el canal 0
 ADC1->CFGR1 = ADC_CFGR1_CONT;
 ADC1->CR = ADC_CR_ADSTART;
  
 
  while (1) {
    dc = ADC1->DR;
  TIM3->CCR3 = dc;
      
  }
}

No hay comentarios:

Publicar un comentario