Discussion in "Project Doubts" started by    omega123    Jul 19, 2010.
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.


[ 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.

#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'
 omega123 like this.
Mon Mar 14 2011, 08:08 am
no error msg.
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

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 ?

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

Andyhet
Sat May 18 2024, 07:28 am
BrettTibre
Fri May 17 2024, 06:14 pm
Gordonfax
Fri May 17 2024, 10:28 am
Davidspils
Fri May 17 2024, 10:19 am
Patricknoind
Fri May 17 2024, 09:53 am
JeremyCycle
Fri May 17 2024, 09:46 am
FrabSeby
Thu May 16 2024, 07:31 pm
PeterGem
Thu May 16 2024, 06:27 am