programmi MAPI svolti

Remo Guido

Membro TOP
Utente Premium
7 Luglio 2014
31
1
5
8
ADC + DMA + TIMER
PHP:
//misurare ogni secondo la temperatura tramite sensore interno dello schedino
//spostare dall'adc->dr in un vettore di 10 elementi, calcolare incertezza di tipo a
#include "stm32f4xx.h"
#define N 10
short buffer[N]={0};

int main(){
  //abilitiamo le periferiche tim2 dma2 adc1
  RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
  RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
 
  //configuro il timer tim2
  TIM2->ARR = 36000000;
  TIM2->CR2 |= TIM_CR2_MMS_1;
 
  //configuro adc1
  ADC1->CR2 |= ADC_CR2_EXTEN_0 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_2 | ADC_CR2_DDS | ADC_CR2_DMA | ADC_CR2_EOCS;
  ADC1->SMPR1 |= ADC_SMPR1_SMP16_0 | ADC_SMPR1_SMP16_1 | ADC_SMPR1_SMP16_2;
  ADC1->SQR3 |= 16;
  ADC->CCR |= ADC_CCR_TSVREFE;
 
  //configuro il dma2
  DMA2_Stream0->CR |= DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_CIRC;
  DMA2_Stream0->NDTR = N;
  DMA2_Stream0->PAR = (uint32_t) (&(ADC1->DR));
  DMA2_Stream0->M0AR = (uint32_t) (buffer);
 
 

 
  ADC1->CR2 |= ADC_CR2_ADON;
  TIM2->CR1 |= TIM_CR1_CEN;
  ADC1->CR2 |= ADC_CR2_SWSTART;
  DMA2_Stream0->CR |= DMA_SxCR_EN;
  while(1);
 
}
 

Remo Guido

Membro TOP
Utente Premium
7 Luglio 2014
31
1
5
8
ADC1 + conversione
PHP:
#include "stm32f4xx.h"

/*      TRACCIA:

Configurare EXTI0-PA0 come sorgente di interrupt con fronte di salita attivo. Configurare PA1 e PA2 come output digitale ed impostare
valore logico alto e basso rispettivamente. Configurare l'ADC per acquisire sul canale 3 e come sorgente di interrupt. Nella routine
di interrupt di EXTI0 avviare la conversione dell'ADC. Visualizzare il valore espresso in Volt nel LIVEWATCH.

        Informazioni aggiuntive:
Impostare PA1 e PA2 su 2 livelli diversi (uno al livello logico basso ed un alto) in modo tale da poter effettuare 2 conversioni diverse
collegando il jumper tra PA1-PA3 e tra PA2-PA3 (Una mi deve dare tensione alta e una bassa).    */

int tensione ;        //lo scegliamo short perchË il valore misurato con la conversione Ë 12 bit. (ADC)
float tensioneVolt = 0.0;     //Per la tensione in Volt Ë necessario il tipo float, andr‡ fatto quindi il casting


int main() {

  RCC->AHB1ENR |= 1;            //Abilitiamo la porta A, ovvero il pulsante (PA0) e PA1 PA2
 
  //RCC->APB2ENR |= 1<<14;
  //SYSCFG->EXTICR[0] &= 0x0;      //E' inutile poichË Ë gi‡ cosÏ di default
 
  EXTI->RTSR |= 1;              //Inizio codice INTERRUPT
  EXTI->IMR |= 1;
  NVIC->ISER[0] |= 1<<6;
                                //Inizio codice ADC
  RCC->APB2ENR |= 1<<8;        
  ADC1->CR2 |= (1 | 1<<10);     //In realt‡ il bit EOCS (ed anche EOC) non ci servir‡
  //ADC1->SMPR2 |= 0x7<<9;      //Non sono state fatte richieste riguardo la velocit‡ (cioË la precisione della misura)
  //ADC1->SQR1 &= 0x0<<20;      //Gi‡ cosÏ di default
  ADC1->SQR3 |= 0x3;            //La prima (e unica) conversione deve avvenire sul canale 3 (Quello collegato a PA3 !!! )
 
                                //Inizio codice PORTE PA1 e PA2 (La porta A Ë gi‡ abilitata con RCC->AHB1ENR (prima istruzione))
  GPIOA->MODER |= 0x5<<2;       //Imposto PA1 e PA2 come general purpose output mode (per l'output digitale)
  GPIOA->MODER |= 0x3<<6;       //DEVO IMPOSTARE IL PIN PA3 IN ANALOG MODE(lÏ farÚ il confronto con le due tensioni PA1 e PA2)
  GPIOA->ODR |= 1<<1;  //Devo abilitare l'ODR della porta di output digitale che mi deve alzare la tensione
 
  GPIOA->PUPDR |= (1<<2|1<<5);  //Imposto PA2 per il pull-up (tensione alta) e PA1 per il pull-down (tensione bassa)
 
  while(2){};                   //Programma non deve terminare (uso il while True)
   
}

void EXTI0_IRQHandler (){

  EXTI->PR |= 1;
 
  ADC1->CR2 |= 1<<30;           //Start conversion
 
  tensione = ADC1->DR;
  tensioneVolt = (float) (tensione*3)/4095;       //La conversione in volt Ë valore *3/4096, DEVO FARE IL CAST

}
 

Seguici su Facebook