Выбрать главу

  //

  dt = 0;

  while(!dt) dt = CANRead(&id, data, &len, &read_flag);

  if (id == 3) {

   temperature = data[0];

   ByteToStr(temperature,txt); // Convert to string

   Lcd_Out(1,8,txt);           // Output to LCD

   Delay_ms(1000);             // Wait 1 second

  }

 }

}

Figure 9.17: DISPLAY program listing

The mikroC CAN bus function CANInitialize is used to initialize the CAN module. The timing parameters and the initialization flag are specified as arguments in this function.

The initialization flag is made up from the bitwise AND of:

init_flag = CAN_CONFIG_SAMPLE_THRICE &

 CAN_CONFIG_PHSEG2_PRG_ON &

 CAN_CONFIG_STD_MSG &

 CAN_CONFIG_DBL_BUFFER_ON &

 CAN_CONFIG_VALID_XTD_MSG &

 CAN_CONFIG_LINE_FILTER_OFF;

Where sampling the bus three times is specified, the standard identifier is specified, double buffering is turned on, and the line filter is turned off.

Then the operation mode is set to CONFIG and the filter masks and filter values are specified. Both mask 1 and mask 2 are set to all 1’s (–1 is a shorthand way of writing hexadecimal FFFFFFFF, i.e., setting all mask bits to 1’s) so that all filter bits match up with incoming data.

Filter 3 for buffer 2 is set to value 3 so that identifiers having values 3 are accepted by the receive buffer.

The operation mode is then set to NORMAL. The program then configures the LCD and displays the message “CAN BUS” for one second on the LCD.

The main program loop executes continuously and starts with a for statement. Inside this loop the LCD is cleared and text “TEMP =” is displayed on the LCD. Then character “T” is sent over the bus with the identifier equal to 500 (the COLLECTOR node filter is set to accept identifier 500). This is a request to the COLLECTOR node to send the temperature reading. The program then reads the temperature from the CAN bus, converts it to a string in array txt, and displays it on the LCD. This process repeats after a one-second delay.

COLLECTOR Program

Figure 9.18 shows the program listing of the COLLECTOR program, called COLLECTOR.C. The initial part of this program is the same as the DISPLAY program. The receive filter is set to 500 so that messages with identifier 500 are accepted by the program.

/***********************************************************************

                   CAN BUS EXAMPLE - NODE: COLLECTOR

                   =================================

This is the COLLECTOR node of the CAN bus example. In this project a

PIC18F258 type microcontroller is used. An MCP2551 type CAN bus transceiver

is used to connect the microcontroller to the CAN bus. The microcontroller is

operated from an 8MHz crystal with an external reset button.

Pin CANRX and CANTX of the microcontroller are connected to pins RXD

and TXD of the transceiver chip respectively. Pins CANH and CANL of the

transceiver chip are connected to the CAN bus.

An LM35DZ type analog temperature sensor is connected to port AN0 of the

microcontroller. The microcontroller reads the temperature when a request is

received and then sends the temperature value as a byte to Node:DISPLAY on

the CAN bus.

CAN speed parameters are:

Microcontroller clock: 8MHz

CAN Bus bit rate:      100Kb/s

Sync_Seg:              1

Prop_Seg:              6

Phase_Seg1:            6

Phase_Seg2:            7

SJW:                   1

BRP:                   1

Sample point:          65%

Author: Dogan Ibrahim

Date:   October 2007

File:   COLLECTOR.C

**********************************************************************/

void main() {

 unsigned char temperature, data[8];

 unsigned short init_flag, send_flag, dt, len, read_flag;

 char SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg, txt[4];

 unsigned int temp;

 unsigned long mV;

 long id, mask;

 TRISA = 0xFF; // PORTA are inputs

 TRISB = 0x08; // RB2 is output, RB3 is input

 //

 // Configure A/D converter

 //

 ADCON1 = 0x80;

 //

 // CAN BUS Timing Parameters

 //

 SJW = 1;

 BRP = 1;

 Phase_Seg1 = 6;

 Phase_Seg2 = 7;

 BRP = 1;

 Prop_Seg = 6;

 init_flag = CAN_CONFIG_SAMPLE_THRICE &

  CAN_CONFIG_PHSEG2_PRG_ON &

  CAN_CONFIG_STD_MSG &

  CAN_CONFIG_DBL_BUFFER_ON &

  CAN_CONFIG_VALID_XTD_MSG &

  CAN_CONFIG_LINE_FILTER_OFF;

 send_flag = CAN_TX_PRIORITY_0 &

  CAN_TX_XTD_FRAME &

  CAN_TX_NO_RTR_FRAME;

 read_flag = 0;

 //

 // Initialise CAN module

 //

 CANInitialize(SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg, init_flag);

 //

 // Set CAN CONFIG mode

 //

 CANSetOperationMode(CAN_MODE_CONFIG, 0xFF);

 mask = -1;

 //

 // Set all MASK1 bits to 1's

 //

 CANSetMask(CAN_MASK_B1, mask, CAN_CONFIG_XTD_MSG);

 //

 // Set all MASK2 bits to 1's

 //

 CANSetMask(CAN_MASK_B2, mask, CAN_CONFIG_XTD_MSG);

 //

 // Set id of filter B1_F1 to 3

 //

 CANSetFilter(CAN_FILTER_B2_F3,500,CAN_CONFIG_XTD_MSG);

 //

 // Set CAN module to NORMAL mode

 //

 CANSetOperationMode(CAN_MODE_NORMAL, 0xFF);

 //

 // Program loop. Read the temperature from analog temperature

 // sensor

 //

 for(;;) // Endless loop

 {

  //