Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
03/27/08 00:39
Read: times


 
#152591 - CAN application for SILABS F040
Helo there,
Could anyone help me with "C" code for C8051F040 ? Program should receive two diferent messages from CAN bus in automobile. Messages are ordinary automobile data (speed and velocity) which are regularly sent to bus from engine unit. I Thing, bit timing is set correctly, and message objects in CANcore seems to be set correctly too, but MCU never falls down to interrupt from CAN source ... global interrupt and interrupt from CANcore is enabled, so I don't understand why I can't receive any data.

my code is like:



Sorry about the code, but if you copy and paste to any IDE it will seems much better ;) Thank you !

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

#include <C8051F040.H> 

/*type definition */
typedef unsigned char UCHAR;   
typedef unsigned short USHORT;
typedef unsigned int UINT;
typedef unsigned long ULONG;

/* funktion prototypes  */
void CanInit(void); //inicializace CAN modulu
void CanSetMsgRx(UCHAR cislo,USHORT id,UCHAR dlc); //nastaveni projimaciho objektu zprav
void CanSetMsgTx(UCHAR cislo,USHORT id,UCHAR dlc); //nastaveni vysilaciho objektu zprav
void CanTransmit(void);  //vyslani zpravy
void Port_Init (void);
void Oscilator_INIT (void);

/* index CAN registr (index in CAN0ADR)  */
#define CanControlRegistr 		0x00  // CAN0CN
#define CanStatusRegistr   		0x01  // CAN0STA
#define CanErrorCount      		0x02  // RP,REC,TEC
#define CanBitTimingRegistr     0x03  // Timing
#define CanInterruptRegistr		0x04  // interrupt identificator
#define CanTestRegistr      	0x05  // CAN0TST
#define CanExtensionBRP			0x06  // BRP Extension to 10 bits
#define CanIF1CommandRequest    0x08  // number of object
#define CanIF1CommandMask       0x09  // 
#define CanIF1LowerMask    		0x0A  // filter mask,lower bits
#define CanIF1UpperMask    		0x0B  // filter mask,higher bits
#define CanIF1LowerArbitration  0x0C  // ID, lower bits
#define CanIF1UpperArbitration  0x0D  // ID, higher bits
#define CanIF1MessageControl    0x0E  // 
#define CanIF1DataA1	    	0x0F  // data - 1 - 2 byte
#define CanIF1DataA2	    	0x10  // data - 3 - 4 byte
#define CanIF1DataB1	    	0x11  // data - 5 - 6 byte
#define CanIF1DataB2	    	0x12  // data - 7 - 8 byte
#define CanIF2CommandRequest    0x20  // Number of object
#define CanIF2CommandMask       0x21  // 
#define CanIF2LowerMask    		0x22  // filter mask,lower bits
#define CanIF2UpperMask    		0x23  // filter mask,higher bits
#define CanIF2LowerArbitration  0x24  // ID, lower bits
#define CanIF2UpperArbitration  0x25  // ID, higher bits
#define CanIF2MessageControl    0x26  // 
#define CanIF2DataA1	    	0x27  // data - 1. and 2. byte
#define CanIF2DataA2	    	0x28  // data - 3. and 4. byte
#define CanIF2DataB1	    	0x29  // data - 5. and 6. byte
#define CanIF2DataB2	    	0x2A  // data - 7. and 8. byte
#define CanTransmissionRequest1 0x40  // TRQX 1 - 16
#define CanTransmissionRequest2 0x41  // TRQX 17 - 32
#define CanNewDat1  	 		0x48  // NEWDAT 1 - 16
#define CanNewDat2  	 		0x49  // NEWDAT 17 - 32
#define CanInterruptPending1  	0x50  // INTPND 1 - 16
#define CanInterruptPending2  	0x51  // INTPND 17 - 32
#define CanMessageValid1  		0x58  // MSGVAL 1 - 16
#define CanMessageValid2  		0x59  // MSGVAL 17 - 32

/* macros for writing to CAN's registrs */
#define CanWrReg(hb,lb)  CAN0DATH=(hb); CAN0DATL=(lb);  //zapis 2 bytu dat na adr. v CAN0ADR
#define CanWrAdr(index,datah,datal) CAN0ADR=index; CanWrReg((datah),(datal)) //zapis 2 bytu dat na zadanou adresu
#define CanWrL(index,data8) CAN0ADR=index; CAN0DATL=(data8);         // zapis 1 bytu dat na zadanou adresu

/* bits CAN Control - CAN0CN*/
#define INITC 0x01
#define IEC   0x02
#define SIEC  0x04
#define EIEC  0x08
#define IFC   0x10
#define DARC  0x20
#define CCEC  0x40
#define TESTC 0x80

/* bits IF Arbitration */
#define FOR_RX 			0x00
#define FOR_TX 			0x20
#define STANDARD_FRAME	0x00
#define EXTENDED_FRAME	0x40
#define CLR_MSGVAL 		0x00
#define MSGVAL 			0x80

/* bits IF Mask  */
#define CLR_MDIR 		0x00
#define MDIR 			0x40
#define CLR_MXTD 		0x00
#define MXTD 			0x80

/* bits IF Control,config */
#define EOB 	0x80
#define TXRQST 	0x01
#define RMTEN 	0x02
#define RXIE 	0x04
#define TXIE 	0x08
#define UMASK 	0x10
#define INTPND 	0x20
#define MSGLST 	0x40
#define NEWDAT 	0x80

/* bits IF Commad Mask  */
#define CDATAB 	0x01
#define CDATAA 	0x02
#define CNEWDAT 0x04
#define CTXRQST 0x04
#define CINTPND 0x08
#define CONTROL 0x10
#define CARB 	0x20
#define CMASK 	0x40
#define CWR 	0x80
#define CRD 	0x0
  
/*global variables*/
UCHAR id;
USHORT h;

/* IDs and DLCs */
#define ID_SPEED 0x280		// ID for velocity	
#define ID_SPIN 0x320		// ID for speed
#define DLC_SPEED 8			// DLC for Velocity
#define DLC_SPIN 8			// DLC for Speed


/*------------------------------------------------------ 
       MAIN 
------------------------------------------------------*/ 
void main (void) 
{
  WDTCN = 0xde;
  WDTCN = 0xad;						// Watchdog off
  
  Port_Init ();						// port Init
  Oscilator_INIT ();				// oscilator init
  CanInit ();
  while (1)
  {
  }
}

/*------------------------------------------------------ 
       Initialize CAN 
------------------------------------------------------*/ 
void CanInit(void)  
{
    unsigned char i;    
    SFRPAGE=CAN0_PAGE;
    CAN0CN=CCEC|INITC;								// for setup BTR
    CAN0STA=0;
    CanWrAdr(CanBitTimingRegistr, 0x7D,0xC0)   		// SETUP of BitTimmingRegistr 
    CanWrL (CanIF1CommandMask,0xFF)
    CanWrAdr(CanIF1UpperArbitration,CLR_MSGVAL,0)
    for(i=1;i<33;i++)
    	{
    	CanWrL (CanIF1CommandRequest,i)	            	// reset of all MSGVALs (unused)
   	 	}
    CanSetMsgRx(1,ID_SPEED,DLC_SPEED);					// nastaveni objektu 1: rychlost
    CanSetMsgRx(2,ID_SPIN,DLC_SPIN);					// nastaveni objektu 2: otacky

    CanWrL (CanIF1CommandMask,CONTROL|CINTPND|CNEWDAT|CDATAA|CDATAB)  // mask for receive objects

    CAN0CN=IEC;										// Interrupt in CAN core enabled
    EIE2=0x20;										// Interrupt in MCU from CAN core enabled
	EA = 1;											// Global interrupt enabled
}

/*------------------------------------------------------ 
       SETUP receive object 
------------------------------------------------------*/ 

void CanSetMsgRx(unsigned char cislo,USHORT id,unsigned char dlc)
{
    CanWrL (CanIF1CommandMask,CWR|CMASK|CARB|CONTROL)  // write, mask, ID, control
	//autoincrement CANOADR
	CanWrReg(0xFF,0xFF);                               // lower mask
	//autoincrement CANOADR
	CanWrReg(0xFF,0xFF);                               // higher maska
	//autoincrement CANOADR
	CanWrReg(0,0);                                     // lower ID
	//autoincrement CANOADR
    CanWrReg(MSGVAL|FOR_RX|(unsigned char)(id>>8),(unsigned char)(id))	// MSGVAL,receive,higher ID 
	//autoincrement 
    CanWrReg(RXIE,EOB|dlc)
	//autoincrement	                           // control: povoleni preruseni, delka
    CanWrL (CanIF1CommandRequest,cislo)				   // write to RAM object
}

/*------------------------------------------------------ 
       ISR for CAN core 
------------------------------------------------------*/ 

void CanInterrupt(void) interrupt 19
{
 SFRPAGE  = CAN0_PAGE; 
 while(1)				
 {
   CAN0ADR= CanInterruptPending1;		// indication of source of interrupt
   id = CAN0DATL;
   if(id==0) break;						// bRake if no request
   if(id & 1)
   {									// object 1: velocity
     CanWrL(CanIF2CommandRequest, 1)	// data from RAM to IF registru
     CAN0ADR= CanIF2DataB1;				// value of velocity  is on 4th and 5th byte
     h=CAN0DATH>>1;						// bits 15 - 1 
     CAN0ADR= CanIF2DataA2;
     h|=(CAN0DATL<<7);
   }
   if(id & 2)
   {// object 2: engine speed
     CanWrL(CanIF2CommandRequest,2)// data from RAM to IF registr
     CAN0ADR= CanIF2DataA2;// value of speed is on 3rd and 4th byte
     h=(CAN0DATH<<8);	// new value: bits 15 - 0
     h+=CAN0DATL;    
    }
 }

}

/*---------------------------------------------------------
Init procedures
----------------------------------------------------------*/
void Oscilator_INIT (void)
{
  int n;                        // local variable used in delay FOR loop.
  SFRPAGE = CONFIG_PAGE;        // switch to config page to config oscillator
  OSCXCN  = 0x77;               // ext. osc - 22.1 MHz Crystal
                                // system clock is 11.05 MHz
  for (n=0;n<3000;n++);         // delay about 1ms
  while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize
  CLKSEL |= 0x01;               // switch to external oscillator
}

void Port_Init (void)
{
  SFRPAGE  = CONFIG_PAGE;        
  XBR3     = 0x80;     			 // CAN TX - push-pull 
  P1MDOUT |= 0x40;     			 // P1.6 - push-pull (LED)
  XBR2     = 0x40;     			 // Enable Crossbar/low ports
}
=================================================================


List of 2 messages in thread
TopicAuthorDate
CAN application for SILABS F040            01/01/70 00:00      
   http://www.8052.com/forum/read.phtml?id=149409            01/01/70 00:00      

Back to Subject List