
Fork of Lab3_latest_21_01_2015_aggiornata by
main.cpp
- Committer:
- capopolito
- Date:
- 2015-02-08
- Revision:
- 7:3abddf195ada
- Parent:
- 6:848474d4d02e
File content as of revision 7:3abddf195ada:
#include "mbed.h" #include "MMA8451Q.h" #include "I2C.h" #include "SPI.h" #include "DigitalIn.h" #include "DigitalOut.h" #if defined (TARGET_KL25Z) || defined (TARGET_KL46Z) PinName const SDA = PTE25; PinName const SCL = PTE24; #elif defined (TARGET_KL05Z) PinName const SDA = PTB4; PinName const SCL = PTB3; #elif defined (TARGET_K20D50M) PinName const SDA = PTB1; PinName const SCL = PTB0; #else #error TARGET NOT DEFINED #endif //--RELATIVI ALLA COMUNICAZIONE SPI------ PinName const mosi = PTD2; //mosi SPI1_mosi PinName const miso = PTD3; //miso SPI1_miso PinName const sck = PTD1; //sck SPI1_sck PinName const pcs0 = PTD0; //pcs0 SPI1_pcs0 //--RELATIVI ALLA COMUNICAZIONE SPI------ #define MMA8451_I2C_ADDRESS (0x1d<<1) //instanzia e inizializza oggettto i2c della clase I2C I2C i2c(SDA,SCL); // SDA I2C data line pin // SCL I2C clock line pin //instanzia e inizializza oggettto spi della classe SPI SPI spi(mosi,miso,sck); DigitalOut slave_select(pcs0,1); //inizializza slave-select //------------------------------------------------------- //registri da impostare char CTRL_REG_1 = 0x2A ; //read/write // register address del CTRL_REG_1 char CTRL_REG_2 = 0x2B ; //read/write // register address del CTRL_REG_2 char CTRL_REG_3 = 0x2C ; //read/write // register address del CTRL_REG_3 char CTRL_REG_4 = 0x2D ; //read/write // register address del CTRL_REG_4 char OUT_X_MSB = 0x01 ; //read only // parte più significativa del registro contenete l'accelerazione sull'asse x char OUT_Y_MSB = 0x03 ; //read only // parte più significativa del registro contenete l'accelerazione sull'asse y char OUT_Z_MSB = 0x05 ; //read only // parte più significativa del registro contenete l'accelerazione sull'asse z char XYZ_DATA_CFG = 0x0E; //read/write // register address del XYZ_DATA_CFG char ASLP_COUNT= 0x29; //read/write // register address SLEEP TIME-OUT COUNTER char SYSMOD = 0x0B; //read only // register address SYSMOD System Mode Register //registri da impostare------------------------------------------------------------------- //-indirizzo del dipositivo con l'ultimo bit asserito per la lettura e negato per la scrittura char address_wr = 0x3A ; // byte per eseguire lettura: address_device + bit_wr(W=0) char address_rd = 0x3B ; // byte per eseguire scrittura: address_device + bit_rd(R=1) //------------------------------------------------------------------------------------------------ //--variabile di appoggio utilizzata per scrivere e leggere i registri char data = 0x00 ; // inizalizza la variabile data con le impostazioni da scrivere su CTRL_REG_1 //--registri aggiunti e settati per prova ------------------------------------------------------------------ char FF_MT_CFG = 0x15; //read/write // registera addres del FF_MT_CFG (Frefall/Motionn Configuration register char FF_MT_THS = 0x17; //read/write // register address del FF_MT_THS Freefall and Motion Threshold char FF_MT_COUNT = 0x18; //read/write //register address del FF_MT_COUNT Debounce Register //--registri aggiunti e settati per prova --------------------------------------------------------------------- int main(void) { printf("inizio \n"); //--setting delle impostazioni del SPI in base alle specifiche------------------ int bits = 8; int mode = 1; spi.format(bits,mode);//definisce formato spi con 16 bit e pol=0 e pha=1 //di default la frequenza è 1MHz char command_wr=0x80; //comando per la scrittura (10000DDD), di default nella locazione DDD=000 //int command_rd=0; //comando per la lettura (00000DDD), dib default nella locazione DDD=000 //non utilizzato ! //--setting delle impostazioni della SPI come da specifiche------------------------ //impostazione dei registri dell'I2C con scrittura Single Byte Write // setta impostazioni su CTRL_REG_1 data = 0x58 ; // setta la variabile data con le impostazioni da scrivere su CTRL_REG_1 //Bit 7-> ASLP_RATE1 = 0 //Bit 6-> ASLP_RATE0 = 1 -> // Il sample rate in sleep è 6.25 Hz vedi AN070 //Bit 5-> DR2 = 0 //Bit 4-> DR1 = 1 //Bit 3-> DR0 = 1 -> // Il sample rate in wake è 100 Hz vedi AN070 //Bit 2-> LNOISE = 0 //Bit 1-> F_READ = 0 -> //Faste read is enabled, acquissco un solo byte! //Bit 0-> ACTIVE = 0 -> //Mette il dispositivo in standby per settare gli altri registri i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_1); // scrivi l'indirizzo del CTRL_REG_1 i2c.write(data); // scrivi il "data" già inizializzato con le impostazioni del CTRL_REG_1 i2c.stop(); //NOTE: //La modalità "FAST READ", che si attiva asserendo il bit F_READ, può non essere impostata perchè //per campionare il dato con risoluzione 8 bit è sufficente leggere solo la parte //significativa del dato contenuta nei registri OUT_MSB_X, Y e Z. //Cambio la frequenz di campionamento, valore dell'ODR (Over Sampling Ratio), //dalla modalità sleep alla modalità wake (in modo da accorgermi di essere in wake) // setta impostazioni su CTRL_REG_2 data=0x04; //imposta data con le impostazioni del CTRL_REG_2 //ST=0 disabilita il self-test //RST=0 disabilita modalità reset //bit 5 don't care //SMODS0=SMODS1=0 setta la modalità oversampling_mode = normal , quando è in modalità in sleep //SLPE=1 abilita l'autosleep -> vedi AN070 //MODS0=MODS1=0 setta la modalità oversampling_mode = normal , quando è in modalità in active i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_2); // scrivi l'indirizzo del CTRL_REG_2 i2c.write(data); // scrivi il "data" contenete le impostazioni del CTRL_REG_2 i2c.stop(); // setta impostazioni su CTRL_REG_3 data=0x68; //imposta data con le impostazioni del CTRL_REG_3 attineti alle gestioni dell'interupt in modalità sleep // vedi data-sheet //Bit 7-> FIFO GATE = 0 //Bit 6-> WAKE_TRANS = 1 //Bit 5-> WAKE_LNDRPT = 1 //Bit 4-> WAKE_PULSE = 0 //Bit 3-> WAKE_FF_MT = 1 //Bit 2-> don't care //Bit 1-> IPOL = 0 //Bit 0-> PP_OD = 0 i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_3); // scrivi l'indirizzo del CTRL_REG_3 i2c.write(data); // scrivi il "data" contenete le impostazioni del CTRL_REG_3 i2c.stop(); // setta impostazioni su CTRL_REG_4 data=0xB5; //imposta data con le impostazioni del CTRL_REG_4 attineti alle gestioni dell'interupt // vedi data-sheet //Bit 7-> IN_EN_ASLP = 1 ; se = 1 Auto-SLEEP/WAKE interrupt enabled -> vedi AN070 //Bit 6-> INT_EN_FIFO = 0 //Bit 5-> INT_EN_TRANS = 1 //Bit 4-> INT_EN_LNDPRT = 1 //Bit 3-> INT_EN_PULSE = 0 //Bit 2-> INT_EN_FF_MT = 1 //Bit 1-> don't care = 0 //Bit 0-> INT_EN_DRDY = 1 ;// abilito data ready per motivi di logica interna pur no usandolo i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_4); // scrivi l'indirizzo del CTRL_REG_4 i2c.write(data); // scrivi il "data" contenete le impostazioni del CTRL_REG_4 i2c.stop(); // setta impostazioni su XYZ_DATA_CFG data=0x00; //imposta data con le impostazioni del XYZ_DATA_CFG attineti alla dinamica che si vuole acquisire (+-2g) // FS1=FS0=0 imposta la dinamica +-2g i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(XYZ_DATA_CFG); // scrivi l'indirizzo del XYZ_DATA_CFG i2c.write(data); // scrivi il "data" contenete le impostazioni del XYZ_DATA_CFG i2c.stop(); //setta impostazioni su ASLP_COUNT data=0xF0; //->impostato da me valore max //data=0x01; //impostato da me valore min //data=0x04; //imposta data con le impostazioni del ASLP_COUNT -> impostato dal professore!!! i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(ASLP_COUNT); // scrivi l'indirizzo del ASLP_COUNT i2c.write(data); // scrivi il "data" contenete le impostazioni del ASLP_COUNT i2c.stop(); //---registri impostati per gestire gli interrupt --------------------------------- // setta impostazioni su FF_MT_CFG (Frefall/Motion Configuration Register (Read/Write) data=0xF8; //imposta data con le impostazioni del FF_MT_SRC attineti quando vogliamo svegliare il dispositivo dal wake //Bit 7-> ELE = 1 ;event flag latch enabled in FF_MT_SRC //Bit 6-> OAE = 1 ;Motion Flag (if=1 OR combination) (if=1 AND combination) //Bit 5-> ZEFE = 1 ;se = 0 asse Z event dection disabled ; se = 1 asse X raise event flag on measured acceleration value beyond present threshold //Bit 4-> YEFE = 1 ;se = 0 asse Y event dection disabled ; se = 1 asse Y raise event flag on measured acceleration value beyond present threshold //Bit 3-> XEFE = 1 ;se = 0 asse X event dection disabled ; se = 1 asse X raise event flag on measured acceleration value beyond present threshold //Bit 2-> = 0 don't care //Bit 1-> = 0 don't care //Bit 0-> = 0 don't care i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(FF_MT_CFG); // scrivi l'indirizzo del FF_MT_CFG i2c.write(data); // scrivi il "data" contenete le impostazioni del FF_MT_CFG i2c.stop(); // setta impostazioni su FF_MT_THS (Read/Write) data=0x04; //imposta data con le impostazioni del FF_MT_THS i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(FF_MT_THS); // scrivi l'indirizzo del FF_MT_THS i2c.write(data); // scrivi il "data" contenete le impostazioni del FF_MT_THS i2c.stop(); // setta impostazioni su FF_MT_COUNT (Read/Write) data=0x08; //imposta data con le impostazioni del FF_MT_COUNT i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(FF_MT_COUNT); // scrivi l'indirizzo del FF_MT_COUNT i2c.write(data); // scrivi il "data" contenete le impostazioni del FF_MT_COUNT i2c.stop(); //---registri impostati per gestire gli interrupt --------------------------------- //!!! attiva il dispositivo (esce da standby) !!! // setta impostazioni su CTRL_REG_1 data=0x5B ; // mette a 1 il bit ACTIVE e lascia invariati gli altri (già impostati) i2c.start(); // dai lo start i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_1); // scrivi l'indirizzo del CTRL_REG_1 i2c.write(data); // scrivi il "data" in le impostazioni del CTRL_REG_1 i2c.stop(); //PER ACCENDERE LED PwmOut rled(LED1); PwmOut gled(LED2); PwmOut bled(LED3); //verifica della corretta scrittura dei principali registri, mediante lettura Single Byte Read //lettura single byte read del registro CTRL_REG_1 char ctrl_reg_1 = 0x00; i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_1); // scrivi l'indirizzo del registro i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read ctrl_reg_1=i2c.read(0); i2c.stop(); printf("CTRL_REG_1: %1.2x \n", ctrl_reg_1); // in esadecimale //lettura single byte read del registro CTRL_REG_2 char ctrl_reg_2 = 0x00; i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_2); // scrivi l'indirizzo del registro i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read ctrl_reg_2=i2c.read(0); i2c.stop(); printf("CTRL_REG_2: %1.2x \n", ctrl_reg_2); //in esadecimale //lettura single byte read del registro CTRL_REG_3 char ctrl_reg_3 = 0x00; i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_3); // scrivi l'indirizzo del registro i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read ctrl_reg_3=i2c.read(0); i2c.stop(); printf("CTRL_REG_3: %1.2x \n", ctrl_reg_3); //in esadecimale //lettura single byte read del registro CTRL_REG_4 char ctrl_reg_4 = 0x00; i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(CTRL_REG_4); // scrivi l'indirizzo del registro i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read ctrl_reg_4=i2c.read(0); i2c.stop(); printf("CTRL_REG_4: %1.2x \n", ctrl_reg_4); //in esadecimale //lettura single byte read del registro ASLP_COUNT char aslp_count = 0x00; i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(ASLP_COUNT); // scrivi l'indirizzo del registro i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read aslp_count=i2c.read(0); i2c.stop(); printf("ASLP_COUNT: %1.2x \n", aslp_count); //in esadecimale //verifica della corretta scrittura dei registri principali------------------------------ char sysmod = 0x00; float x_axis, y_axis, z_axis; float x_axis_norm, y_axis_norm, z_axis_norm; int x_tens, x_unit, y_tens, y_unit, z_tens, z_unit; char x_tens_ascii, x_unit_ascii, y_tens_ascii, y_unit_ascii, z_tens_ascii, z_unit_ascii; char loc_x_tens=0x00, loc_x_unit=0x01, loc_y_tens=0x02, loc_y_unit=0x03, loc_z_tens=0x04, loc_z_unit=0x05; //location DDD=000, DDD=001, DDD=010, DDD=011, DDD=100, DDD=101; char command_location=0x00; // in caso di scrittura 1000 DDD while (true) { printf("SYSMOD_pre_read: %1.2x \n", sysmod); wait(0.1); //lettura dello stato dell'accelerometro wake o sleep //lettura single Byte Read contenuto di SYSMOD System Mode Register // Bit 7-> FGERR // Bit 6-> FGT_4 // Bit 5-> FGT_3 // Bit 4-> FGT_2 // Bit 3-> FGT_1 // Bit 2-> FGT_0 // Bit 1-> SYSMOD1 // Bit 0-> SYSMOD0 // SYSMOD[1:0] // System Mode. Default value: 00. // 00: STANDBY mode // 01: WAKE mode // 10: SLEEP mode i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(SYSMOD); // scrivi l'indirizzo del registro i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read sysmod=i2c.read(0); i2c.stop(); printf("SYSMOD_post_read: %1.2x \n", sysmod); wait(0.1f); if ( (sysmod &0x02) == 0x02) { // if SYSMOD1,SYSMOD0 = 1,0 wait(0.1f); printf("I'm sleeping , SYSMOD: %1.2x \n",sysmod); rled = 0.0f; gled = 0.0f; bled = 0.0f; } //chiusra del if if ( (sysmod &0x01) ==0x01){ // if SYSMOD1,SYSMOD0 = 0,1 wait(0.1f); printf("Good morning! , SYSMOD: %1.2x \n", sysmod); //lettura degli assi con lettura Single Byte Read // asse x i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(OUT_X_MSB); // scrivi l'indirizzo del registro contente l'accelerazione sull'asse X i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read x_axis=i2c.read(0); // scrive bit di NAK (non acknowlodgement) e salva il dato sul bus su x_axis i2c.stop(); // asse y i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(OUT_Y_MSB); // scrivi l'indirizzo del registro contente l'accelerazione sull'asse Y i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read y_axis=i2c.read(0); // scrive bit di NAK (non acknowlodgement) e salva il dato sul bus su y_axis i2c.stop(); // asse Z i2c.start(); i2c.write(address_wr); // scrivi e passa l'indirizzo del dispositivo con bit di scrittura i2c.write(OUT_Z_MSB); // scrivi l'indirizzo del registro contente l'accelerazione sull'asse Z i2c.start(); i2c.write(address_rd); // scrivi e passa l'indirizzo del dispositivo con bit di read z_axis=i2c.read(0); // scrive bit di NAK (non acknowlodgement) e salva il dato sul bus su z_axis i2c.stop(); //accendo led rled = 1.0f - x_axis/64; gled = 1.0f - y_axis/64; bled = 1.0f - z_axis/64; //scrivo sulla seriale printf("X: %1.2f, Y: %1.2f, Z: %1.2f\n", x_axis/64, y_axis/64, z_axis/64); //SCRIVO DATI SU DISPLAY A SETTE SEGMENTI DELLA SCHEDA DE2 MEDIANTE SPI //accelerazione sull'asse x x_axis_norm=x_axis/64*99; // normalizzo tra [0 99] x_tens = (int(x_axis_norm/10)); // ottengo le decine x_unit = (x_axis_norm-10*x_tens); // ottengo le unità x_tens_ascii = ( '0' + (x_tens) ); // ottengo le decine in ASCII x_unit_ascii = ( '0' + (x_unit) ); // ottengo le unità in ASCII //accelerazione sull'asse y y_axis_norm=y_axis/64*99; // normalizzo tra [0 99] y_tens = (int(y_axis_norm/10)); // ottengo le decine y_unit = (y_axis_norm-10*y_tens); // ottengo le unità y_tens_ascii = ( '0' + (y_tens) ); // ottengo le decine in ASCII y_unit_ascii = ( '0' + (y_unit) ); // ottengo le unità in ASCII //accelerazione sull'asse z z_axis_norm=z_axis/64*99; // normalizzo tra [0 99] z_tens = (int(z_axis_norm/10)); // ottengo le decine z_unit = (z_axis_norm-10*z_tens); // ottengo le unità z_tens_ascii = ( '0' + (z_tens) ); // ottengo le decine in ASCII z_unit_ascii = ( '0' + (z_unit) ); // ottengo le unità in ASCII //stampo nella seriale componente x,y,z dell'accelereazione normailzzate tra 0 e 99 printf("ax_norm: %1.2f, ay_norm: %1.2f, az_norm: %1.2f\n", x_axis_norm, y_axis_norm, z_axis_norm); //stampo nella seriale le decine delle componenti x,y,z dell'accelereazione normailzzate tra 0 e 99 printf("ax_tens: %1.2d, ay_tens: %1.2d, az_tens: %1.2d\n", x_tens, y_tens, z_tens); //stampo nella seriale le unità delle componenti x,y,z dell'accelereazione normailzzate tra 0 e 99 printf("ax_unit: %1.2d, ay_unit: %1.2d, az_unit: %1.2d\n", x_unit, y_unit, z_unit); //stampo nella seriale le decine in ascii delle componenti x,y,z dell'accelereazione normailzzate tra 0 e 99 printf("ax_tens_ascii: %1.2c, ay_tens_ascii: %1.2c, az_tens_ascii: %1.2c\n", x_tens_ascii, y_tens_ascii, z_tens_ascii); //stampo nella seriale le unità in ascii delle componenti x,y,z dell'accelereazione normailzzate tra 0 e 99 printf("ax_unit_ascii: %1.2c, ay_unit_ascii: %1.2c, az_unit_ascii: %1.2c\n", x_unit_ascii, y_unit_ascii, z_unit_ascii); //stampo nella seriale componente x,y,z dell'accelereazione normailzzate tra 0 e 99 //scrivo nei display i valori dell'accelerazione //componente x dell'accelarazione //scrivo codice ascii delle decine nel display nel display dedicato command_location = ( command_wr | loc_x_tens ) ; //1000 000 = 0x80 //command_location = 0x80; slave_select.write(0); spi.write(command_location); spi.write(x_tens_ascii); slave_select.write(1); //scrivo codice ascii delle unità nel display nel display dedicato command_location = ( command_wr | loc_x_unit ) ; //1000 001 = 0x81 //command_location = 0x81; slave_select.write(0); spi.write(command_location); spi.write(x_unit_ascii); slave_select.write(1); //componente y dell'accelarazione //scrivo codice ascii delle decine nel display nel display dedicato command_location = ( command_wr | loc_y_tens ); //1000 010 = 0x82 //command_location = 0x82; slave_select.write(0); //asserisco lo slave select attivo basso spi.write(command_location); spi.write(y_tens_ascii); slave_select.write(1); //nego lo slave select attivo basso //scrivo codice ascii delle unità nel display nel display dedicato command_location = ( command_wr | loc_y_unit ); //1000 011 = 0x83 //command_location = 0x83; slave_select.write(0); //asserisco lo slave select attivo basso spi.write(command_location); spi.write(y_unit_ascii); slave_select.write(1); //nego lo slave select attivo basso //componente z dell'accelarazione //scrivo codice ascii delle decine nel display nel display dedicato command_location = ( command_wr | loc_z_tens ); //1000 100 = 0x84 //command_location = 0x84; slave_select.write(0); //asserisco lo slave select attivo basso spi.write(command_location); spi.write(z_tens_ascii); slave_select.write(1); //nego lo slave select attivo basso //scrivo codice ascii delle unità nel display nel display dedicato command_location = ( command_wr | loc_z_unit ); //1000 101 = 0x85 //command_location = 0x85; slave_select.write(0); spi.write(command_location); spi.write(z_unit_ascii); slave_select.write(1); //scrivo nei display i valori dell'accelerazione } //close 2nd if }//close while }//close main