I2C baud rate and slave address problem

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

I2C baud rate and slave address problem

5,359 Views
rdelljh
Contributor I
I am trying to communicate with a NSC200 motion controller using the RS485 on the Wytec Dragon 12 board. From the NSC200 manual the baud rate needs to be 19200. using the SCL divider equation I get 24MHZ/19200 = 1250 which doesnt match up with any numbers in the I2C block guide. So I picked 1280 w/ IBFD as $35. I chose $1 for the slave address of the NSC200. I can not get an acknowledgment from the NSC200, just a "No Ack" on my lcd.

Here is the code:
#include "c:\egnu092\include\hcs12.h"
#include "c:\egnu092\include\vectors12.h"
#include "c:\egnu092\include\delay.c"
#include "c:\egnu092\include\lcd_util_dragon12.c"

char *version = "1VE?";
char *home = "1OR";
char *NoAck = "Fail Ack";

char receive[7];
void openI2C(char ibc, char i2c_ID);
char sendCommand(char *ptr, char ID);
char readData();
void sendSlaveID (char cx);
void displayRead(void);
void displayError(void);

int main (void){
openlcd();
openI2C(0x35,0xFE); /* set I2C baud rate to 19200Hz */
//openI2C(0x00,0xA0); // input from freescale an2318sw

sendCommand(home,0x10); //move controller to home position
//sendCommand(version,0x10); /*request to receive controller version*/
//readData();
//displayRead();
while(1);
}
void openI2C(char ibc, char i2c_ID){
IBCR |= IBEN; /* enable I2C module */
IBFD = ibc; /* configure I2C clock rate */
IBAD = i2c_ID;
IBCR &= ~IBIE; /* disable I2C interrupt */
IBCR |= IBSWAI; /* disable I2C in wait mode */
}
void sendSlaveID (char cx){
while (IBSR&IBB); /* wait until I2C bus is idle */
IBCR |= TXRX+MSSL; /* generate a start condition */
IBDR = cx; //send out the slave address with R/W bit
while(!(IBSR & IBIF)); //wait for address transmission to complete
IBSR &= IBIF; /* clear IBIF flag */
}

char readData(){
char i, temp;
sendSlaveID(0x10); //generate a start condition and send NSC200*/
if (IBSR&RXAK)
displayError();
IBCR |= RSTA; /* generate a restart condition */
IBDR = 0x11; /* send ID and set R/W flag to read */
while(!(IBSR & IBIF));
IBSR = IBIF;
if (IBSR&RXAK)
displayError(); //if NSC200 did not respond, return error code
IBCR &= ~(TXRX+TXAK); /* prepare to receive and acknowledge */
temp = IBDR; /* a dummy read to trigger 9 clock pulses */
for (i = 0; i 5; i++) {
while(!(IBSR & IBIF)); /* wait for a byte to shift in */
IBSR = IBIF; /* clear the IBIF flag */
receive[i] = IBDR; /* save the current time in buffer */
} /* also initiate the next read */
while(!(IBSR & IBIF)); /* wait for the receipt of receive[5] */
IBSR = IBIF;
IBCR |= TXAK; /* not to acknowledge receive[6] */
receive[5] = IBDR; /* save receive[5] and initiate next read */
while(!(IBSR & IBIF));
IBSR = IBIF;
IBCR &= ~MSSL; /* generate stop condition */
receive[6] = IBDR;
return 0;
}

char sendCommand(char *ptr, char ID){
char i;
sendSlaveID(0x10); /* send ID to NSC200 */
if(IBSR & RXAK) /* did NSC200 acknowledge? */
displayError();

for(i = 3; i >= 0; i--) {
IBDR = *(ptr+i);
while(!(IBSR&IBIF));
IBSR = IBIF;
if(IBSR & RXAK)
displayError();
}
return 0;
}
void displayRead(void){
cmd2lcd(0x83); /* set cursor to row 1 column 3 */
puts2lcd(receive);
//cmd2lcd(0xC3); /* set cursor to row 2 column 3 */
}
void displayError(void){
cmd2lcd(0x83);
puts2lcd(NoAck);
}

Thanks
rdelljh
Labels (1)
0 Kudos
8 Replies

908 Views
imajeff
Contributor III
I'm confused. If the NSC200 needs RS485 then what does that have to do with I2C? The protocols are not even close.
0 Kudos

908 Views
rdelljh
Contributor I
I was under the impression that I2C was the protocol for rs485.
I you would please point me in the direction of rs485 documentation, it would be greatly appreciated.
0 Kudos

908 Views
rdelljh
Contributor I
I still cant find mention of rs485 in motorola or freescale documentation. I see JK1 the port I'm using on page 3 of the dragon 12 schematic. I also see J18, what should the jumpers be on J18?
Is SPI the protocol for rs485?
0 Kudos

908 Views
rdelljh
Contributor I
I apologize for my misuse of word protocol.
Assuming that the SPI is for rs485 (4pins), I am still having difficultly reconciling the baudrate. The NSC200 needs 19200
if I take 24MHz/19200 = 1250 which doesnt match up w/ a SPI module clock divisor.
0 Kudos

908 Views
rocco
Senior Contributor II
Hi, rdelljh:

You need to use the SCI for RS485.

RS485 is simply another 'electrical' interface for serial data. Logically, it is like RS232, in that it runs at a baud rate, and has a start-bit, seven, eight or nine data bits, an optional parity bit and one or two stop bits.

Where it is different from RS232 is in the electrical levels of the signals and the physical characteristics of the wiring. You would hook your SCI pins up to a driver/receiver IC designed for RS485.
0 Kudos

908 Views
imajeff
Contributor III
Yea RS485 uses the SCI port. I learned about RS485 with my Dragon12. The schematic shows me how to control the direction bit, which RS232 does not use. And it uses a different driver chip than RS232 which takes the direction signal to control input/output.
0 Kudos

908 Views
rdelljh
Contributor I
using the rs485 interface with SCI
I have attempted to replicate the needed CTS/RTS hardware handshake protocol, as suggested earlier by asserting the PJ0 pin to create a clear to send signal.
My motorcontroller still remains unresponsive.
I know that I am transmitting something since the TX LED lights up when I send. However, I have observed the RX LED to flicker before and after my program starts. I have been unable to collect any data.

Here is my control register setup and my "assert command".

char *error = "1TE?\r\n";

PTIJ = PTIJ | 0x01; //assert PJ0
puts2SCI1(error);
PTIJ = PTIJ & ~0x01; //de-assert PJ0
getsSCI1(data);
cmd2lcd(0x83);
puts2lcd(data);

void init_SCI1(void){
SCI1BDH = 0x00;
SCI1BDL = 78; /* set baud rate to 19200 */
SCI1CR1 = 0x00; //8-N-1
SCI1CR2 = 0x0C;
}

void putc2SCI1(char xc){
while (!(SCI1SR1&TDRE));
SCI1DRL = xc;
}

void puts2SCI1(char *ptr){
while(*ptr) {
putc2SCI1(*ptr);
ptr++;
}
}


thanks
rdelljh
0 Kudos

908 Views
rocco
Senior Contributor II
Hi, rdelljh:

I think you may need to wait for "Transmission Complete" before de-asserting PJ0. As it looks now, you would be de-asserting PJ0 right after loading the last byte into the buffer, which means the second-to-last byte has just started shifting out.

The motor controller will not receive the "\n", and will only receive the first bit or two of the "\r".
0 Kudos