Traccia 25/05/15

sustekk

Membro
26 Novembre 2014
8
0
1
Salve a tutti, qualcuno ha la traccia di stamattina del prof Schiano e può postarla? Grazie mille ;)
 

megone

Membro
Utente Premium
13 Aprile 2015
34
19
15
Mi sono fatto mandare via email dal Prof. le 2 tracce del SMT32F4.

TRACCIA 1

Configurare il pin PD9 per generare un segnale a onda quadra (0-3V) di frequenza pari alla seconda parte della propria matricola
Es. Matr NXX/000234 --> frequenza = 234 Hz
Collegare con un jumper i pin PD9 e PD10
Configurare PD10 come sorgente di interruzione esterna
Misurare 100 volte il valore del periodo (risoluzione 1 us) del segnale prodotto da PD9 nella routine di interrupt
Visualizzare nel live watch valore medio e incertezza di categoria A

-------------------------------
TRACCIA 2

Configurare il convertitore AD per la misurazione di temperatura interna
Configurare il funzionamento con trigger (fornito da evento update di TIM2) e trasferimento dati in memoria con DMA
Configurare la seconda parte della propria matricola come intervallo di campionamento espresso in ms
Es. Matr NXX/000234 --> periodo di campionamento = 234 ms
Acquisire la temperatura per un intervallo di 10s
Visualizzare nel live watch valori acquisiti, valore medio e incertezza di categoria A


Se qualcuno riesce a svolgere magari potrebbe postare la soluzione.
 

megone

Membro
Utente Premium
13 Aprile 2015
34
19
15
Ho provato a svolgere la seconda traccia. Non avendo fisicamente lo schedino non posso testarla quindi non assicuro la correttezza. C'è qualcuno disposto a fare delle prove? Magari date un vostro parere in merito.

Codice:
/*
Configurare il convertitore AD per la misurazione di temperatura interna
Configurare il funzionamento con trigger (fornito da evento update di TIM2) e trasferimento dati in memoria con DMA
Configurare la seconda parte della propria matricola come intervallo di campionamento espresso in ms
    Es. Matr NXX/000234 --> periodo di campionamento = 234 ms
Acquisire la temperatura per un intervallo di 10s
Visualizzare nel live watch valori acquisiti, valore medio e incertezza di categoria A


SOLUZIONE ADOTTATA: si configura il TIM2 per contare a una frequenza di 1 MHz quindi con risoluzione di 1 us.
(considerando come Clock di base HSI a 16MHz e settando Prescaler a 15). Ad ogni numero di
millisecondi corrispondente alla matricola (nell'esempio 234 ms) il Counter raggiunge il valore di ARR e genera un trigger TRGO
che viene recepito come segnale di start dall'ADC1. Ogni volta che si resetta il counter viene incrementato un indice che serve
per contare i 10 secondi (questo per evitare l'uso di un altro timer da sincronizzare).
A quel punto spengo il timer e faccio i calcoli richiesti.

ALTERNATIVA: il conto degli N cicli per raggiungere i 10 secondi, invece che con 2 while può essere gestito in una routine TIM2_IRQHandler
che viene eseguita ad ogni evento di update, quindi ogni volta che viene generato il trigger.
*/

#include "stm32f4xx.h"

#define MATRICOLA 234
#define N 10000/MATRICOLA               //contando in ms, 10 sec = 10000 ms, che si raggiungono dopo N misurazioni

int media;
int i=0;
int incertezza;
short int buffer[N];

int main (void){
//N=(10000/MATRICOLA)
 
//ATTIVAZIONE PERIFERICHE
RCC->APB2ENR |= 1<<8;    //ADC1
RCC->APB1ENR |= 1;     //TIM2
RCC->AHB1ENR |= 1<<21;    //DMA1

//CONFIG DMA1

DMA1_Stream0->CR |= 1<<13;    //MSIZE a 16bit
DMA1_Stream0->CR |= 1<<11;    //PSIZE a 16bit
DMA1_Stream0->CR |= 1<<10;    //MINC
DMA1_Stream0->CR |= 1<<5;    //controllo del DMA affidato alla periferica (in questo caso TIM2)
DMA1_Stream0->NDTR = N;
DMA1_Stream0->PAR = (uint32_t)(&ADC1->DR);
DMA1_Stream0->M0AR = (uint32_t) buffer;

//CONFIG ADC1

ADC1->CR2 |= 6<<24;    //seleziono Trigger TRGO di TIM2
ADC1->CR2 |= 1<<28;    //attivo su fronte di salita
ADC1->SQR3 |= 0x10;     // canale 16 (o 18) - 1° in sequenza
ADC1->CR2 |= 1<<8;    //DMA
ADC1->CR2 |= 1<<9;    //DDS

DMA2_Stream0->CR |= 1; //ABILITO LO STREAM0

ADC1->CR2 |= 1;        //Accendo ADC
ADC->CCR |= 1<<23;    //Accendo Sens Temp.

//CONFIG TIM2

TIM2->PSC =0xF;            //Timer clock a 1MHz (16/(15+1))
TIM2->ARR = MATRICOLA*1000;     //visto che a 1 MHz ogni ciclo dura 1 us, moltiplico per 1000 per contare in ms
TIM2->CR2 |= 1<<5;        //Trigger TRGO in corrispondenza di Update
TIM2->CR1 |= 1;            //Inizia il conteggio       

    while (i!=N){               
                        //si conta ogni volta che il Counter viene azzerato
        while (TIM2->CNT != 0){}    //finchè non si raggiunge il numero di misurazioni
                        //che si contano in 10 secondi (10000/MATRICOLA)
        i++;
    }

TIM2->CR1 |= 0;            //spengo il timer

//media
    for(i=0; i<N; i++) {
        media=media+buffer[i];
        media=media/N;
    }

   
//incertezzaA
    for (i=0; i<N; i++){
        incertezza=incertezza+pow(buffer[i]-media,2);
        incertezza=pow(incertezza/N, 0.5);
    }

while(1);

}
 
  • Like
Reactions: poel
2 Giugno 2015
2
1
3
Ho provato a svolgere la seconda traccia. Non avendo fisicamente lo schedino non posso testarla quindi non assicuro la correttezza. C'è qualcuno disposto a fare delle prove? Magari date un vostro parere in merito.

Codice:
/*
Configurare il convertitore AD per la misurazione di temperatura interna
Configurare il funzionamento con trigger (fornito da evento update di TIM2) e trasferimento dati in memoria con DMA
Configurare la seconda parte della propria matricola come intervallo di campionamento espresso in ms
    Es. Matr NXX/000234 --> periodo di campionamento = 234 ms
Acquisire la temperatura per un intervallo di 10s
Visualizzare nel live watch valori acquisiti, valore medio e incertezza di categoria A


SOLUZIONE ADOTTATA: si configura il TIM2 per contare a una frequenza di 1 MHz quindi con risoluzione di 1 us.
(considerando come Clock di base HSI a 16MHz e settando Prescaler a 15). Ad ogni numero di
millisecondi corrispondente alla matricola (nell'esempio 234 ms) il Counter raggiunge il valore di ARR e genera un trigger TRGO
che viene recepito come segnale di start dall'ADC1. Ogni volta che si resetta il counter viene incrementato un indice che serve
per contare i 10 secondi (questo per evitare l'uso di un altro timer da sincronizzare).
A quel punto spengo il timer e faccio i calcoli richiesti.

ALTERNATIVA: il conto degli N cicli per raggiungere i 10 secondi, invece che con 2 while può essere gestito in una routine TIM2_IRQHandler
che viene eseguita ad ogni evento di update, quindi ogni volta che viene generato il trigger.
*/

#include "stm32f4xx.h"

#define MATRICOLA 234
#define N 10000/MATRICOLA               //contando in ms, 10 sec = 10000 ms, che si raggiungono dopo N misurazioni

int media;
int i=0;
int incertezza;
short int buffer[N];

int main (void){
//N=(10000/MATRICOLA)

//ATTIVAZIONE PERIFERICHE
RCC->APB2ENR |= 1<<8;    //ADC1
RCC->APB1ENR |= 1;     //TIM2
RCC->AHB1ENR |= 1<<21;    //DMA1

//CONFIG DMA1

DMA1_Stream0->CR |= 1<<13;    //MSIZE a 16bit
DMA1_Stream0->CR |= 1<<11;    //PSIZE a 16bit
DMA1_Stream0->CR |= 1<<10;    //MINC
DMA1_Stream0->CR |= 1<<5;    //controllo del DMA affidato alla periferica (in questo caso TIM2)
DMA1_Stream0->NDTR = N;
DMA1_Stream0->PAR = (uint32_t)(&ADC1->DR);
DMA1_Stream0->M0AR = (uint32_t) buffer;

//CONFIG ADC1

ADC1->CR2 |= 6<<24;    //seleziono Trigger TRGO di TIM2
ADC1->CR2 |= 1<<28;    //attivo su fronte di salita
ADC1->SQR3 |= 0x10;     // canale 16 (o 18) - 1° in sequenza
ADC1->CR2 |= 1<<8;    //DMA
ADC1->CR2 |= 1<<9;    //DDS

DMA2_Stream0->CR |= 1; //ABILITO LO STREAM0

ADC1->CR2 |= 1;        //Accendo ADC
ADC->CCR |= 1<<23;    //Accendo Sens Temp.

//CONFIG TIM2

TIM2->PSC =0xF;            //Timer clock a 1MHz (16/(15+1))
TIM2->ARR = MATRICOLA*1000;     //visto che a 1 MHz ogni ciclo dura 1 us, moltiplico per 1000 per contare in ms
TIM2->CR2 |= 1<<5;        //Trigger TRGO in corrispondenza di Update
TIM2->CR1 |= 1;            //Inizia il conteggio      

    while (i!=N){              
                        //si conta ogni volta che il Counter viene azzerato
        while (TIM2->CNT != 0){}    //finchè non si raggiunge il numero di misurazioni
                        //che si contano in 10 secondi (10000/MATRICOLA)
        i++;
    }

TIM2->CR1 |= 0;            //spengo il timer

//media
    for(i=0; i<N; i++) {
        media=media+buffer[i];
        media=media/N;
    }

  
//incertezzaA
    for (i=0; i<N; i++){
        incertezza=incertezza+pow(buffer[i]-media,2);
        incertezza=pow(incertezza/N, 0.5);
    }

while(1);

}
L'ho testato e il programma in sé funziona e condivido il ragionamento, ma dopo le acquisizioni i valori di media e incertezza mi sembrano sballati. O forse sono io impedito, sia chiaro!
 
  • Like
Reactions: poel

Seguici su Facebook