interfacing MMA7660FC with at89s52
Wed Mar 09 2011, 07:46 pm
as usual did not work on the first try. can someone debug it. also can someone post the method to debug using proteus as ajay sir told to do so.
#include<reg51.h> //---------------------------------Defining Macros----- sbit sclk = P3^6; sbit sda = P3^7; #define stepper P1 //---------------------------------FXN prototypes void start_MMA7660FC(); void send_MMA7660FC(char); char get_MMA7660FC(); void stop_MMA7660FC(); void send_to_MMA7660FC(char, char); void get_from_MMA7660FC(char); void motor_cw(unsigned int); void wait(); void acknowledge(); void noacknowledge(); void DelayMs(unsigned int) ; void delay(); unsigned char i[3]; void main(void) { unsigned char x,y,z; unsigned int cnt_x; send_to_MMA7660FC(0x07,0x01); wait(); get_from_MMA7660FC(0x00); x=i[0]; y=i[1]; z=i[2]; if(x> =0x00 && x<=0x16) { cnt_x=0; cnt_x=(((-149*(x*x))/(1000)-(64*x)/(1000)+78)*10)/(72); motor_cw(cnt_x); } else if(x> =0x2B && x<=0x3F) { cnt_x=0; cnt_x=(((180*(x*x))/(1000)-(23*x)+824)*10)/(72); motor_cw(cnt_x); } } //-----------------fxn to send data to serial eeprom-- // give the adress and the data as the parametrs to the fxn void send_to_MMA7660FC(char s_address, char s_data) { start_MMA7660FC(); // sending start condition to eeprom send_MMA7660FC(0X98); // A0 = 10100000 = sending device address word for write acknowledge(); send_MMA7660FC(s_address); // sending data address acknowledge(); send_MMA7660FC(s_data); // sending data acknowledge(); stop_MMA7660FC(); // sending stop condition to eeprom acknowledge(); DelayMs(10); return; } //------------------fxn to get the data back frm the serial eeprom-- // just give the adress from where the data is to be retrieved void get_from_MMA7660FC(char s_address) { unsigned char j; //-------dummy write seq----+ word address--- start_MMA7660FC(); // sending start condition to eeprom send_MMA7660FC(0X98); // sending A0 = 10100000 = device address word for write acknowledge(); send_MMA7660FC(s_address); // sending data address acknowledge(); //----------------dummy over-- start_MMA7660FC(); send_MMA7660FC(0X99); // sending A1 =10100001 = device adress word for read acknowledge(); for(j=0;j<3;j++) { i[j] = get_MMA7660FC(); // sending data acknowledge(); } noacknowledge(); stop_MMA7660FC(); // sending stop condition to eeprom return; } //----------------------fxn to transmit a byte to the eeprom //this fxn just send the 8 bits serialy on the SDA line //this fnx does not store the data in eeprom but just transmits it, this fxn is used by the storing fxn //just pass the byte to be transmitted as parameter to this fxn void send_MMA7660FC(char s_byte) { char temp = s_byte; char i ; for(i = 7 ; i > = 0 ; i--) { temp = s_byte; temp = temp > > i; temp = temp & 0X01; if(temp == 0) sda = 0; else sda = 1; sclk = 1; wait(); sclk = 0; } return; } //---------------------------fxn to receive 8 bits serialy from sda line- // this is not a fxn to read from eeprom // it just receives 8 bits serialy and retuns the byte received to the calling fxn char get_MMA7660FC() { char temp, temp_h, i; temp = 0; temp_h = 1; sda = 1; // making SDA as input pin for microcontroller sclk = 0; for(i = 7; i > =0 ; i--) { sclk = 1; if(sda == 1) { temp = temp | temp_h<<i ; } wait(); sclk = 0; } sclk = 0; return(temp); } //--------------------------fxn to send the start condition void start_MMA7660FC() { sda = 1; sclk = 1; wait(); sda = 0; sclk = 0; return; } //------------------------------fxn to send stop condition void stop_MMA7660FC() { sda = 0; sclk = 1; wait(); sda = 1; sclk = 0; return; } //-------------------------------------fxn for acknowledging the eeprom // this fxn actualy does not read the acknowledge signal // it just waits for sufficient time and assumes that the eeprom has given tha ack by the time the wait gets over void acknowledge() { sda = 0; sclk = 1; wait(); sclk = 0; return; } //--------------------------a small delay fxn to ensure the line settels down after transition------------------------------- void wait() { char i; for(i=0;i<=20;i++) i++; return; } void delay() { unsigned char l,m,n; for(l=0;l<6;l++) for(m=0;m<255;m++) for(n=0;n<255;n++); } void motor_cw(unsigned int cntr) { unsigned int a; for(a=0;a<cntr;a++) { stepper = 0x08; delay(); stepper = 0x0C; delay(); stepper = 0x04; delay(); stepper = 0x06; delay(); stepper = 0x02; delay(); stepper = 0x03; delay(); stepper = 0x01; delay(); stepper = 0x09; delay(); } } // Delay mS function //--------------------------------------- void DelayMs(unsigned int count) { // mSec Delay 11.0592 Mhz unsigned int i; // Keil v7.5a while(count) { i = 115; while(i> 0) i--; count--; } } void noacknowledge() { sda = 1; sclk = 1; wait(); sclk = 0; return; }
Wed Mar 09 2011, 09:51 pm
You need to test any program one step at a time.
First establish that you can read from the MMA7660FC.
Write a simple program that reads from the MMA7660FC and displays one register
either by lighting LEDS on a port or sending the byte to your PC.
Have the test program loop, so it reads once per second.
To use Proteus you need to create the circuit in Proteus.
Add the hex code of you program to the Proteus project and run
a simulation.
Proteus is a complex, professional program, so will need some time to learn.
Proteus works by modelling the actions of the circuit components.
It does not have a model of a MMA7660FC, so test using a serial eeprom, which
is written to and read the same way.
First establish that you can read from the MMA7660FC.
Write a simple program that reads from the MMA7660FC and displays one register
either by lighting LEDS on a port or sending the byte to your PC.
Have the test program loop, so it reads once per second.
To use Proteus you need to create the circuit in Proteus.
Add the hex code of you program to the Proteus project and run
a simulation.
Proteus is a complex, professional program, so will need some time to learn.
Proteus works by modelling the actions of the circuit components.
It does not have a model of a MMA7660FC, so test using a serial eeprom, which
is written to and read the same way.
[ Edited Wed Mar 09 2011, 09:56 pm ]
Thu Mar 10 2011, 11:43 pm
@experimenteruk
am doing what i did with the assembly code..trying the test mode. it allows user to write values to the x y z registers. but as usual not working.
am doing what i did with the assembly code..trying the test mode. it allows user to write values to the x y z registers. but as usual not working.
#include<reg51.h> //---------------------------------Defining Macros sbit sclk = P3^6; sbit sda = P3^7; #define stepper P1 //---------------------------------FXN prototypes void start_MMA7660FC(); void send_MMA7660FC(char); unsigned char get_MMA7660FC(); void stop_MMA7660FC(); void send_to_MMA7660FC(char, char); void get_from_MMA7660FC(char); void wait(); void acknowledge(); void noacknowledge(); void DelayMs(unsigned int) ; unsigned char i[3]=0; void main(void) { TMOD=0X20; SCON=0X50; TH1=0XFD; TR1=1; send_to_MMA7660FC(0x07,0x00); send_to_MMA7660FC(0x07,0x04); send_to_MMA7660FC(0x00,0x01); send_to_MMA7660FC(0x01,0x02); send_to_MMA7660FC(0x02,0x03); send_to_MMA7660FC(0x07,0x01); get_from_MMA7660FC(0x00); while(1) { unsigned char x; for(x=0;x<10;x++) { SBUF=i[x]; while(TI==0); TI=0; } } } //-----------------fxn to send data to serial eeprom // give the adress and the data as the parametrs to the fxn void send_to_MMA7660FC(char s_address, char s_data) { unsigned char e; for(e=0;e<10;e++) { start_MMA7660FC(); // sending start condition to eeprom send_MMA7660FC(0X98); // A0 = 10100000 = sending device address word for write acknowledge(); send_MMA7660FC(s_address+e); // sending data address acknowledge(); send_MMA7660FC(s_data); // sending data acknowledge(); stop_MMA7660FC(); // sending stop condition to eeprom acknowledge(); DelayMs(20); } return; } //------------------fxn to get the data back frm the serial eeprom // just give the adress from where the data is to be retrieved void get_from_MMA7660FC(char s_address1) { unsigned char j; //-------dummy write seq----+ word address------------------------------------ start_MMA7660FC(); // sending start condition to eeprom send_MMA7660FC(0X98); // sending A0 = 10100000 = device address word for write acknowledge(); send_MMA7660FC(s_address1); // sending data address acknowledge(); //----------------dummy over---------------------------------------------------- start_MMA7660FC(); send_MMA7660FC(0X99); // sending A1 =10100001 = device adress word for read acknowledge(); for(j=0;j<3;j++) { i[j] = get_MMA7660FC(); // sending data acknowledge(); } noacknowledge(); stop_MMA7660FC(); // sending stop condition to eeprom return; } //----------------------fxn to transmit a byte to the eeprom //this fxn just send the 8 bits serialy on the SDA line //this fnx does not store the data in eeprom but just transmits it, this fxn is used by the storing fxn //just pass the byte to be transmitted as parameter to this fxn void send_MMA7660FC(unsigned char Data) { unsigned char BitCounter=8; // 8 bits in a BYTE do { sclk=0; wait(); wait(); if((Data & 0x80)==0x80) // detcting is it 1 or 0 sda=1; else sda=0; wait(); sclk=1; wait(); Data=Data<<1; // shifting left BitCounter--; } while(BitCounter); sclk=0; } //---------------------------fxn to receive 8 bits serialy from sda line // this is not a fxn to read from eeprom // it just receives 8 bits serialy and retuns the byte received to the calling fxn unsigned char get_MMA7660FC(void) { unsigned char temp=0; unsigned BitCounter=8; sda=1; do{ sclk=0; wait(); sclk=1; wait(); if(sda) temp=temp|0x01; else temp=temp&0xfe; if(BitCounter-1) temp=temp<<1; BitCounter--; } while(BitCounter); return(temp); } //--------------------------fxn to send the start condition void start_MMA7660FC() { sda = 1; sclk = 1; wait(); sda = 0; wait(); sclk = 0; return; } //------------------------------fxn to send stop condition-------------------------------------------------------------------- void stop_MMA7660FC() { sclk = 0; sda = 0; wait(); sclk = 1; wait(); sda = 1; wait(); return; } //-------------------------------------fxn for acknowledging the eeprom // this fxn actualy does not read the acknowledge signal // it just waits for sufficient time and assumes that the eeprom has given tha ack by the time the wait gets over void acknowledge() { sclk=0; sda = 0; wait(); sclk = 1; wait(); sclk = 0; return; } //--------------------------a small delay fxn to ensure the line settels down after transition void wait() { char c; for(c=0;c<=20;c++) c++; return; } // Delay mS function //--------------------------------------- void DelayMs(unsigned int count) { // mSec Delay 11.0592 Mhz unsigned int e; // Keil v7.5a while(count) { e = 115; while(e> 0) e--; count--; } } void noacknowledge() { sclk=0; sda = 1; wait(); sclk = 1; wait(); sclk = 0; return; }
[ Edited Thu Mar 10 2011, 11:57 pm ]
Fri Mar 11 2011, 12:36 am
@experimenteruk
am doing what i did with the assembly code..trying the test mode. it allows user to write values to the x y z registers. but as usual not working.omega123
Which compiler are you using ?
does it have a library of I2C functions ?
If not, it may be worth trying inline assembly.
You could use the assembly code that already works to read the accelerometer.
I say "may" because it might also add more complications.
Read this page
http://www.keil.com/support/docs/2308.htm
then try some simple bits of inline code to see if it worth trying.
You assembly code is quite simple, so it should go inline without too much trouble.
[ Edited Fri Mar 11 2011, 02:25 am ]
omega123 like this.
Fri Mar 11 2011, 06:33 pm
@experimenterUK thank u for your suggestion. here is a program i wrote to test it. the only issue is that it does not consider anything after the line#pragma endasm. here is the code. it doesnot complie the "c" part of the code.
#include<reg51.h> #define x_val 0x50 #define stepper P1 void motor_cw(unsigned int); void delay(); void main(void) { unsigned int x_axis=0; #pragma asm mov x_val,#22 #pragma endasm if(x_val> =0x00 && x_val<=0x16) { x_axis=(((-149*(x_val*x_val))/(1000)-(64*x_val)/(1000)+78)*10)/(72); motor_cw(x_axis); } else if(x_val> =0x2B && x_val<=0x3F) { x_axis=(((180*(x_val*x_val))/(1000)-(23*x_val)+824)*10)/(72); motor_cw(x_axis); } } void motor_cw(unsigned int cntrx) { unsigned int a; for(a=0;a<cntrx;a++) { stepper = 0x08; delay(); stepper = 0x0C; delay(); stepper = 0x04; delay(); stepper = 0x06; delay(); stepper = 0x02; delay(); stepper = 0x03; delay(); stepper = 0x01; delay(); stepper = 0x09; delay(); } } void delay() { unsigned char l,m,n; for(l=0;l<6;l++) for(m=0;m<255;m++) for(n=0;n<255;n++); }
[ Edited Fri Mar 11 2011, 08:34 pm ]
Mon Mar 14 2011, 02:30 am
Inline code cannot access 'C' variables
so "mov x_val,#22" is illegal.
Did you get error message ?
However accessing Ports is okay, so this is fine.
#pragma asm
setb SDA
#pragma endasm
Most of your interface code will be fine,
just use the Accumulator to pass results back to 'C'
so "mov x_val,#22" is illegal.
Did you get error message ?
However accessing Ports is okay, so this is fine.
#pragma asm
setb SDA
#pragma endasm
Most of your interface code will be fine,
just use the Accumulator to pass results back to 'C'
omega123 like this.
Mon Mar 14 2011, 12:50 pm
as i am thinking in ur first code on this page
http://www.8051projects.net/forum-t36102-last.html
u write this
but in asm code u write
ur swaping the pins
now do change in c code as
http://www.8051projects.net/forum-t36102-last.html
u write this
sbit sclk = P3^6;
sbit sda = P3^7;
but in asm code u write
SDA equ P3.6
SCL equ P3.7
ur swaping the pins
now do change in c code as
sbit sclk = P3^7;
sbit sda = P3^6;
Mon Mar 14 2011, 08:50 pm
@majoka already changed it, but forgot to post correction. here is the code but still no output from motor.
#include<reg51.h> sbit SDA = P3^6; sbit SCL = P3^7; #define stepper P1 void motor_cw(unsigned int); void delay(); void main(void) { unsigned int x_axis=0; #pragma asm mov scon,#0x50 // initilaizing serial port at 9600 @ 11.0592MHz mov tmod,#0x20 mov th1,#0xfd mov tl1,#0xfd setb tr1 acall init //active mode mov r7,#98h // device address 0x98 mov r6,#07h // write to mode reg mov r5,#01h // write mode reg to 00000001 acall write_byte // all is done in this function mov 0x41,#20 call delayms mov 0x41,#20 call delayms mov r7,#98h // device address 0x98 mov r6,#00h // starting address mov r5,#99h // read mode call read_block mov a,r0 init: setb sda setb scl ret read_block: call start jc x35 mov a,r7 call shout jc x34 mov a,r6 call shout jc x34 call start jc x34 mov a,r5 //read form mma7660 read addres 0x99 call shout jc x34 // read from register 0 call shin mov r0,a call ACK // read from register 1 call shin mov r1,a call ACK // read from register 2 call shin mov r2,a call ACK call NAK clr c x34: call stop x35: ret write_byte: call start jc x49 mov a,r7 call shout jc x48 mov a,r6 call shout jc x48 mov a,r5 call shout jc x48 clr c x48: call stop x49: ret start: setb SDA setb SCL jnb SDA, x40 jnb SCL, x40 nop clr SDA nop nop nop nop nop clr SCL clr c jmp x41 x40: setb c x41: ret stop: clr SCL clr SDA nop nop setb SCL nop nop nop nop nop setb SDA ret shout: mov b, #8 x42: rlc a mov SDA, c nop setb SCL nop nop nop nop clr SCL djnz b, x42 setb SDA nop nop setb SCL nop nop nop nop mov c, SDA clr SCL ret shin: setb SDA mov b, #8 x43: nop nop nop setb SCL nop nop mov c, SDA rlc a clr SCL djnz b, x43 ret ACK: clr SCL clr SDA nop nop setb SCL nop nop nop nop clr SCL ret NAK: clr SCL setb SDA nop nop setb SCL nop nop nop nop clr SCL ret delayms: mov 0x40,#230 d: nop nop djnz 0x40,d djnz 0x41,delayms ret #pragma endasm if(ACC> =0x00 && ACC<=0x16) { x_axis=(((-149*(ACC*ACC))/(1000)-(64*ACC)/(1000)+78)*10)/72; motor_cw(x_axis); } else if(ACC> =0x2B && ACC<=0x3F) { x_axis=(((180*(ACC*ACC))/(1000)-(23*ACC)+824)*10)/72; motor_cw(x_axis); } } void motor_cw(unsigned int cntrx) { unsigned int a; for(a=0;a<cntrx;a++) { stepper = 0x08; delay(); stepper = 0x0C; delay(); stepper = 0x04; delay(); stepper = 0x06; delay(); stepper = 0x02; delay(); stepper = 0x03; delay(); stepper = 0x01; delay(); stepper = 0x09; delay(); } } void delay() { unsigned char l,m,n; for(l=0;l<6;l++) for(m=0;m<255;m++) for(n=0;n<255;n++); }
Mon Mar 14 2011, 11:00 pm
@majoka already changed it, but forgot to post correction. here is the code but still no output from motor.omega123
Don't worry about the motor for now, are you *sure* you are able to read the MMA7660FC properly ?
Powered by e107 Forum System