IIC help please...MC9S08SH

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IIC help please...MC9S08SH

Jump to solution
2,019 Views
rokzar
Contributor II

Hello,

        to put it simply, i have given it my all and failed trying to make an IR sensor work with the IIC module on my board. I have read all the IIC app notes, search this forum back and forth...read HCS08 unleashed and now i simply have to ask for help.

My dilemma:

-I am new to programming so thats a handicap right there

-my code only seems to WORK only when i step line by line while in debug mode

-i have scoped my signals and they appear to be functioning (only in debug mode)

-Once i hit the run buttonthe code completes one loop then freezes at

      while (!(IICS_IICIF));  //  <---  stops here during "free run"

When this occurs, my SDA line is held low by the sensor. It stops at the same place even when i disable the watchdog.

The sensor http://www.robotshop.us/solarbotics-i2c-it-ir-rangefinder-1.html

 comes with code for PICS and other processors, and it appears to be very easy to work with, but i cant get it to work with what i have (MC9S08SH

 

MY CODE:

-------------------------------------------------------------------------------- 

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

#define trimvalue 0xFFAE      //debugger calculated trim value
#define LED3  PTCD_PTCD1
#define LED4  PTCD_PTCD0


#define IRaddress   0x20
#define IRreceive   0
#define IRtransmit  1
#define inch        1
#define cm          2
#define raw         3

unsigned int data1,data2,data3,data4;        //for data and testing

 /*SCI setup*/
void SCI_init(void){
 
  SCIBD = 26;      //set baud rate to 19200= 8MHz/(16*(SCIBD))
  SCIC2 =0b00001100;  //enable receive and transmit
 
}


 /* simple software delay */
 
 void delay (unsigned int long value){
  for (;value<=0;value--)__RESET_WATCHDOG();
 }

/*MCU setup*/

void MCU_init (void){
 ICSTRM  =  trimvalue;         //set to calcuated trim value
 PTCDD = 0b00000011;          // make PTC0,1 output for leds
 SPMSC1_BGBE =1;              //enable bandgap buffer.
}

/*IIC setup*/
  void IIC_init(void){
  IICC1_IICEN = 1;  //enable module IIC module
  IICF_MULT= 0x01;  //divide by 2
  IICF_ICR0x14;  //divide by 80;       (50khz)
 
   } 
/*master send function call*/ 
  void master_send (void){
  IICC1= 0b10110000;     //iic enable, no iterrupt,master,transmit,ack on,)
  return;
  }
/*master receive function call*/
  void master_receive (void){
  IICC1= 0b10101000;
  return;
  }
/*iic disable*/
void iic_disable(void){
  IICC1_IICEN = 0;     //disable iic module
  return;            
}
void main(void) {

  EnableInterrupts; /* enable interrupts */
  MCU_init();
  SCI_init();
  IIC_init();
  SCID=0x22;   // test to check reset
 

for(;:smileywink:
 
   
   LED3=1;
  
   master_send();
   IICD=0x20<<1|0;  //write address, put in receive mode
   while (!(IICS_IICIF));
   IICS_IICIF = 1
   while(IICS_RXAK); // check for RX ack;
   //IICC_RSTA=1;      //restart send
   IICD=2;           // ask sensor to send in CM
   while (!(IICS_IICIF));  //  <---  stops here during "free run"
   IICS_IICIF = 1
   while(IICS_RXAK); // check for RX ack;
   IICC_RSTA=1;      //restart send
   IICD=0x20<<1|1;  //write address, put in transmit mode
   delay(10000);
  while (!(IICS_IICIF));
   IICS_IICIF = 1
   while(IICS_RXAK); // check for RX ack;
   //--------------------------------
    IICC_TX=0; //switch to receive mode
    data1=IICD;   //dummy read!!       <--reads sensor value!!
    IICC_TXAK = 1; // acknowledge disable;      <-- have tried swapping bits and places
    IICC_MST = 0; // generate stop signal;
    data2 = IICD; // read correct data;
   
    if(SCIS1_TDRE ==1){       //serial for debug
    SCID=data2;
  }
  
   __RESET_WATCHDOG(); /* feeds the dog */
 
 
  } /* loop forever */
  /* please make sure that you never leave main */
}

 

 

thanks in advance.

Labels (1)
0 Kudos
1 Solution
430 Views
rokzar
Contributor II

I finally got the sensor to work. Thanks Dave for the suggestions about using delays to troubleshoot. I think what i was missing all along might have been

- resend the start command between write and read

- disable the iic module when i have finished reading the data (otherwise on the next cycle things froze up)

- only setting MST=0 did not help ...hence had to disable the whole iic module.

 

the final code is shown below. Thanks once more

 

// this version of code works.


#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

#define trimvalue 0xFFAE      //debugger calculated trim value
#define LED3  PTCD_PTCD1
#define LED4  PTCD_PTCD0


#define IRaddress   0x20
#define IRreceive   0
#define IRtransmit  1
#define inch        1
#define cm          2
#define raw         3

volatile unsigned int data1,data2,data3;

 /*SCI setup*/
void SCI_init(void){
 
  SCIBD = 26;      //set baud rate to 19200= 8MHz/(16*(SCIBD))
  SCIC2 =0b00001100;  //enable receive and transmit
 
}


 /* simple software delay */
 
 void delay (unsigned int long value){
  for (;value>0;value--)__RESET_WATCHDOG();
 }

/*MCU setup*/

void MCU_init (void){
 ICSTRM  =  trimvalue;         //set to calcuated trim value
 PTCDD = 0b00000011;          // make PTC0,1 output for leds
 SPMSC1_BGBE =1;              //enable bandgap buffer.
}

/*IIC setup*/
  void IIC_init(void){
  IICC1_IICEN = 1;  //disable module IIC module
  IICF_MULT= 0x10;  //divide by 4        01
  IICF_ICR=  0x00;  //divide by 40;      07
 
   } 
/*master send function call*/ 
  void master_send (void){
  IICC1= 0b10111000;     //iic enable, no iterrupt,master,transmit,ack on,)
  return;
  }
/*master receive function call*/
  void master_receive (void){
  IICC1= 0b10101000;
  return;
  }
/*iic disable*/
void iic_disable(void){
  IICC1_IICEN = 0;     //disable iic module
  IICD=0;
  return;              //write zeros to iic data register.
}
void main(void) {

  EnableInterrupts; /* enable interrupts */
  MCU_init();
  SCI_init();
  IIC_init();
  SCID=0x22;   // test to check reset (help debug)


for(;:smileywink:
 
     delay (10000);    //allow time for sensor to initiate!
    //-----setup sensor units
     LED3=1;          // to help debug
     master_send();   //configure as master, transmit mode
     IICD=(0x20<<1)|0;  //send address and write bit
     delay (10);
     while (!IICS_TCF)__RESET_WATCHDOG(); //wait until transmission finishes
     delay (10);
     IICD= cm;    //tell sensor to send units in CM
      delay (10);
     while (!IICS_TCF)__RESET_WATCHDOG(); //wait until transmission finishes
     delay(10);
  if(IICS_RXAK==0){
     LED4=~LED4;          //to help debug
      }
      IICC1_RSTA=1 ;   //set restart bit
   //--------read sensor
 
    master_send();
    delay (10);
    IICD=(0x20<<1)|1;  //send address and receive bit
    delay (10);
    while(!IICS_TCF)__RESET_WATCHDOG(); //wait for trans to complete
    master_receive();    //put in receive mode
    data1 = IICD;       //dummy read
    while(!IICS_TCF)__RESET_WATCHDOG(); //wait for trans to complete
    IICC_TXAK=1;     //No ACK
    data2 = IICD;    // REAL DATA
    IICC1_MST=0;       //release bus
    iic_disable();    //disable iic module all together.
   
    //--------serial transmit
    if (SCIS1_TDRE==0){           //if not ready to send wait
              __RESET_WATCHDOG();
           }
   SCID=data2;
   
    __RESET_WATCHDOG(); /* feeds the dog */
  
  
  } /* loop forever */
  /* please make sure that you never leave main */
}

 

I will clean things up later on....

 

 

View solution in original post

0 Kudos
3 Replies
430 Views
DRichards
Contributor III

As you say your code works when you single step, perhaps you are not meeting a timing requirement when you run at full speed. Try putting delays in between the preceeding few lines. If this works you can hone down the delays to find the problem area.

 

By the way, your delay routine looks wrong. You have for(;value<=0;value--), this should be

  for(;value>=0;value--) assuming you are supplying positive values for value. (You could of course change this to for(;value>0;value--) if you wanted to use unsigned values).

0 Kudos
430 Views
rokzar
Contributor II

DRich- thanks for pointing out the delay error.

I also suspect  i am having a timing/sequence issue. I have tried twicking the IIC baud rate and adding delays but it doesnt work either....(still get stuck at the same point).

 

what i dont understand is why the sensor appears to be holding the SDA line low after the first loop, and why the processor thinks it getting the first ACK but not the second!! (on the second loop around). I have been working on this for almost a week and am at the point of giving up and using an analog sensor.....

 I will post the sample code for PICS and maybe someone will be able to point out something I'm missing.

Ill keep you posted.                             

0 Kudos
431 Views
rokzar
Contributor II

I finally got the sensor to work. Thanks Dave for the suggestions about using delays to troubleshoot. I think what i was missing all along might have been

- resend the start command between write and read

- disable the iic module when i have finished reading the data (otherwise on the next cycle things froze up)

- only setting MST=0 did not help ...hence had to disable the whole iic module.

 

the final code is shown below. Thanks once more

 

// this version of code works.


#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

#define trimvalue 0xFFAE      //debugger calculated trim value
#define LED3  PTCD_PTCD1
#define LED4  PTCD_PTCD0


#define IRaddress   0x20
#define IRreceive   0
#define IRtransmit  1
#define inch        1
#define cm          2
#define raw         3

volatile unsigned int data1,data2,data3;

 /*SCI setup*/
void SCI_init(void){
 
  SCIBD = 26;      //set baud rate to 19200= 8MHz/(16*(SCIBD))
  SCIC2 =0b00001100;  //enable receive and transmit
 
}


 /* simple software delay */
 
 void delay (unsigned int long value){
  for (;value>0;value--)__RESET_WATCHDOG();
 }

/*MCU setup*/

void MCU_init (void){
 ICSTRM  =  trimvalue;         //set to calcuated trim value
 PTCDD = 0b00000011;          // make PTC0,1 output for leds
 SPMSC1_BGBE =1;              //enable bandgap buffer.
}

/*IIC setup*/
  void IIC_init(void){
  IICC1_IICEN = 1;  //disable module IIC module
  IICF_MULT= 0x10;  //divide by 4        01
  IICF_ICR=  0x00;  //divide by 40;      07
 
   } 
/*master send function call*/ 
  void master_send (void){
  IICC1= 0b10111000;     //iic enable, no iterrupt,master,transmit,ack on,)
  return;
  }
/*master receive function call*/
  void master_receive (void){
  IICC1= 0b10101000;
  return;
  }
/*iic disable*/
void iic_disable(void){
  IICC1_IICEN = 0;     //disable iic module
  IICD=0;
  return;              //write zeros to iic data register.
}
void main(void) {

  EnableInterrupts; /* enable interrupts */
  MCU_init();
  SCI_init();
  IIC_init();
  SCID=0x22;   // test to check reset (help debug)


for(;:smileywink:
 
     delay (10000);    //allow time for sensor to initiate!
    //-----setup sensor units
     LED3=1;          // to help debug
     master_send();   //configure as master, transmit mode
     IICD=(0x20<<1)|0;  //send address and write bit
     delay (10);
     while (!IICS_TCF)__RESET_WATCHDOG(); //wait until transmission finishes
     delay (10);
     IICD= cm;    //tell sensor to send units in CM
      delay (10);
     while (!IICS_TCF)__RESET_WATCHDOG(); //wait until transmission finishes
     delay(10);
  if(IICS_RXAK==0){
     LED4=~LED4;          //to help debug
      }
      IICC1_RSTA=1 ;   //set restart bit
   //--------read sensor
 
    master_send();
    delay (10);
    IICD=(0x20<<1)|1;  //send address and receive bit
    delay (10);
    while(!IICS_TCF)__RESET_WATCHDOG(); //wait for trans to complete
    master_receive();    //put in receive mode
    data1 = IICD;       //dummy read
    while(!IICS_TCF)__RESET_WATCHDOG(); //wait for trans to complete
    IICC_TXAK=1;     //No ACK
    data2 = IICD;    // REAL DATA
    IICC1_MST=0;       //release bus
    iic_disable();    //disable iic module all together.
   
    //--------serial transmit
    if (SCIS1_TDRE==0){           //if not ready to send wait
              __RESET_WATCHDOG();
           }
   SCID=data2;
   
    __RESET_WATCHDOG(); /* feeds the dog */
  
  
  } /* loop forever */
  /* please make sure that you never leave main */
}

 

I will clean things up later on....

 

 

0 Kudos