Informazioni MAPI Liccardo

Danny 92

Membro
25 Febbraio 2015
10
4
3
Buongiorno ragazzi , non avendo seguito il corso di Liccardo sono in difficolta ;

io sto usando lo schedino F3 , è quello giusto per fare l'esame o è indifferente usare F3 o F4?

inoltre non riesco a trovare un programma per lo schedino , in particolare non ho capito
se devo imparare ad usare SPI I2C giroscopio e accelerometro . grazie
 

Daviducci0

Membro
14 Marzo 2015
3
2
3
Puoi usare sia lo schedino F3 o F4. Se sei uno studente in corso per lo schedino F3 devi studiare I2C e DMA. Invece se hai seguito il corso dell'F3 di alcuni anni fa devi studiare SPI(temperatura+giroscopio) e I2C.
 
  • Like
Reactions: Danny 92

marchello

Membro
9 Aprile 2014
8
4
3
In realtà puoi scegliere se fare l'esame con l'F3 o con l'F4, Se porti l'F3 devi usare solo il protocollo I2C per comunicare con l'accelerometro. Mentre se scegli F4 devi farti sia SPI che I2C (giroscopio e accelerometro)

P.S Io sono più uno studente in corso ho fatto l'esame con l'F3 portando il programma di quest'anno
 
  • Like
Reactions: Danny 92

Danny 92

Membro
25 Febbraio 2015
10
4
3
Grazie ragazzi , ne approfitto per chiedervi se avete materiale relativo all accelerometro per l F3 , grazie
 

marchello

Membro
9 Aprile 2014
8
4
3
PHP:
#include "stm32f30x.h"

int config[3]={0x47,0x00,0x00};
int configData[3]={0};
int accData[6]={0};
int x=0;
int y=0;
int z=0;
void main()
{
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;  //Abilito GPIOB
GPIOB->MODER |= GPIO_MODER_MODER6_1|GPIO_MODER_MODER7_1;  //PB6 ==I2C1_SCL e PB7==I2C1_SDA in Alternate mode p. 41 - STM32F3Datasheet.pdf
GPIOB->AFR[0] |= 4 <<24 |4<<28;  //Associo l'alternate function AF4 a PA6 e PA7, perchè p. 44 - STM32F3Datasheet.pdf, p. 148 - STM32F3RefMan.pdf
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;  //Abilito segnale di clock per I2C
//Configurazione TIMNGR Table 84. Examples of timings settings for fI2CCLK = 8 MHz - 100kz p. 684 - STM32F3RefMan.pdf
I2C1->TIMINGR |= 0x10420F13;
I2C1->CR1 |= I2C_CR1_PE; //Abilitazione periferica I2C
/*[ Master in Trasmissione (scrittura)] - Configurazione dei registri dell'Accelerometro*/
/*In particolare voglio configurare il seguenti registri:
[+] CTRL_REG1_A (20h) == 0b01000111 == 0x47 --> ODR a 50Hz Normal Mode
[+] CTRL_REG2_A (21h) == 0b00000000 == 0x00 --> Nessun filtro
[+] CTRL_REG3_A (22h) == 0b00000000 == 0x00 --> Nessuna interruzione
NOTA: Per non ripetere sempre le stesse istruzioni attiviamo l'autoincrement:
Basta prendere l'indirizzo di partenza 0x20 nel nostro caso e aggiungere un uno nel MSB
0x20 == 00100000;
0x80 == 10000000;
faccio 0x20|0x80 = 0xA0
*/
while((I2C1->ISR & I2C_ISR_BUSY)==I2C_ISR_BUSY); //Mi assicuro che la periferica non sia nello stato Busy
I2C1->CR2 &=~I2C_CR2_NBYTES;  //Pulisco il sottoregistro NBYTES di CR2 potrebbe essere stato sporcato da operazioni precedenti
I2C1->CR2 |= 4 << 16;  //Specifico il numero di byte da trasferire compreso il SUBADD (indirizzo del sottoregistro) in questo caso 4
I2C1->CR2 |= (uint8_t)0x19 <<1;  //Specifico l'indirizzo dello Slave/Accelerometro 0b0011001==0x19  <<1 perchè il bit 0 è don't care
I2C1->CR2 &=~I2C_CR2_RD_WRN;  //Specifico di voler effettuare un'operazione di scrittura (WRN==0)
I2C1->CR2 |= I2C_CR2_START;  //Do il comando di Start
while((I2C1->ISR & I2C_ISR_TXE)!=I2C_ISR_TXE);  //Mi assicuro che il Transmit data register sia vuoto
I2C1->TXDR = (0x20|0x80);  //Trasmetto l'indirizzo del sottoregistro (SUBADD) con autoincremento
//Trasmetto i 3 Dati
for(int j=0;j<3;j++)
{
while((I2C1->ISR & I2C_ISR_TXE)!= I2C_ISR_TXE);  //Mi assicuro che il Transmit data register sia vuoto
I2C1->TXDR = config[j];  //Trasmetto il dato
}
while(( I2C1->ISR & I2C_ISR_TC)!=I2C_ISR_TC);  //Attendo il Transfer Complete
I2C1->CR2 |= I2C_CR2_STOP;  //Do lo Stop
while((I2C1->ISR & I2C_ISR_STOPF)!=I2C_ISR_STOPF);  //Attendo lo Stop flag
I2C1->ICR |= I2C_ICR_STOPCF;  //Pulisco il Stop flag


/* Master in ricezione(lettura)] Voglio leggere le componenti dell'accelerazione lungo gli assi.
Devo leggere i seguenti valori dai seguenti sottoregistri. (Versione Con STOP START (no restart))
[+] OUT_X_L_A (28h), OUT_X_H_A (29h)
[+] OUT_Y_L_A (2Ah), OUT_Y_H_A (2Bh)
[+] OUT_Z_L_A (2Ch), OUT_Z_H_A (2Dh)*/
while(1)//Aggiorno continuamente i valori
{
while((I2C1->ISR & I2C_ISR_BUSY)==I2C_ISR_BUSY);  //Mi assicuro che la periferica non sia nello stato Busy
I2C1->CR2 &=~I2C_CR2_NBYTES;  //Pulisco il sottoregistro NBYTES di CR2 potrebbe essere stato sporcato da operazioni precedenti
I2C1->CR2 |= 1 <<16;  //Specifico il numero di byte da trasferire compreso il SUBADD (indirizzo del sottoregistro) in questo caso 1
I2C1->CR2 |= (0x19 <<1);  //Specifico l'indirizzo dello Slave/Accelerometro 0b0011001==0x19  <<1 perchè il bit 0 è don't care
I2C1->CR2 &=~I2C_CR2_RD_WRN;  //Specifico di voler effettuare un'operazione di scrittura (WRN==0)
I2C1->CR2 |= I2C_CR2_START;  //Do il comando di Start
while((I2C1->ISR & I2C_ISR_TXE)!=I2C_ISR_TXE);  //Mi assicuro che il Transmit data register sia vuoto
I2C1->TXDR = (0x28|0x80);  //Trasmetto l'indirizzo del sottoregistro (SUBADD) da cui voglio leggere con autoincremento
while(( I2C1->ISR & I2C_ISR_TC)!=I2C_ISR_TC);  //Attendo direttamente il Transfer Complete perchè sto inviando un solo byte
I2C1->CR2 |= I2C_CR2_STOP;  //Do lo Stop
while((I2C1->ISR & I2C_ISR_STOPF)!=I2C_ISR_STOPF);  //Attendo lo Stop flag
I2C1->ICR |= I2C_ICR_STOPCF;  //Pulisco il Stop flag
I2C1->CR2 |= (0x19 <<1);  //Rispecifico l'indirizzo dello Slave/Accelerometro 0b0011001==0x19  <<1 perchè il bit 0 è don't care
I2C1->CR2 |=I2C_CR2_RD_WRN;  //Specifico di voler effettuare un'operazione di lettura (WRN==1)
I2C1->CR2 &=~I2C_CR2_NBYTES;  //Pulisco il sottoregistro NBYTES di CR2 potrebbe essere stato sporcato da operazioni precedenti
I2C1->CR2 |= 6 << 16;  //Specifico il numero di byte da leggere caso 6 perchè voglio leggere i 6 sottoregistri dell'accelerometro
I2C1->CR2 |= I2C_CR2_START;  //Do il comando di Start
while((I2C1->ISR & I2C_ISR_TXE)!=I2C_ISR_TXE);  //Mi assicuro che il Transmit data register sia vuoto
//Leggo i 6 dati
for(int j=0;j<6;j++)
{
while(( I2C1->ISR & I2C_ISR_RXNE)!=I2C_ISR_RXNE);  //Mi assicuro che il Receive data register non sia vuoto (sia pieno)
accData[j]=I2C1->RXDR;  //Prelevo il dato
}
I2C1->CR2 |= I2C_CR2_STOP;  //Do lo Stop
while((I2C1->ISR & I2C_ISR_STOPF)!=I2C_ISR_STOPF);  //Attendo lo Stop flag
I2C1->ICR |= I2C_ICR_STOPCF;  //Pulisco il Stop flag
/*Dobbiamo convertire il dato ricevuto nell'informazione accelerazione
Prima la parte alta e poi la parte bassa.
1)Facciamo prima uno shift a sx della parte alta (es. OUT_X_H_A) di 8 facendo un cast a 16 bit (uint16_t) per non perdere bit
2)Sommiamo la seconda componente parte bassa (es. OUT_X_L_A)
3)Il risulato che ottengo lo divido per 16 perchè in realta' di questi 16 bit solo 12 me ne servono e sono allineati a sx. Dividendo per 16 sposto di 4 a sinistra (potrei mettere lo shift di 4 .. stessa cosa)
4)In realtà questo non e' unsigned perchè puo' andare sia per positivi che per negativi (operazione che viene gestita automaticamente)
5)Se voglio guadagnere un po di risoluzione faccio un cast a float*/
x=((int16_t)((uint16_t)accData[1]<<8)+accData[0])/16;
y=((int16_t)((uint16_t)accData[3]<<8)+accData[2])/16;
z=((int16_t)((uint16_t)accData[5]<<8)+accData[4])/16;
}
//return 0;
}
 
Ultima modifica da un moderatore:
  • Like
Reactions: Danny 92

Danny 92

Membro
25 Febbraio 2015
10
4
3
la configurazione del TIMINGR è standard ? quel valore va bene sempre ?

inoltre mi sapete dire come fare ad esprimere l'accelerazione in g ?

ed ancora , questo codice mi restituisce dei valori troppo elevati per l'asse z
 
Ultima modifica:

berto91

Membro
Utente Premium
27 Ottobre 2015
12
9
3
Allora non sono sicuro ma per il TIMINGR a pag 12 del file relativo all'accelerometro c'è scritto che la max in standard mode è di 100 KHz ora nel RefMan a pagg 684 scegliendo la madolità 8MHz(non so xk proprio 8) Standard mode a 100 KHz trovi i valori da inserire nel registro

2/3 quei valori che trovi per i l'accelerazione sono in millig l'asse z deve essere intorno a 1000 o 1g accelerazione terrestre
 
  • Like
Reactions: Danny 92

berto91

Membro
Utente Premium
27 Ottobre 2015
12
9
3
Ciao raga

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

Come si svolge
 
Ultima modifica:

Danny 92

Membro
25 Febbraio 2015
10
4
3
bella domanda , non ho trovato nessun esempio , ma non dovrebbe essere molto diverso dalla sinusoide , io invece di riempire il vettore dei campioni da inviare al dac con i valori della sinusoide , lo riempirei per meta con il valore massimo dell'onda e per meta con il valore minimo
 
  • Like
Reactions: berto91

Danny 92

Membro
25 Febbraio 2015
10
4
3
guardando alcune tracce , ho letto :
Configurare i pin PA1 e PA2 come output digitali di valore rispettivamente 0 e 1

come si fa ?
 

berto91

Membro
Utente Premium
27 Ottobre 2015
12
9
3
E lo stesso per fare accendere i led configuri GPIOA->MODER come General purpose output mode ai pin PA1 e PA2 e ci scrivi 0 o 1
 
  • Like
Reactions: Danny 92

Danny 92

Membro
25 Febbraio 2015
10
4
3
quindi tramite il registro ODR setto i valori , in particolare al bit 0 corrisponde il pin PA0 e cosi via ?
 

berto91

Membro
Utente Premium
27 Ottobre 2015
12
9
3
Genero un segnale ad onda quadra di periodo 10s nn so se è il metodo migliore ma funziona

Se voglio generare un segnale sinusoidale creo un fettore di N elementi (di solito 100) contenete i valori del segnale e imposto il timer affinchè generi un evento ogni periodo/N


#include "stm32f30x.h"
int var[2]={4095,0};
int j=0;
int main()
{
RCC->APB1ENR |=1<<1;//abilito TIM3
RCC->AHBENR |=1<<17;//ABILTIO PORTA A
RCC->AHBENR |=1<<21; //abilito porta E
//RCC->APB2ENR |=1<<0;

GPIOE->MODER|=0x55550000;//IMPOSTO GPIOE IN General purpose output mode
TIM3->PSC=7199;//IMPOSTO IL PSC IN MODO DA AVERE UNA FREQUENZA DI CLOCK DI 72000000/(7199+1)
TIM3->ARR=50000;//IMPOSTO IL ARR IN MODO DA CONTARE 50000 IMPULSI
TIM3->CR1 |=1<<0;//AVVIO IL IL CONTEGGIO
TIM3->DIER|=1<<0;//ABILITO Update interrupt
NVIC->ISER[0]|=1<<29;//SELEZIONO NEL Nested vectored interrupt controller IL TIM3
//-------DAC--------------
RCC->APB1ENR |=1<<29; //ABILITO IL CANALE DEL DAC
GPIOA->MODER|=0x00000300;//IMPOSTO IL PA4 COME Analog mode
DAC->CR|=1;//ABILITO IL DAC1
for(int i=0;i<1000000;i++);//ASPETTO 10 MICROSECONDI NN SONO SICURO DI QUANTO EFFETIVAMENTE CONTI
DAC->CR|=1<<2; //ABILITO IL TRIGGER
DAC->CR|=7<<3; //IMPOSTO IL TRIGGER VIA SOFTWAR
while(1);
}
void TIM3_IRQHandler(void)
{
TIM3->SR&=~((uint32_t)1);
DAC->DHR12R1=var[j];//SCRIVO IL VALORE DI var[j] NEL REGISTRO DEL DAC
DAC->SWTRIGR |= 1; //DA IL TRIGGER
for(int i=0;i<500000;i++);//ASPETTO DOVREI ASPETTARE 4 microsecondi
if(GPIOE->ODR&(1<<9))
GPIOE->ODR&=~((uint32_t)1<<9);
else
GPIOE->ODR|=1<<9;
j++;
if(j==2)
j=0;
}
 
Ultima modifica:
  • Like
Reactions: Danny 92

Seguici su Facebook