Svolgiamo insieme Traccia misura periodo onda quadra tramite interrupt EXTI

Antò

Membro attivo
30 Maggio 2013
24
3
3
C'è una traccia sul sito della prof.ssa Liccardo che dice:

Configurare il pin PA5 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 PA5 e PF4
Configurare PF4 come sorgente di interruzione esterna
Misurare 100 volte il valore del periodo (risoluzione 1 us) del segnale prodotto da PA5 nella routine di interrupt
Visualizzare nel live watch valore medio e incertezza di categoria A

Il problema è che il DAC a volte genera correttamente sul canale due (PA5), altre no, quindi nonostante si metta il jumper su PA5 il canale da usare è il primo. Di conseguenza non viene generata nessuna interruzione su EXTI4. Se qualcuno l'ha fatta potrebbe postare la soluzione completa o, almeno, a questo problema? Grazie
 

Pietro

Membro TOP
26 Settembre 2015
30
17
3
Ciao, io ho svolto una traccia simile solo che la matricola è posta pari al periodo e non alla frequenza dell'onda quadra.
Ho generato un vettore LUT di due elementi rispettivamente 0 e 4095 e ho impostato l'ARR del timer2 pari a metà periodo dell'onda (poichè per metà periodo l'uscita è alta, per metà bassa)

C++:
/*
    Configurare il pin PA5 affinchè generi un'onda quadra di ampiezza 0-3V e periodo in us pari
    alla propria matricola sul canale OUT2. Collegare con Jumper il pin PF4.

    Configurare PF4 come sorgente di interruzione esterna (EXTI4) sul fronte di salita.

    Nella ISR abilitare il TIM6 per misurare la durata del periodo del segnale di PA5
    (ovvero misurare il tempo tra due interrupt successive) per 1000 volte.

    Visualizzare valore medio e incertezza tipo di categoria A del periodo del segnale generato.
*/

#include <stm32f30x.h>
#include <math.h>
#define N 2

void abilita();
void onda_quadra();
void timer2();      //Trigger DAC             
void timer6();          //Misura del periodo                     
void interrupt();
void setup_DAC();


int k=0;
int flag = 0;
float matricola = 472;
int LUT[N] = {0};
float periodo[1000] = {0};
float cont=0;
int i = 0;

void main()
{
    onda_quadra();
  
    abilita();
    
    setup_DAC();
    timer2();
    timer6();
  
    interrupt();
  
    while(1)
    {
        DAC->DHR12R2 = LUT[i];
      
        while((TIM2->SR & TIM_SR_UIF) != TIM_SR_UIF);
        TIM2->SR &= ~TIM_SR_UIF;
      
        i++;
      
        if(i>1)     
        {
          i=0;
        }
      
    }
  
}

void EXTI4_IRQHandler()
{
    EXTI->PR |= EXTI_PR_PR4;
  
    flag++;
  
    if(k<1000)                                                      // Calcolo mille volte il periodo
    {
        if(flag == 1)                                                  // Primo fronte di salita, parte il conteggio
        TIM6->CR1 |= TIM_CR1_CEN;
      
        if(flag != 1)                                                   // Tutti gli altri fronti di salita
        {
            TIM6->CR1 &= ~TIM_CR1_CEN;          //Fermo il timer
            cont = (TIM6->CNT)/72000000.0;      // Recupero il conteggio e quindi il tempo trascorso tra due fronti
            periodo[k] = cont;
            k++;
            TIM6->CNT = 0;                                     //Riattivo il timer
            TIM6->CR1 |= TIM_CR1_CEN;          
          
        }
    }
  
}

void abilita()
{
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOFEN;
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM6EN | RCC_APB1ENR_DACEN;
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
  
    GPIOA->MODER |= GPIO_MODER_MODER5;
    GPIOF->MODER &= ~GPIO_MODER_MODER4;
  
}

void onda_quadra()
{
    for(int i=0;i<N;i++)
    {
        if(i%2==0)
        {
          LUT[i] = 0;
        }
        else
        {
          LUT[i] = 4095;
        } 
    }
}

void timer2()
{
    TIM2->CNT = 0;
    TIM2->ARR = matricola*36;        //perchè il periodo è in us
    TIM2->CR2 |= TIM_CR2_MMS_1;
    TIM2->CR1 |= TIM_CR1_CEN;
}

void timer6()
{
    TIM6->CNT = 0; 
}

void setup_DAC()
{
    DAC->CR |= DAC_CR_TEN2;
    DAC->CR |= DAC_CR_TSEL2_2;       
    DAC->CR |= DAC_CR_EN2;
  
}

void interrupt()
{
    NVIC->ISER[0] |= (1<<10);
    SYSCFG->EXTICR[1] |= SYSCFG_EXTIRCR_EXTI4_PF;
    EXTI->IMR |= EXTI_IMR_MR4;
    EXTI->RTSR |= EXTI_RTSR_TR4;
}
 
Ultima modifica:
  • Like
Reactions: Lupo

Antò

Membro attivo
30 Maggio 2013
24
3
3
Ok credo di aver capito il mio errore.
Per abilitare la EXTIx su PF4 hai usato l'istruzione:

Codice:
SYSCFG->EXTICR[1] |= SYSCFG_EXTIRCR_EXTI4_PF;

Leggendo sul reference manual a pagina 176 riporta che SYSCFG_EXTICR2 è il registro che gestisce le interrupt sulla linea EXTI4. Perchè hai usato invece SYSCFG_EXTICR1 che gestisce dalla EXTI3 alla EXTI0?
 
  • Like
Reactions: Pietro

Antò

Membro attivo
30 Maggio 2013
24
3
3
Penso di aver capito l'ambiguità: SYSCFG->EXTICR[1] in realtà si riferisce a SYSCFG_EXTICR2.
 
  • Like
Reactions: Pietro

Seguici su Facebook