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

📄 can2.lst

📁 本文件是CAN总线通讯演示程序;将CAN_TEST下的CAN1
💻 LST
📖 第 1 页 / 共 2 页
字号:
 210          void external_osc (void)
 211          {
 212   1        int n;                        // local variable used in delay FOR loop.
 213   1        SFRPAGE = CONFIG_PAGE;        // switch to config page to config oscillator
 214   1        OSCXCN  = 0x77;               // start external oscillator; 22.1 MHz Crystal
 215   1                                      // system clock is 22.1 MHz / 2 = 11.05 MHz
 216   1        for (n=0;n<255;n++);          // delay about 1ms
 217   1        while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize
 218   1        CLKSEL |= 0x01;               // switch to external oscillator
 219   1      }
 220          
 221          void config_IO (void)
 222          {
 223   1        SFRPAGE  = CONFIG_PAGE;        //Port SFR's on Configuration page
 224   1        XBR3     = 0x80;     // Configure CAN TX pin (CTX) as push-pull digital output
 225   1      
 226   1        P5MDOUT |= 0x10;   // Configure P5.4 as push-pull to drive LED
 227   1      
 228   1        XBR2     = 0x40;     // Enable Crossbar/low ports
 229   1      }
 230          
 231          ////////////////////////////////////////////////////////////////////////////////
 232          //CAN Functions
 233          ////////////////////////////////////////////////////////////////////////////////
 234          
 235          
 236          //Clear Message Objects
 237          void clear_msg_objects (void)
 238          {
 239   1        SFRPAGE  = CAN0_PAGE;
 240   1        CAN0ADR  = IF1CMDMSK;    // Point to Command Mask Register 1
 241   1        CAN0DATL = 0xFF;         // Set direction to WRITE all IF registers to Msg Obj
C51 COMPILER V7.02b   CAN2                                                                 01/20/2006 11:20:24 PAGE 5   

 242   1        for (i=1;i<33;i++)
 243   1          {
 244   2            CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
 245   2            CAN0DATL = i;
 246   2          }
 247   1      }
 248          
 249          //Initialize Message Object for RX
 250          void init_msg_object_RX (char MsgNum)
 251          {
 252   1        SFRPAGE  = CAN0_PAGE;
 253   1        CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
 254   1        CAN0DAT  = 0x00B8;     // Set to WRITE, and alter all Msg Obj except ID MASK
 255   1                               // and data bits
 256   1        CAN0ADR  = IF1ARB1;    // Point to arbitration1 register
 257   1        CAN0DAT  = 0x0000;     // Set arbitration1 ID to "0"
 258   1        CAN0DAT  = 0x8000;     // Arb2 high byte:Set MsgVal bit, no extended ID,
 259   1                               // Dir = RECEIVE
 260   1        CAN0DAT  = 0x0480;     // Msg Cntrl: set RXIE, remote frame function disabled
 261   1        CAN0ADR  = IF1CMDRQST; // Point to Command Request reg.
 262   1        CAN0DATL = MsgNum;     // Select Msg Obj passed into function parameter list
 263   1                               // --initiates write to Msg Obj
 264   1        // 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM
 265   1      }
 266          
 267          //Initialize Message Object for TX
 268          void init_msg_object_TX (char MsgNum)
 269          {
 270   1        SFRPAGE = CAN0_PAGE;
 271   1        CAN0ADR = IF1CMDMSK;  // Point to Command Mask 1
 272   1        CAN0DAT = 0x00B2;     // Set to WRITE, & alter all Msg Obj except ID MASK bits
 273   1        CAN0ADR = IF1ARB1;    // Point to arbitration1 register
 274   1        CAN0DAT = 0x0000;     // Set arbitration1 ID to highest priority
 275   1        CAN0DAT = 0xA004;     // Autoincrement to Arb2 high byte:
 276   1                              // Set MsgVal bit, no extended ID, Dir = WRITE
 277   1        CAN0DAT = 0x0081;     // Msg Cntrl: DLC = 1, remote frame function not enabled
 278   1        CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
 279   1        CAN0DAT = MsgNum;     // Select Msg Obj passed into function parameter list
 280   1                              // --initiates write to Msg Obj
 281   1        // 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
 282   1      }
 283          
 284          //Start CAN
 285          void start_CAN (void)
 286          {
 287   1        /* Calculation of the CAN bit timing :
 288   1      
 289   1        System clock        f_sys = 22.1184 MHz/2 = 11.0592 MHz.
 290   1        System clock period t_sys = 1/f_sys = 90.422454 ns.
 291   1        CAN time quantum       tq = t_sys (at BRP = 0)
 292   1      
 293   1        Desired bit rate is 1 MBit/s, desired bit time is 1000 ns.
 294   1        Actual bit time = 11 tq = 996.65ns ~ 1000 ns
 295   1        Actual bit rate is 1.005381818 MBit/s = Desired bit rate+0.5381%
 296   1      
 297   1        CAN bus length = 10 m, with 5 ns/m signal delay time.
 298   1        Propagation delay time : 2*(transceiver loop delay + bus line delay) = 400 ns
 299   1        (maximum loop delay between CAN nodes)
 300   1      
 301   1        Prop_Seg = 5 tq = 452 ns ( >= 400 ns).
 302   1        Sync_Seg = 1 tq
 303   1      
C51 COMPILER V7.02b   CAN2                                                                 01/20/2006 11:20:24 PAGE 6   

 304   1        Phase_seg1 + Phase_Seg2 = (11-6) tq = 5 tq
 305   1        Phase_seg1 <= Phase_Seg2,  =>  Phase_seg1 = 2 tq and Phase_Seg2 = 3 tq
 306   1        SJW = (min(Phase_Seg1, 4) tq = 2 tq
 307   1      
 308   1        TSEG1 = (Prop_Seg + Phase_Seg1 - 1) = 6
 309   1        TSEG2 = (Phase_Seg2 - 1)            = 2
 310   1        SJW_p = (SJW - 1)                   = 1
 311   1      
 312   1        Bit Timing Register = BRP + SJW_p*0x0040 = TSEG1*0x0100 + TSEG2*0x1000 = 2640
 313   1      
 314   1        Clock tolerance df :
 315   1      
 316   1        A: df < min(Phase_Seg1, Phase_Seg2) / (2 * (13*bit_time - Phase_Seg2))
 317   1        B: df < SJW / (20 * bit_time)
 318   1      
 319   1        A: df < 2/(2*(13*11-3)) = 1/(141-3) = 1/138 = 0.7246%
 320   1        B: df < 2/(20*11)                   = 1/110 = 0.9091%
 321   1      
 322   1        Actual clock tolerance is 0.7246% - 0.5381% = 0.1865% (no problem for quartz)
 323   1        */
 324   1      
 325   1        SFRPAGE  = CAN0_PAGE;
 326   1        CAN0CN  |= 0x41;       // Configuration Change Enable CCE and INIT
 327   1        CAN0ADR  = BITREG   ;  // Point to Bit Timing register
 328   1        CAN0DAT  = 0x2640;     // see above
 329   1      
 330   1        CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
 331   1        CAN0DAT  = 0x0087;     // Config for TX : WRITE to CAN RAM, write data bytes,
 332   1                               // set TXrqst/NewDat, clr IntPnd
 333   1      
 334   1        // RX-IF2 operation may interrupt TX-IF1 operation
 335   1        CAN0ADR  = IF2CMDMSK;  // Point to Command Mask 2
 336   1        CAN0DATL = 0x1F;       // Config for RX : READ CAN RAM, read data bytes,
 337   1                               // clr NewDat and IntPnd
 338   1        CAN0CN  |= 0x06;       // Global Int. Enable IE and SIE
 339   1        CAN0CN  &= ~0x41;      // Clear CCE and INIT bits, starts CAN state machine
 340   1      }
 341          
 342          //Transmit CAN frame to turn other node's LED ON
 343          void transmit_turn_LED_ON (char MsgNum)
 344          {
 345   1        SFRPAGE  = CAN0_PAGE;  // IF1 already set up for TX
 346   1        CAN0ADR  = IF1CMDMSK;  // Point to Command Mask 1
 347   1        CAN0DAT  = 0x0087;     // Config to WRITE to CAN RAM, write data bytes,
 348   1                               // set TXrqst/NewDat, Clr IntPnd
 349   1        CAN0ADR  = IF1DATA1;   // Point to 1st byte of Data Field
 350   1        CAN0DATL = 0x11;       // Ones signals to turn LED's light ON in data A1 field
 351   1        CAN0ADR  = IF1CMDRQST; // Point to Command Request Reg.
 352   1        CAN0DATL = MsgNum;     // Move new data for TX to Msg Obj "MsgNum"
 353   1      }
 354          
 355          //Transmit CAN Frame to turn other node's LED OFF
 356          void transmit_turn_LED_OFF (char MsgNum)
 357          {
 358   1        SFRPAGE  = CAN0_PAGE;  // IF1 already set up for TX
 359   1        CAN0ADR  = IF1DATA1;   // Point to 1st byte of Data Field
 360   1        CAN0DATL = 0x00;       // Zero signals to turn LED's light ON in Data A1 field
 361   1        CAN0ADR  = IF1CMDRQST; // Point to Command Request Reg.
 362   1        CAN0DATL = MsgNum;     // Move new data for TX to Msg Obj "MsgNum"
 363   1      }
 364          
 365          
C51 COMPILER V7.02b   CAN2                                                                 01/20/2006 11:20:24 PAGE 7   

 366          // Receive Data from the IF2 buffer
 367          void receive_data (char MsgNum)
 368          {
 369   1        char virtual_button;
 370   1        char SFRPAGE_SAVE = SFRPAGE;        // Save SFRPAGE
 371   1        SFRPAGE  = CAN0_PAGE; // IF1 already set up for RX
 372   1        CAN0ADR  = IF2CMDRQST;// Point to Command Request Reg.
 373   1        CAN0DATL = MsgNum;    // Move new data for RX from Msg Obj "MsgNum"
 374   1                              // Move new data to a
 375   1        CAN0ADR  = IF2DATA1;  // Point to 1st byte of Data Field
 376   1      
 377   1        virtual_button = CAN0DATL;
 378   1        SFRPAGE = CONFIG_PAGE;
 379   1        if (virtual_button == 0x11)   //Ones is signal from other node to turn LED ON
 380   1          LED_1;
 381   1        else
 382   1          LED_0;                     //Otherwise turn LED OFF (message was one's)
 383   1        SFRPAGE = SFRPAGE_SAVE;
 384   1      }
 385          
 386          ////////////////////////////////////////////////////////////////////////////////
 387          //Interrupt Service Routine
 388          ////////////////////////////////////////////////////////////////////////////////
 389          void ISRname (void) interrupt 19
 390          {
 391   1        char SFRPAGE_SAVE = SFRPAGE;        // Save SFRPAGE
 392   1        SFRPAGE  = CAN0_PAGE;
 393   1      
 394   1        status = CAN0STA;
 395   1        if ((status&0x10) != 0)
 396   1          {                            // RxOk is set, interrupt caused by reception
 397   2            CAN0STA = (CAN0STA&0xEF)|0x07;         // Reset RxOk, set LEC to NoChange
 398   2            /* read message number from CAN INTREG */
 399   2            receive_data (0x01);             // Up to now, we have only one RX message
 400   2          }
 401   1        if ((status&0x08) != 0)
 402   1          {                            // TxOk is set, interrupt caused by transmision
 403   2            CAN0STA = (CAN0STA&0xF7)|0x07;        // Reset TxOk, set LEC to NoChange
 404   2          }
 405   1        if (((status&0x07) != 0)&&((status&0x07) != 7))
 406   1          {                           // Error interrupt, LEC changed
 407   2            /* error handling ? */
 408   2            CAN0STA = CAN0STA|0x07;              // Set LEC to NoChange
 409   2          }
 410   1        SFRPAGE = SFRPAGE_SAVE;
 411   1      }
 412          


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    450    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =     38       1
   IDATA SIZE       =   ----    ----
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

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