??? 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 |