SCoAuNt hNeert nwoSr kt yinleg
by Fred Eady
Being a Southern boy from Tennessee, I grew up with lots of “canned” stuff. Let’s see, there were
canned peaches, canned beans, canned corn, canned okra (my favorite), and canned apples, just to
name a few of the delicacies I enjoyed as a child. The really funny thing is that “canning” in my
hometown of Fayetteville wasn’t (and isn’t today) done with metal cans. “Canning” is done with Mason
Jars. This month, we’re going to enjoy a different kind of canned delight ... CANned motor control.
Last time, we discussed the nature of the CAN (Controller
Area Network) protocol and assembled some very
simple PIC-based CAN hardware. To accomplish the
motor control task, we’ll add a full-bridge PWM (Pulse Width
Modulation) motor driver in the form of an Allegro A3953SB
to one of our CAN nodes. Before we add the additional
motor driver hardware, for starters, let’s put some CAN
application code together and control an LED. We’ll use the
HI-TECH PICC- 18 C compiler for this project as I have found
that particular C Compiler code is very easy to port to other
programming languages.
Definitions in a CAN
Microchip has done a great deal of the CAN coding
for us. Our CAN application firmware will draw from a
CAN code module that Microchip freely supplies on their
website. All we have to do is include the files ecan.c and
ecan.h in our application source code. The inclusion of
the ecan files allows us to easily send and receive CAN
messages using “canned” functions embedded within
the ecan.c file. For instance, to receive a CAN message
we simply invoke the ECANReceiveMessage function in
this manner:
if(ECANReceiveMessage(&id, data, &dataLen, &canflags))
{
// Do our work here..
}
The arguments of the ECANReceiveMessage function
include our CAN ID (id), up to eight bytes of data (data), the
actual data length (dataLen), and CAN-message-related flag
data (canflags).
Sending a CAN message is just as easy. Instead of
parsing the arguments of the function as we must do in the
ECANReceiveMessage function, we stuff in the CAN ID,
data, and data length values and use the ECANSendMessage
function to push the CAN bits out onto the CAN bus. Once
all of the data we want to send has been loaded into the
correct memory slots, we invoke the ECANSendMessage
function like this:
while(!ECANSendMessage(id, data, dataLen,
ECAN_TX_STD_FRAME));
In our CAN application, we will always transmit a
standard CAN frame. Thus, ECAN_TX_STD_FRAME will
always be present in our ECANSendMessage function calls.
The ECANSendMessage function returns a completion value
and that’s what we’re waiting for in the ECANSendMessage
statement I just revealed to you.
Before we can use the CAN send and receive functions,
in addition to including the ecan.c and ecan.h files, we must
declare the following variables:
unsigned long id;
char data[8];
char dataLen;
ECAN_RX_MSG_FLAGS canflags;
As you have already ascertained, the variables we
declared are used by the “canned” send and receive
CAN message functions. While we’re here, let’s go ahead
and define our CAN node IDs and establish the nodes’
logical addresses. Here’s what that looks like for our
CAN nodeA:
#define myid
#define nodeA
#define nodeB
0x141
0x41
0x42
The only change we make to the addressing definitions
in our CAN nodeB is to alter the myid value to 0x142. Recall
that CAN node addressing is done within the contents of the
CAN message. Thus, nodeA is at logical address 0x41 and
nodeB has a CAN mailbox at address 0x42. Also, remember
that the lower the CAN ID, the higher its transmit priority.
SERVO 09.2007 55