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.
vuoi
o PayPal
tutte le volte che vuoi
/*TRACCIA:
DAC che genera un segnale sinusoidale sul pin 2 prendendo 100 campioni da un
vettore in memoria (LUT) tramite DMA.
Il segnale viene trasferito sul pin 4 tramite un jumper e viene convertito in
digitale dall'ADC, che trasferirà poi i
100 campioni in un secondo vettore (LUT2), sempre tramite DMA. (Viene usato il
TIMER2 per gestire entrambi i dispositivi)
La conversione viene avviata tramite Interrupt sulla linea PA0 premendo il
tastino USER e si ferma quando il tasto USER viene
premuto nuovamente; durante tutta l'operazione, i LED si accenderanno
alternativamente a rappresentare l'operatività del
programma (si spegnaranno quando la conversione viene fermata)
*/
#include <stm32f30x.h>
#include <math.h>
#include <stdbool.h>
#define N 100
#define PI 3.14
void abilitazione_periferiche();
void sin_gen(float);
void ADCsetup();
void DACsetup();
void DMA1_setup();
void DMA2_setup();
void TIM2setup();
void TIM3setup();
short int LUT[N];
short int LUT2[N];
_Bool parti = false;
int i=8;
void main(){
sin_gen(1.3);
abilitazione_periferiche();
GPIOE->MODER |= 0x55555555;
ADCsetup();
DACsetup();
DMA1_setup();
DMA2_setup();
SYSCFG->EXTICR[1] &= ~7;
EXTI->IMR |= EXTI_IMR_MR0;
EXTI->RTSR |= EXTI_RTSR_TR0;
NVIC->ISER[0] |= (1<<6);
TIM2setup();
TIM3setup();
TIM2->CR1 |= 1;
while(1){
if(parti==true){
ADC1->CR |= ADC_CR_ADSTART;
while((ADC1->ISR & ADC_ISR_EOC) != ADC_ISR_EOC);
}
}
}
void EXTI0_IRQHandler(){
EXTI->PR |= EXTI_PR_PR0;
parti=!parti;
if(parti==true){
TIM2->CR1 |= TIM_CR1_CEN;
TIM3->CR1 |= TIM_CR1_CEN;
}else{
TIM2->CR1 &= ~TIM_CR1_CEN;
TIM3->CR1 &= ~TIM_CR1_CEN;
}
}
void TIM3_IRQHandler(){
TIM3->SR &= ~TIM_SR_UIF;
GPIOE->ODR = (1<<i);
i++;
if(i>15) i=8;
}
void sin_gen(float ampiezza){
float Vsin;
for(int i=0;i<N;i++){
Vsin = 1.5+ampiezza*sin(2*PI*i/N);
LUT[i] = (short int)(Vsin*4095.0/3.0);
}
}
void abilitazione_periferiche(){
RCC->AHBENR |= RCC_AHBENR_ADC12EN;
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->AHBENR |= RCC_AHBENR_GPIOEEN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
}
void ADCsetup(){
ADC1->CR &= ~ADC_CR_ADVREGEN_1;
ADC1->CR |= ADC_CR_ADVREGEN_0;
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->CFGR |= ADC_CFGR_DMAEN;
ADC1->CFGR |= ADC_CFGR_EXTEN_0;
ADC1->CFGR |= (11<<6);
ADC1->SQR1 |= (3<<6);
ADC1->SQR1 &= ~ADC_SQR1_L;
ADC1->SMPR1 |= ADC_SMPR1_SMP3;
}
void TIM3setup(){
TIM3->ARR = 60000;
TIM3->PSC = 60;
TIM3->DIER |= TIM_DIER_UIE;
NVIC->ISER[0] |= (1<<29);
}
void DACsetup(){
DAC->CR |= DAC_CR_EN1;
DAC->CR |= DAC_CR_TEN1;
DAC->CR |= DAC_CR_TSEL1_2;
DAC->CR |= DAC_CR_DMAEN1;
}
void TIM2setup(){
TIM2->ARR = 72000000;
TIM2->CR2 |= TIM_CR2_MMS_1;
}
void DMA1_setup(){
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
DMA1_Channel1->CMAR = (uint32_t)LUT2;
DMA1_Channel1->CNDTR = N;
DMA1_Channel1->CCR &= ~DMA_CCR_DIR;
DMA1_Channel1->CCR |= DMA_CCR_MINC;
DMA1_Channel1->CCR |= DMA_CCR_PSIZE_0;
DMA1_Channel1->CCR |= DMA_CCR_MSIZE_0;
DMA1_Channel1->CCR |= DMA_CCR_EN;
}
void DMA2_setup(){
DMA2_Channel3->CPAR = (uint32_t)&DAC->DHR12R1;
DMA2_Channel3->CMAR = (uint32_t)LUT;
DMA2_Channel3->CNDTR = N;
DMA2_Channel3->CCR |= DMA_CCR_DIR;
DMA2_Channel3->CCR |= DMA_CCR_MINC;
DMA2_Channel3->CCR |= DMA_CCR_CIRC;
DMA2_Channel3->CCR |= DMA_CCR_PSIZE_0;
DMA2_Channel3->CCR |= DMA_CCR_MSIZE_0;
DMA2_Channel3->CCR |= DMA_CCR_EN;
}
/* Accendere uno alla volta i led ogni due secondi poi, ogni volta che premi il
tasto user, il tempo si dimezza, quindi 1 secondo ,
poi mezzo secondo ed infine 250 ms.
Dopodichè ,premendo ancora,il tempo torna a 2 secondi,poi 1 secondo ecc */
#include <stm32f30x.h>
int i=0;
void main(){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //Abilitazione GPIOA
RCC->AHBENR |= RCC_AHBENR_GPIOEEN; //Abilitazione GPIOE
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; //Abilitazione TIM2
GPIOA->MODER &= ~GPIO_MODER_MODER0; //Abilitazioned PAO come input
GPIOE->MODER |= 0x55550000; //Abilitazione LEDs come output
SYSCFG->EXTICR[1] &= ~7;
EXTI->IMR |= EXTI_IMR_MR0;
EXTI->RTSR |= EXTI_RTSR_TR0;
NVIC->ISER[0] |= (1<<6) | (1<<28);
TIM2->DIER |= TIM_DIER_UIE;
TIM2->ARR = 144000000;
TIM2->PSC = 0;
TIM2->CR1 |= TIM_CR1_ARPE; //ARR Bufferizzato
TIM2->CNT = 0;
TIM2->CR1 |= TIM_CR1_CEN;
while(1);
}
void EXTI0_IRQHandler(){
EXTI->PR |= EXTI_PR_PR0;
if((TIM2->ARR)>= 36000000){
TIM2->ARR=(TIM2->ARR)/2;
}
else{
TIM2->ARR = 144000000;
}
}
void TIM2_IRQHandler(void ){
TIM2->SR &= ~TIM_SR_UIF ; //Azzero UIF
GPIOE->ODR = 1<<(i++%8)+8; //Accendo i led uno alla volta
}
/*Utilizzare il pulsante USER come sorgente di interruzione. Ad ogni pressione
generare col DAC un nuovo valore di tensione pari al precedente
aumentato della matricola. Acquisire tale tensione con l' ADC e visualizzarla in
LIVE WATCH*/
#include <stm32f30x.h>
#define MATRICOLA 2202
int tensione=0;
void abilitazione_periferiche();
void ADCsetup();
void DACsetup();
void main(){
abilitazione_periferiche();
GPIOA->MODER |= GPIO_MODER_MODER2 | GPIO_MODER_MODER4;
GPIOA->MODER &= ~GPIO_MODER_MODER0;
ADCsetup();
DACsetup();
SYSCFG->EXTICR[1] &= ~7;
EXTI->IMR |= EXTI_IMR_MR0;
EXTI->FTSR |= EXTI_FTSR_TR0;
NVIC->ISER[0] |= (1<<6);
while(1);
}
void EXTI0_IRQHandler(){
EXTI->PR |= EXTI_PR_PR0;
DAC->DHR12R1 += MATRICOLA; //CARICO IN VALORE NEL REGISTRO DHR DAC
for(int i=0;i<20;i++);
ADC1->CR |= ADC_CR_ADSTART;
while((ADC1->ISR & ADC_ISR_EOC)!= ADC_ISR_EOC);
tensione = (ADC1->DR);
}
void abilitazione_periferiche(){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->AHBENR |= RCC_AHBENR_ADC12EN;
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
}
void ADCsetup(){
ADC1->CR &= ~ADC_CR_ADVREGEN_1;
ADC1->CR |= ADC_CR_ADVREGEN_0;
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 |= (3<<6);
ADC1->SMPR1 |= ADC_SMPR1_SMP3;
}
void DACsetup(){
DAC->CR |= DAC_CR_EN1;
}
/*Programma che accende un led alla volta alla pressione del tasto USER*/
#include <stm32f30x.h>
int i=0;
void main(){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN;
GPIOA->MODER &= ~GPIO_MODER_MODER0;
GPIOE->MODER |= 0x55550000;
SYSCFG->EXTICR[1] &= ~7;
EXTI->IMR |= EXTI_IMR_MR0;
EXTI->RTSR |= EXTI_RTSR_TR0;
NVIC->ISER[0] |= (1<<6);
while(1);
}
void EXTI0_IRQHandler(){
EXTI->PR |= EXTI_PR_PR0;
GPIOE->ODR = 1<<(i++%8)+8;
}
/* Configurare l' ADC per campionare ogni secondo 2 canali d ingresso
selezionabili alternativamente mediante PA0.
In particolare, devono essere acquisiti i canali collegati al sensore di
temperatura e alla batteria.
Visualizzare i valori misurati mediante LIVE WATCH, facendo in modo che il
canale inattivo indichi un codice pari alla propria matricola */
#include "stm32f30x.h"
#define MATRICOLA 700
int temperatura=0;
int vts=0;
float v25= 1.43*1000;
float avg_slope= 4.3;
int batteria=0;
void main()
{ //ABILITO PA0 E CONFIG. INTERRUPT
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
EXTI->IMR |= EXTI_IMR_MR0;
NVIC->ISER[0] |= 1 <<6;
EXTI->RTSR |= EXTI_RTSR_TR0;
//ABILITO E CONFIG. TIMER 2
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->ARR = 72000000;
TIM2->PSC = 0;
TIM2->DIER |= TIM_DIER_UIE;
NVIC->ISER[0] |= 1 <<28;
//ABILITO E CONFIG. ADC
RCC->AHBENR |= RCC_AHBENR_ADC12EN;
ADC1_2->CCR |= ADC12_CCR_CKMODE_0;
ADC1->CR &= ~ADC_CR_ADVREGEN_1;
ADC1->CR |= ADC_CR_ADVREGEN_0;
for(int i=0;i<10000;i++);
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);
//ABILITO SENSORE TEMPERATURA E BATTERIA
ADC1_2->CCR |= ADC12_CCR_TSEN | ADC12_CCR_VBATEN;
//AVVIO IL TIMER
TIM2->CR1 |= TIM_CR1_CEN;
while(1);
}
int flag=1;
void TIM2_IRQHandler(){
//TIM2->SR &= ~TIM_SR_UIF; senza funziona lo stesso.
if(flag){
batteria=MATRICOLA;
ADC1->SQR1 =16 <<6; //IMPOSTO CANALE 16 (SENSORE DI TEMPERATURA)
ADC1->SMPR2 |= ADC_SMPR2_SMP16; //SAMPLE TIME SUL CANALE 16 AL MAX
ADC1->CR |= ADC_CR_ADSTART; //AVVIO LA CONVERSIONE
while((ADC1->ISR & ADC_ISR_EOC)!= ADC_ISR_EOC); //ATTENDO FINE CONVERSIONE
vts=(ADC1->DR *3000)/4096; //CONVERTO IN mV
temperatura=(int)((v25-vts)/avg_slope)+25; //CONVERTO TENSIONE IN TEMP.
}else{
temperatura=MATRICOLA;
ADC1->SQR1 =17 <<6; //IMPOSTO CANALE 17 (BATTERIA)
ADC1->SMPR2 |= ADC_SMPR2_SMP17; //SAMPLE TIME SUL CANALE 17 AL MAX
ADC1->CR |= ADC_CR_ADSTART; //AVVIO LA CONVERSIONE
while((ADC1->ISR & ADC_ISR_EOC)!= ADC_ISR_EOC); //ATTENDO FINE CONVERSIONE
batteria=ADC1->DR; //BATTERIA IN LIVE WATCH
}
}
void EXTI0_IRQHandler(){
EXTI->PR |= EXTI_PR_PR0;
if(flag){
flag=0;
}else{
flag=1;
}
}
/* Sensore di temperatura, led blu per temperatura bassa , led rosso per
temperatura alta */
#include "stm32f30x.h"
int VTS =0; //tensione misurata
int Temperature = 0; //temperatura rilevata
float V25 =1.43*1000;
float Avg_Slope=4.3;
void led_adc_en();
void setim_ie(int arr,int psc,int cnt,int IRQn);
void setim(int ar