⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv_can.txt

📁 picos18的can驱动样例程序
💻 TXT
字号:
 ______________________________________________________________________
>                                                                      <
>                         CAN bus driver v1.05                         <
>                                 for                                  <
>                         PICos18 release 2.05                         <
>                                                                      <
>             PICos18 - Real-time kernel for PIC18 family              <
>                                                                      <
>                                                                      <
> www.picos18.com                                    www.pragmatec.net <
>______________________________________________________________________<


This file contains all necessary informations to use properly the 
PIC18 CAN driver for PICos18 v2.xx. This driver let you design a
multi-task application using the same CAN port without being concerned 
by the CAN shared access. Then every task of your application can send
messages without being necessarily synchronised to the others.


 ______________________________________________________________________
>                                                                      <
>                         I - Zip file content                         <
>______________________________________________________________________<

The drv_can zip file contains :
- drv_can.c
- drv_can.h   : header file
- drv_can.txt : this file

To use the PICos18 CAN driver, first unzip the file.
Place the C and H file in your project directory.

This driver is supposed to be use with PICos18 and has been tested with 
MPLAB 7.00 and C18 v2.40. Do not use this driver at a frequency lower 
than 8 Mhz (use the PIC18 PLL to increase the internal frequency).

 ______________________________________________________________________
>                                                                      <
>                        II - Hardware settings                        <
>______________________________________________________________________<

The driver is able to run in loopback mode. It means you can run your 
application with this driver without necessarily being connected to a
real network.

To activate the loopback mode, add the following compiler option in the 
MPLAB C18 panel of the Build Options window :

__LOOPBACK__


The basic job of the driver is to filter the incoming message by software.
If a task is waiting for a certain CAN ID, the CAN driver is in charge of
waking the waiting task as soon as the expected message arrives.

To disable this feature and so to force the driver to wake up ALL the task
of your application each time a new message arrives, add the following
option in the MPLAB C18 panel of the Build Options window :

__NOFILTER__


In a current usage, you don't have to activate these both options. For
instance the LOOPBACK mode could be use to test the hardware before 
starting the application and the NOFILTER option may be use to design 
a kind of software bus analyser.


Moreover you HAVE to specify if you want to use this driver in 11 bits 
or in 29 bits mode (length of the CAN ID field). 
To activate the standart mode (11 bits) add the following option in the 
MPLAB C18 panel of the Build Options window :

__SDT11BITS__

To activate the extended mode (29 bits) add the following option in the 
MPLAB C18 panel of the Build Options window :

__EXT29BITS__

If you forget to select any one of the modes, the compiler will exit
with an error message : "you should define 11 or 29 bits for CANID !"


Baudrate Settings:
------------------
This CAN driver has a predefined CAN baud rate. You just have to define
your oscillator frequency in MHz in the drv_can.c file :
#define	OSCILATOR_FREQ			40

Note : We have only define baud rate settings for 16, 20, 32 and 40 MHz

Finaly you have to define the appropriate baud rate as follow :
#define	DEFAULT_SPEED			0  //for 10	kbps
#define	DEFAULT_SPEED			1  //for 20	kbps
#define	DEFAULT_SPEED			2  //for 50	kbps
#define	DEFAULT_SPEED			3  //for 125kbps
#define	DEFAULT_SPEED			4  //for 250kbps
#define	DEFAULT_SPEED			5  //for 500kbps
#define	DEFAULT_SPEED			6  //for 800kbps
#define	DEFAULT_SPEED			7  //for 1000kbps


 ______________________________________________________________________
>                                                                      <
>                       III - TASCDESC settings (1)                    <
>______________________________________________________________________<

Update also the tascdesc.c file to take into account the new CAN driver 
in your application :

/**********************************************************************
 * ----------------------- TASK & STACK DEFINITION --------------------
 **********************************************************************/
DeclareTask(Example);
DeclareTask(CAN_Drv);
...

volatile unsigned char stack0[DEFAULT_STACK_SIZE];
volatile unsigned char stack_can[DEFAULT_STACK_SIZE];
...

 ______________________________________________________________________
>                                                                      <
>                        IV - TASCDESC settings (2)                    <
>______________________________________________________________________<

Finally add the task and alarm descriptor to the tascdesc.c file :

...
/**********************************************************************
 * ----------------------------- CAN task -----------------------------
 **********************************************************************/
rom_desc_tsk rom_desc_CAN_DRV = {
	DRV_CAN_PRIO,                  /* prioinit from 0 to 15       */
	stack_can,                     /* stack address (16 bits)     */
	CAN_Drv,                       /* start address (16 bits)     */
	READY,                         /* state at init phase         */
	CAN_DRV_ID,                    /* id_tsk from 0 to 15         */
	sizeof(stack_can)              /* ctx address   (16 bits)     */
};
...

To use the CAN we propose an EXAMPLE task that send some messages 
periodicaly. Because the task is a periodic one, we create an alarm :

AlarmObject Alarm_list[] = 
  {
   /*******************************************************************
    * ----------------------- Example task ----------------------------
    *******************************************************************/
   {
     OFF,                                  /* State                   */
     0,                                    /* AlarmValue              */
     0,                                    /* Cycle                   */
     &Counter_kernel,                      /* ptrCounter              */
     Example,                              /* TaskID2Activate         */
     ALARM_EVENT,                          /* EventToPost             */
     0                                     /* CallBack                */
   }
 };


 ______________________________________________________________________
>                                                                      <
>                         V - TASK Settings                            <
>______________________________________________________________________<
	
Open define.h and add these definitions with suitable values :
 
#define ALARM_EVENT          0x80

#define CAN_NEW_MSG          0x02
#define CAN_RCV_MSG          0x04
#define CAN_ERR_MSG          0x08

#define CAN_QUEUE_FULL       0x01
#define CAN_QUEUE_EMPTY      0x02

...
	
#define CAN_DRV_ID              6
#define DRV_CAN_PRIO            8

#define EXAMPLE_ID              4
#define EXAMPLE_PRIO            5

The CAN task is considered to be a driver, that means you have to give 
one of the highest priority to the CAN driver to let it run each time 
the CAN buffer is updated.

Adapt the values to your application is necessary (event values...).

 ______________________________________________________________________
>                                                                      <
>                        VI - ISR connection                           <
>______________________________________________________________________<
	
Open the file int.c and declare the external CAN ISR function :
 
  extern void AddOneTick(void);
  extern void CAN_INT(void);                     //   <= here
  void InterruptVector(void);

And complete the InterruptVector function :

void InterruptVectorL(void)
{
  EnterISR();

  if (INTCONbits.TMR0IF == 1)
    AddOneTick();
  if ((PIR3 & PIE3) != 0)
    CAN_INT();

  LeaveISR();
}

 ______________________________________________________________________
>                                                                      <
>                       VII - CAN driver usage (1)                     <
>______________________________________________________________________<

In the task, you have first to specify a SIDL and SIDH values as a CAN ID.
In this CAN driver release only the SIDH field is managed by the driver, 
then the CAN ID is 8 bits long only. Check the next release to be able
to manage 21 bits CAN ID field.


In the Example task, include the driver header:

#include "drv_can.h"

And declare a CAN message (type CAN_message_t):
CAN_ message_t CAN_msg; 

See hereafter a basic example to send a "Test: xx" message with a counter
value to a CAN network:


#include "define.h"
#include "drv_can.h"

 /* Replace by the correct value of your alarm ID */
#define  CAN_TASK_ALARM 0


/**********************************************************************
 * Variables shared with the rest of application.
 **********************************************************************/
CAN_message_t  SND1_message;
unsigned char  data1, data2;

/**********************************************************************
 * ------------------------- Internal test TASK -----------------------
 *
 * The task sends a CAN message every 3 secondes. 
 *
 **********************************************************************/
TASK(CAN_sender)
{
   SetRelAlarm(CAN_TASK_ALARM, 3000, 3000);  
 
   SND1_message.CANID   = 0x7AA; 
// SND1_message.CANID   = 0x1A55AA55; // In 29 bits mode only
   SND1_message.length  = 8;
   SND1_message.data[0] = 'T';
   SND1_message.data[1] = 'e';
   SND1_message.data[2] = 's';
   SND1_message.data[3] = 't';
   SND1_message.data[4] = ':';
   SND1_message.data[5] = ' ';
   SND1_message.data[6] = '0';
   SND1_message.data[7] = '0';

   data1 = 0x30;
   data2 = 0x30;
   
   while (1)
   {
     WaitEvent(ALARM_EVENT);
     ClearEvent(ALARM_EVENT);

     data2++;
     if (data2 == 0x3A)
     {
       data2 = 0x30;
       data1++;
       if (data1 == 0x3A)
         data1 = 0x30;
     }

     SND1_message.data[6] = data1;
     SND1_message.data[7] = data2;
     
     CAN_enqMsg(&SND1_message);
     SetEvent(CAN_DRV_ID, CAN_NEW_MSG);

     /* Optionnal : we don't need to wait for end of transmission */
     WaitEvent(CAN_QUEUE_EMPTY);
     ClearEvent(CAN_QUEUE_EMPTY);
   }
}


 ______________________________________________________________________
>                                                                      <
>                      VIII - CAN driver usage (2)                     <
>______________________________________________________________________<

In your application you can have one or more task waiting for a certain
can message (specifyed by a certai CAN ID).


In the Example task, include the driver header:

#include "drv_can.h"

And declare a CAN message (type CAN_message_t):
CAN_ message_t CAN_msg; 

See hereafter a basic example to wait for a message with a specific 
CAN ID value :


#include "define.h"
#include "drv_can.h"

 /* Replace by the correct value of your alarm ID */
#define  CAN_TASK_ALARM 0


/**********************************************************************
 * Variables shared with the rest of application.
 **********************************************************************/
CAN_message_t  RCV_message;
unsigned char data1, data2, length;

/**********************************************************************
 * ------------------------- Internal test TASK -----------------------
 *
 * The task wait for the CAN message with 64 as SIDH CAN ID. 
 *
 **********************************************************************/
TASK(CAN_reciever)
{  
  unsigned char i; 
  RCV_message.CANID   = 0x7AA;
//RCV_message.CANID   = 0x1A55AA55; // In 29 bits mode only
  CAN_RCV_Register(&RCV_message);  
    
  while(1)
  {
    WaitEvent(CAN_QUEUE_FULL);
    ClearEvent(CAN_QUEUE_FULL); 

    length = RCV_message.length;
    data1  = RCV_message.data[length-2];
    data2  = RCV_message.data[length-1];

    CAN_freeMsg(RCV_message);
    SetEvent(CAN_DRV_ID, CAN_RCV_MSG);
  }
}

 ______________________________________________________________________
>                                                                      <
>                        IX - Conclusion                               <
>______________________________________________________________________<

With a such example here is what you should see on the CAN network :

 ID   64    :  <Test: 01>
 ID   64    :  <Test: 02>
 ID   64    :  <Test: 03>
 ID   64    :  <Test: 04>


The code has been tested on the PIC18F458, PIC18F258 and PIC18F4680 without
any trouble.

This CAN driver is provided from the PICos18 web site with other drivers
dedicated to oher peripherals. Some zip files are also provided to be 
used with a driver. Error are taken into account by the CAN driver
but not yet report in a structured log file.

Do not hesitate to check periodicaly the www.picos18.com web site in order
to download the last versions of PIC18 drivers for PICos18.



/* End of File : drv_can.txt */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -