Vizitator andrei_wsk Postat Noiembrie 14, 2011 Partajează Postat Noiembrie 14, 2011 Buna ziua, Incerc sa realizez un proiect cu ajutorul unui pic 16f887 si a unui accelerometru MMA7455. Programul pe care il folosesc este mikroc pro si biblioteca pusa la dispozitie de acesta. Controller-ul comunica cu accelerometrul prin I2c. Am studiat datasheet-ul si am vazut ca adresa accelerometrului este 0x0D. Pt inceput vreau sa citesc doar axa X deci ma intereseaza doar registrul 0x06 sau 0x00(va rog corectati-ma daca gresesc). Conexiuile le-am facut in felul urmator: VCC -VCC, GND -GND, SCL- RC3, SDA- RC4, CS -VCC. Accelerometrul ar trebui sa imi furnizeze pe axa X atat valori negative cat si valori pozitive. Ceea ce am incercat sa realizez defapt a fost sa aprind un led cand citesc valori pozitive si sa il inchid cand citesc valori negative. Din pacate nu reusesc sa fac comunicarea intre controller si accelerometru. Am cautat pe interet si am gasit unele thread-uri unde lumea spunea ca adresa ar fi 0x3A sau 0xD1. Am incercat si cu aceste adrese tot fara succes. Postez si codul // Software I2C connectionssbit Soft_I2C_Scl at RC3_bit;sbit Soft_I2C_Sda at RC4_bit;sbit Soft_I2C_Scl_Direction at TRISC3_bit;sbit Soft_I2C_Sda_Direction at TRISC4_bit;// End Software I2C connectionschar X;void Read_X() { Soft_I2C_Start(); // Issue start signal Soft_I2C_Write(0x3A); Soft_I2C_Write(0x00); Soft_I2C_Start(); // Issue repeated start signal Soft_I2C_Write(0x3B); X = Soft_I2C_Read(0u); Soft_I2C_Stop();}void Init_Main() { ANSEL = 0; // Configure AN pins as digital I/O ANSELH = 0; C1ON_bit = 0; // Disable comparators C2ON_bit = 0; Soft_I2C_Init(); // Initialize Soft I2C communication}void main() { // Main procedure Delay_ms(500); Init_Main(); // Perform initialization while (1) { Read_X(); if (X<0) { trisb.b5=0; portb.b5=1;} else { trisb.b5=1; portb.b5=0;} }} Multumesc Link spre comentariu
sofian Postat Noiembrie 14, 2011 Partajează Postat Noiembrie 14, 2011 Cred ca mai trebuiesc si rezistori de la scl,sda la +5v de 4k7 Link spre comentariu
Vizitator andrei_wsk Postat Noiembrie 15, 2011 Partajează Postat Noiembrie 15, 2011 am si rezistentele de pull up in circuit am uitat sa specific Link spre comentariu
Liviu M Postat Noiembrie 15, 2011 Partajează Postat Noiembrie 15, 2011 In primul data-sheet gasit cu google adresa e 0x1D. SINGLE BYTE WRITETo start a write command, the Master transmits a start condition (ST) to the MMA7455L, slave address ($1D) with the R/W bit setto “0” for a write,Cu adresa asta si cu bitul read/write se "contruieste" byte-ul de adresare - b00111010 - scriere si b00111011 - citire. Adica ce ai folosit tu, 0x3A la scriere si 0x3B la citire.Da' de ce zici ca nu merge? Ce nu face?Ca partea cu negativ e "de la tine". Acceleratia e pe 10 biti, in complement fata de 2. $00: 10bits Output Value X LSB (Read only)...Signed byte data (2’s compliment):Asta inseamna ca trebuie sa citesti si adresa 2 si sa "construiesti" acceleratia, dupa care sa o convertesti in complement fata de 2. Link spre comentariu
MatyC Postat Noiembrie 16, 2011 Partajează Postat Noiembrie 16, 2011 De curiozitate cum ai conectat ledul in montaj? Ca nu prea inteleg de ce in cazul cand portb.b5=1 setezi pinul ca iesire (trisb.b5=0) insa cand vrei 0 pe b5, portb.b5=0 tu setezi pinul ca intrare (trisb.b5=1)? Link spre comentariu
Vizitator andrei_wsk Postat Noiembrie 17, 2011 Partajează Postat Noiembrie 17, 2011 Nu interfateaza. Imi indica 255,valoare maxima, constant indiferent cum misc accelerometrul. Am vazut in tabel pe acest site http://www.parallax.com/Portals/0/Downl ... l-v1.1.pdf la pagina 4 de aceea credeam ca imi va returna numere negative. Apropo de led... il conectez normal prin rezistenta la pinul integratului si la GND. Pur si simplu am schimbat starea lui pt ca daca il lasam ca iesire se aprindea led-ul in continuare chiar daca portb=0. Link spre comentariu
Liviu M Postat Noiembrie 18, 2011 Partajează Postat Noiembrie 18, 2011 Pai daca ledul se aprinde oricum ai seta portul respectiv (high sau low), inseamna ca ai probleme (probabil de configurare) pe care trebuie sa le rezolvi inainte de comunicatia i2c (adica fa ledul sa clipoceasca asa cum vrei tu, dupa care treci la problemele mai complicate).Eu asa as face. Link spre comentariu
wangine Postat Noiembrie 18, 2011 Partajează Postat Noiembrie 18, 2011 daca tot nu ai reusit cu accelerometrul. Compilerul este CCS(PCWHD) Driver pentru I2C /********************************************************************* Writer Tanase Bogdan (c) copyright www.hexhoby.ro ALL RIGHTS RESERVED ******************************************************************** Ver 0.1 release 19/iunie/2011********************************************************************/#include <33FJ64GS406.h>#use delay(clock=81070000) // real clock (masurat)//#use delay(clock=80000000) // clock //#use i2c(Master,Slow,sda=PIN_G3,scl=PIN_G2, force_HW)#use i2c(Master,Slow,sda=PIN_B5,scl=PIN_B6, force_HW) unsigned int8 x_ax, y_ax, z_ax; int1 flag_x, flag_y, flag_z;//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~void start_acc_I2C() {i2c_start(); i2c_write(0x3A); //0x1D shifted in with a 0 had been 0x3A i2c_write(0x16); //MODE CONTROL REGISTER i2c_write(0x05); //CONTINOUS MEASUREMENT i2c_stop(); delay_ms(30); }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~unsigned int8 acc_i2c_read(unsigned int8 reg) { unsigned int8 data; // delay_ms(1);i2c_start(); i2c_write(0x3A); i2c_write(reg); //8 bits output value Z i2c_start(); i2c_write(0x3B); //0x1D shifted in with a 1 had been 0x3B data=i2c_read(0); i2c_stop(); // delay_ms(1);return(data); }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~void acc_i2c_write(unsigned int8 reg,unsigned int8 data) {i2c_start(); i2c_write(0x3A); //0x1D shifted in with a 0 had been 0x3A i2c_write(reg); //MODE CONTROL REGISTER i2c_write(data); //CONTINOUS MEASUREMENT i2c_stop(); }// from interrupts//~~~~~~~~~~~~~~ set to 240Hz bandwitch ?? s-au bandwich ~~~~~~~~~~~~~~~~~void sel_250_Hz() {acc_i2c_write(0x18, 0x80); }//~~~~~~~~~~~~~~~~set offset to 0 ~~~~~~~~~~~~~~~~~~void calib_off_acc_0 () { acc_i2c_write(0x10, 0x00); delay_ms(10); acc_i2c_write(0x12, 47); delay_ms(10);// acc_i2c_write(0x14, 0x00);// delay_ms(10); }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~void auto_calibrate() { int16 i;signed char Xdata,Ydata,Zdata;signed short Xcal,Xcalp, Ycal, Ycalp, Zcal, Zcalp;byte Xcal_L, Xcal_H, Ycal_L,Ycal_H, Zcal_L, Zcal_H;acc_i2c_write(0x16,0x05);//Asigura daca calibratia registrilor este claraacc_i2c_write(0x10,0);acc_i2c_write(0x11,0);Xcal=0;for (i=0;i<=50;i++) {Xdata= acc_i2c_read(0x06);Ydata= acc_i2c_read(0x07);Zdata= acc_i2c_read(0x08);Xcal+= -2*Xdata; //Calculeaza biasul acesteiaYcal+= -2*Ydata;if (Zdata>65){Zcal+=(Zdata-64)*2;}else{Zcal+=(64-Zdata)*2;}Xcalp=Xcal; //Daca calp este pozitiv asuma variabilaif (Xcalp<0) Xcalp +=2048; //daca este neg, convert for 2's complementYcalp=Ycal;if(Ycalp<0) Ycalp+=2048;Zcalp=Zcal;if(Zcalp<0) Zcalp+=2048;Xcal_L= (byte)(Xcalp&0x00FF); //shift low byte to lower 8 bitsXcal_H= (byte)((Xcalp&0xFF00)>>8); //shift high byte to upper 8 bitsYcal_L= (byte)(Ycalp&0x00FF); //shift low byte to lower 8 bitsYcal_H= (byte)((Ycalp&0xFF00)>>8); //shift high byte to upper 8 bitsZcal_L= (byte)(Zcalp&0x00FF); //shift low byte to lower 8 bitsZcal_H= (byte)((Zcalp&0xFF00)>>8); //shift high byte to upper 8 bitsXcal += -2*Xdata;delay_ms(10);Xdata=acc_i2c_read(0x00); }acc_i2c_write(0x10,Xcal_L); //Write low calibration value to the low calibration registeracc_i2c_write(0x11,Xcal_H); //Write high calibration value to the high calibration registeracc_i2c_write(0x12,Ycal_L); //Write low calibration value to the low calibration registeracc_i2c_write(0x13,Ycal_H); //Write high calibration value to the high calibration registeracc_i2c_write(0x14,Zcal_L); //Write low calibration value to the low calibration registeracc_i2c_write(0x15,Zcal_H); //Write high calibration value to the high calibration register }//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~void X_axis() { if(flag_x == false) { i2c_start(); i2c_write(0x3A); i2c_write(0x06); i2c_start(); i2c_write(0x3B); x_ax = i2c_read(0); i2c_stop(); flag_x = true; } }//=============================== //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~void Y_axis() { if(flag_y == false) { i2c_start(); i2c_write(0x3A); i2c_write(0x07); i2c_start(); i2c_write(0x3B); y_ax = i2c_read(0); i2c_stop(); flag_y = true; } }//=============================== //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~void Z_axis() { if(flag_z == false) { i2c_start(); i2c_write(0x3A); i2c_write(0x08); i2c_start(); i2c_write(0x3B); z_ax = i2c_read(0); i2c_stop(); flag_z = true; } }//=============================== si pentru SPI. #include <main.h>//#int_EXT0///#use rs232(UART1,baud=19200,parity=N,bits=8)//#use rs232(baud=9600,parity=N,xmit=PIN_F3,rcv=PIN_F2,bits=8)//#USE SPI (MASTER, SPI1, ENABLE=PIN_G8, MODE=0, BITS=8, STREAM=SPI_0, MSB_FIRST)//#USE SPI (MASTER, CLK=PIN_C3, DI=PIN_C5, DO=PIN_C4, ENABLE=PIN_D1, MODE=0, BITS=8, STREAM=SPI_0, MSB_FIRST)#define ACC_CS PIN_G9 // SPI modes #define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H) #define SPI_MODE_1 (SPI_L_TO_H) #define SPI_MODE_2 (SPI_H_TO_L) #define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) //---------------------------------- //#import(RELOCATABLE, file = E:\PIC_Lucru\dsPIC33FJ64GS406\C30_teste\External_test\test_3\4\intrerrupt_ext.o)//#import(hex,file = E:\PIC_Lucru\dsPIC33FJ64GS406\C30_teste\External_test\test_3\4\test_monitor_1024_768.hex, range = 0x1200 : 0x2003)void EXT0_isr(void) {}volatile signed int Xdata=0, Ydata=0, Zdata=0; //*********************************************************************void Acc_Write_Register(int8 reg, int8 data) { //output_low(ACC_CS); delay_ms(1);spi_write(((reg & 0x3F) << 1) | 0x80); delay_ms(1);spi_write(data); delay_ms(1);//output_high(ACC_CS); } //--------------------------------- int8 Acc_Read_Register(int8 reg) { int8 data; //output_low(ACC_CS); delay_ms(1);spi_write((reg & 0x3F) << 1); delay_ms(1);data = spi_read(0); delay_ms(1);//output_high(ACC_CS); return(data); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pentru filtre daca ai nevoie ceri. Ambele sunt functionale , restul depinde de tine Link spre comentariu
Vizitator andrei_wsk Postat Noiembrie 19, 2011 Partajează Postat Noiembrie 19, 2011 Multumesc mult! Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum