| ??? 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
}
================================================================= |
| Topic | Author | Date |
| CAN application for SILABS F040 | 01/01/70 00:00 | |
http://www.8052.com/forum/read.phtml?id=149409 | 01/01/70 00:00 |



