/* Traccia 1
1) Configurare il pulsante USER come sorgente di interrupt
2) Configurare il pin PA3 come ingresso analogico da collegare all'ADC
3) Configurare i pin PA1 e PA2 come output digitali di valore rispettivamente 0
e 1
4) Acquisire un campione con l'ADC in seguito alla pressione del tasto USER
5) Se la tensione misurata vale 0V impostare la durata del timer a 0.5s; se la
tensione misurata vale 3V impostare la durata del timer a 1.5s
6) Accendere i led alternativamente con intervallo di ON pari al periodo del
timer
7) Riavviare la procedura mediante nuova pressione del tasto USER */
#include <stm32f30x.h>
void abilitazione_periferiche();
void ADCsetup();
int flag=0;
float valore=0;
int i=0;
void main(){
abilitazione_periferiche();
GPIOA->MODER &= ~GPIO_MODER_MODER1; //PA0 in input digitale
GPIOA->MODER &= ~GPIO_MODER_MODER3; //PA3 in input analogico
GPIOA->MODER |= (1<<2); //PA2 in output digitale
GPIOA->MODER |= (1<<4); //PA2 in output digitale
GPIOE->MODER |= 0x55550000; //LEDs come output
SYSCFG->EXTICR[1] &= ~7;
EXTI->IMR |= EXTI_IMR_MR0;
EXTI->RTSR |= EXTI_RTSR_TR0;
NVIC->ISER[0] |= (1<<6);
ADCsetup();
TIM2->DIER |= TIM_DIER_UIE;
NVIC->ISER[0] = (1<<28);
TIM2->ARR = 36000000;
TIM2->CNT = 0;
TIM2->CR1 |= TIM_CR1_CEN;
while(1);
}
void EXTI0_IRQHandler(){
EXTI->PR |= EXTI_PR_PR0;
ADC1->CR |= ADC_CR_ADSTART;
while((ADC1->ISR & ADC_ISR_EOC) != ADC_ISR_EOC);
valore=ADC1->DR;
if(valore==0){
TIM2->ARR = 36000000;
}
else{
TIM2->ARR = 108000000;
}
}
void TIM2_IRQHandler(){
if(((TIM2->SR & TIM_SR_UIF) == TIM_SR_UIF) && flag==0){
GPIOE->ODR = 0x0000FF00;
TIM2->SR &= ~TIM_SR_UIF;
TIM2->CNT = 0;
flag=1;
}
else if(((TIM2->SR & TIM_SR_UIF) == TIM_SR_UIF) && flag==1){
GPIOE->ODR = 0x00000000;
TIM2->SR &= ~TIM_SR_UIF;
TIM2->CNT = 0;
flag=0;
}
}
void abilitazione_periferiche(){
RCC->AHBENR |= RCC_AHBENR_ADC12EN;
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
}
void ADCsetup(){
ADC1->CR &= ~ADC_CR_ADVREGEN_1;
ADC1->CR |= ADC_CR_ADVREGEN_1;
for(int i=0;i<1000;i++);
ADC1_2->CCR |= ADC12_CCR_CKMODE_0;
ADC1->CR |= ADC_CR_ADCAL;
while((ADC1->CR & ADC_CR_ADCAL) == ADC_CR_ADCAL);
ADC1->CR |= ADC_CR_ADEN;
while((ADC1->ISR & ADC_ISR_ADRD) != ADC_ISR_ADRD);
ADC1->CFGR &= ~ADC_CFGR_CONT;
ADC1->SQR1 &= ~ADC_SQR1_L;
ADC1->SQR1 |= 0x000000F0; //Abilito i canali che leggono da PA1 e PA2
ADC1->SMPR1 |= ADC_SMPR1_SMP1;
}
/*Configurare TIM6 come sorgente d interruzione. Accendere i led in successione
uno alla volta con un periodo di agg. (in ms) pari alla propria matricola.
Ad ogni pressione del tasto (con polling), l' ordine della successione dei led
deve essere modificata secondo lo schema:
1->2->3...
1->3->5...
1->5->1...
1->7->5...
1->8->7...*/
#include <stm32f30x.h>
int i=0;
int k=0;
int j=1;
void main(){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
GPIOA->MODER &= ~GPIO_MODER_MODER0;
GPIOE->MODER |= 0x55550000;
NVIC_EnableIRQ(TIM6_DAC_IRQn); //NVIC->ISER[1] |= (1<<54);
TIM6->DIER |= TIM_DIER_UIE;
TIM6->ARR = 58720;
TIM6->PSC = 2699;
TIM6->CNT = 0;
TIM6->CR1 |= TIM_CR1_CEN;
while(1){
while(!(GPIOA->IDR & GPIO_IDR_0) == GPIO_IDR_0);
while((GPIOA->IDR & GPIO_IDR_0) == GPIO_IDR_0);
if(k==3){
k=0;
}else{
k++;
} switch(k)
{ case(0):
j=1;
break;
case(1):
j=2;
break;
case(2):
j=4;
break;
case(3):
j=6;
break;
}
}
}
void TIM6_DAC_IRQHandler(void ){
TIM6->SR &= ~TIM_SR_UIF;
GPIOE->ODR =1 <<(j*(i++))%8+8;
}
/* Configurare il DAC per generare una tensione sinusoidale di ampiezza pari a
1000 cod., offset pari a 2048 e periodo (espresso in ms) pari al secondo
numero XXXX della matricola (NYY/XXXX). Si utilizzino 200 campioni per
rappresentare un periodo. La generazione deve essere temporizzata con trigger
del
timer e l'aggiornamento del campione da generare mediante DMA. Campionare tale
segnale con l'ADC facendo in modo da avere 73 campioni per ogni
periodo di sx ed acquisirne 15 periodi in un opportuno array. L'avvio della
conversione ed il salvataggio nell'array devono essere eseguite
in interrupt del Timer e dell'ADC rispettivamente.
Sui campioni acquisiti valutare valore efficace ed il periodo della sola
componente sinusoidale (senza offset).
*/
#include <stm32f30x.h>
#include <cmath>
#define PI 3.1415
#define AMPIEZZA 1000
#define OFFSET 2048
#define MATRICOLA 2202
#define N_DAC 200
#define N_ADC 73
short int sinetable[N_DAC]={0}; //array contentente i miei campione da
generare
short int risultato[N_ADC*15]={0}; //array di destinazione dopo la
convesione A/D
double sum=0; //per il calcolo valore efficace
int veff=0;
int k=0;
void abilitazione_periferiche();
void disablitazione_periferiche();
void DMA2setup_DAC(short int*, short int);
void ADCsetup();
void DACsetup();
void TIM2setup(int, int);
void TIM3setup(int, int);
void generateSine(short int,short int,short int,short int*);
double ARRDAC=0;
double ARRADC=0;
double PSCDAC=0;
double PSCADC=0;
int main(){
generateSine(AMPIEZZA,N_DAC,OFFSET,sinetable);
abilitazione_periferiche();
GPIOA->MODER |= GPIO_MODER_MODER4;
GPIOA->MODER |= GPIO_MODER_MODER2;
DACsetup();
ARRDAC=((double)MATRICOLA*pow(10,-3)*72*pow(10,6))/(double)(N_DAC*(PSCDAC+1));
TIM2setup((int)PSCDAC,(int)ARRDAC);
DMA2setup_DAC(sinetable,N_DAC);
ADCsetup();
PSCADC=999;
ARRADC=((double)MATRICOLA*pow(10,-3)*72000000)/(double)(N_ADC*(PSCADC+1));
TIM3setup((int)PSCADC,(int)ARRADC);
TIM2->CR1 |= TIM_CR1_CEN;
TIM3->CR1 |= TIM_CR1_CEN;
while(k<=1095);
ADC1->IER &= ~ADC_IER_EOC;
NVIC->ISER[0] &= ~(1<<18);
//calcolo del valore efficace
for(int k=0;k<73;k++){
sum+=pow(risultato[k]-OFFSET,2);
}
veff=(int)sqrt(((double)sum/(double)N_ADC));
return 0;
}
void generateSine(short int amp,short int n,short int offset,short int* ptr){
for(int i=0;i<n;i++){
ptr[i] = (short int)(amp*sinf(2*PI*(double)i/(double)n)+offset);
}
}
void TIM3_IRQHandler(void){
TIM3->SR &= ~TIM_SR_UIF;
ADC1->CR |= ADC_CR_ADSTART;
}
void ADC1_2_IRQHandler(void){
ADC1->ISR &= ~ADC_ISR_EOC;
if(ADC1->DR!=0 && ADC1->DR!=1)
risultato[k++]=ADC1->DR;
}
void abilitazione_periferiche(){
RCC->AHBENR |= RCC_AHBENR_ADC12EN;
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //abilito PA poichè DAC1_OUT1 <==> PA4
}
void disablitazione_periferiche(){
DAC->CR &= ~DAC_CR_EN1;
ADC1->CR |= ADC_CR_ADDIS;
TIM2->CR1 &= ~TIM_CR1_CEN;
DMA2_Channel3->CCR &= ~DMA_CCR_EN;
}
void DMA2setup_DAC(short int* src, short int n){
DMA2_Channel3->CPAR = (uint32_t) src;
DMA2_Channel3->CMAR = (uint32_t)& DAC->DHR12R1;
DMA2_Channel3-&
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
-
Misure elettriche ed elettroniche
-
Misure elettriche ed elettroniche
-
Misure elettriche ed elettroniche
-
Misure elettriche ed elettroniche