For anybody interested, this is a working test example of the AVR Mega16 commanding the SSC-32 servo controller that Dan was trying to get functional.
The code was written using the ImageCraft ICCAVR v7.xx C compiler.
The host controller is the Atmel STK500 fitted with a Mega16 microcontroller.
As this experiment was done using RS232 and both the STK500 and the SSC-32 are DTE devices, a NULL modem adapter is required for serial communications between the STK500 and the SSC-32 devices.
Also, ‘\r’ is adequate for the termination character at the end of a command entry.
When changing BAUD rate on the SSC-32 servo controller, power has to be re-cycled after the BAUD rate junper shunts have been re-configured.
This code should give those wanting to use an AVR to command the SSC-32 an example to look at. This is by no means the only way to accomplish the task. This was just an experiment while trying to help Dan.
Good luck!
[code]#include <iom16v.h>
#define NULL 0x00
#define SWITCH_MASK 0b01111111
#define SWITCH_0 0b01111110
#define SWITCH_1 0b01111101
#define SWITCH_2 0b01111011
#define SWITCH_3 0b01110111
#define SWITCH_4 0b01101111
#define SWITCH_5 0b01011111
#define SWITCH_6 0b00111111
#define READY 0b10000000
// Strings to output different servo angles to channel #0
char CHANNEL_0_VALUE_0] = “#0 P1425 T500”;
char CHANNEL_0_VALUE_1] = “#0 P1450 T500”;
char CHANNEL_0_VALUE_2] = “#0 P1475 T500”;
char CHANNEL_0_VALUE_3] = “#0 P1500 T500”;
char CHANNEL_0_VALUE_4] = “#0 P1525 T500”;
char CHANNEL_0_VALUE_5] = “#0 P1550 T500”;
char CHANNEL_0_VALUE_6] = “#0 P1575 T500”;
char QUERY] = “Q”;
void SSC_32_WRT(char *);
char USART_Rx(void);
void USART_Tx(char);
void main (void)
{
// Initialize the I/O ports.
DDRA = NULL; // Make PORTA inputs.
DDRB = ~NULL; // Make PORTB outputs.
PORTB = SWITCH_MASK; // Set up PORTB.
// Initialize the USART…
// Char size: 8 bit
// Parity: Disabled
// BAUD RATES for 8.000MHz
// 2400 BAUD: UBRRL = 0xCF, UBRRH = 0x00
// 9600 BAUD: UBRRL = 0x33, UBRRH = 0x00
// 38.4K BAUD: UBRRL = 0x0C, UBRRH = 0x00
// 115.2K BAUD: UBRRL = % Error too large
// BAUD RATES for 16.000MHz
// 2400 BAUD: UBRRL = 0xA0, UBRRH = 0x01
// 9600 BAUD: UBRRL = 0x67, UBRRH = 0x00
// 38.4K BAUD: UBRRL = 0x19, UBRRH = 0x00
// 115.2K BAUD: UBRRL = 0x08, UBRRH = 0x00
// Disable the USART while it is being set up.
// The following USART initialization must remain in it’s present order.
UCSRB = NULL;
UCSRA = NULL;
// Initialize the upper BAUD rate register.
UBRRH = 0x00; // Check the list above for the current BAUD rate.
// Enable the UCSRC register and set; PARITY = NONE, DATA = 8, STOP = 1
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
// Initialise the lower BAUD rate register.
UBRRL = 0xCF; // Check the list above for the current BAUD rate.
UCSRB = (1<<RXEN) | (1<<TXEN); // RXEN = Enabled, TXEN = Enabled.
// The program will loop here for ever…
while (1)
{ // No switches get checked or data sent, until the SSC-32 is READY.
SSC_32_WRT(QUERY); // Get the current SSC-32 status.
if (USART_Rx() == ‘.’); // Check for SSC-32_READY STATUS.
{ // The SSC-32 is READY, now the switches can be checked.
PORTB &= ~READY; // Turn on the STK500 READY LED.
if((PINA & SWITCH_MASK) != SWITCH_MASK) // Switch pressed?
{ // A switch has been pressed, we need to find out which one.
PORTB |= READY; // Turn off the STK500 READY LED.
PORTB &= (PINA & SWITCH_MASK); // Display the Switches on the STK500 LED’s.
switch (PINA & SWITCH_MASK)
{ // A switch is active, CASE out which switch is pressed.
case SWITCH_0: SSC_32_WRT(CHANNEL_0_VALUE_0); // Switch 0 is active.
break;
case SWITCH_1: SSC_32_WRT(CHANNEL_0_VALUE_1); // Switch 1 is active.
break;
case SWITCH_2: SSC_32_WRT(CHANNEL_0_VALUE_2); // Switch 2 is active.
break;
case SWITCH_3: SSC_32_WRT(CHANNEL_0_VALUE_3); // Switch 3 is active.
break;
case SWITCH_4: SSC_32_WRT(CHANNEL_0_VALUE_4); // Switch 4 is active.
break;
case SWITCH_5: SSC_32_WRT(CHANNEL_0_VALUE_5); // Switch 5 is active.
break;
case SWITCH_6: SSC_32_WRT(CHANNEL_0_VALUE_6); // Switch 6 is active.
break;
}
// The active switch has been found and the data has been sent. But…
// There is a 20 uS processing delay, before the SSC-32 drops the READY
// status and issues a BUSY status. We need to wait for the BUSY Status
// to become available, so we don’t overwrite the command currently being
// processed by the SSC-32.
do
SSC_32_WRT(QUERY); // Get the current SSC-32 status.
while (USART_Rx() != ‘+’); // Do until the SSC-32 BUSY status is received.
}
else PORTB |= (PINA & SWITCH_MASK); // Switch not pressed.
}
}
}
void USART_Tx(char d)
{
while (!(UCSRA & (1<<UDRE))); // Wait until the USART data buffer is empty.
UDR = d; // Send the character.
}
void SSC_32_WRT(char *p)
{
char n = NULL; // Pointer position counter.
while (p[n] != NULL) // Keep sending data until the NULL character is found.
USART_Tx(p[n++]); // Send the next character. Bump to next character.
USART_Tx(’\r’); // Send termination character to the SSC-32.
while (!(UCSRA & (1<<TXC))); // Wait for last character to complete transmission.
}
char USART_Rx(void)
{
while (!(UCSRA & (1<<RXC))); // Wait until the USART character is Recieved.
return UDR; // Get the received character.
}[/code]