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

📄 can_self.lst

📁 CAN节点的自通信程序
💻 LST
📖 第 1 页 / 共 2 页
字号:
C51 COMPILER V6.12  CAN_SELF                                                               06/20/2008 08:56:27 PAGE 1   


C51 COMPILER V6.12, COMPILATION OF MODULE CAN_SELF
OBJECT MODULE PLACED IN .\can_self.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE .\can_self.c DEBUG OBJECTEXTEND

stmt level    source

   1          /**************************************************************************************
   2          项	目:基于CAN总线的自收发通信
   3          说	明:主程序部分
   4          功  能:外部按键每按下一次,计数值加一,同时计数值在数码管1、2上显示。
   5          		在计数值加一后,会使CAN总线上重新发送数据,此时接收端的计数值也同步更新显示
   6          		在数码管3、4上(为便于观察,接收显示的值比发送值大3)。
   7          //      CAN主要参数:       PeliCAN模式,扩展帧EFF模式                         
   8          //      29位标示码结构:                                                      
   9          //      发送数据结构:计数结果,0x02,0x03,0x04,0x05,0x06,0x07,0x08              
  10          //      接收数据结构: 待显示数据+其它7个字节的数据                             
  11          //      本节点的接收代码寄存器值: 0x11,0x22,0x33,0x44
  12          //		本节点的屏蔽代码寄存器值:0x00,0x00,0x00,0x00;可以接收本节点的数据               
  13          //      目的节点地址:0x11,0x22,0x33,0x44;可以被本节点接收  
  14          模	块:can_self.c
  15          作	者:特	权
  16          时	间:08.6.17.
  17          修  改:08.6.19.
  18          **************************************************************************************/
  19          /***感谢PIAE工作组提供的源码,这里特权根据自己的编程习惯做了一些修改并添加详细注释***/
  20          
  21          #include <reg52.h>
  22          #include <intrins.h>
  23          #include "define.h"
  24          
  25          ///////////////////////////////////////////////
  26          //函数:inter0_key  (外部中断INT0)
  27          //说明:INT0按键为计数按键
  28          //		每按下一次键,计数值加一
  29          //入口:按键中断
  30          //返回:按键加一
  31          ///////////////////////////////////////////////
  32          void inter0_key(void) interrupt 0
  33          {
  34   1          EA = 0;		//关闭中断
  35   1          Txd_data++;		//计数结果增1,即待发送的数据增1
  36   1          TXD_flag = 1;	//发送数据标志位置位,即重新发送数据以更新数码管的显示数值
  37   1          EA = 1;		//重新开启中断
  38   1      }
  39          
  40          ///////////////////////////////////////////////
  41          //函数:inter1_can_rxd  (外部中断INT1)
  42          //说明:接收数据函数,在中断服务程序中调用
  43          //入口:无
  44          //返回:无
  45          ///////////////////////////////////////////////
  46          void inter1_can_rxd( void ) interrupt 2
  47          {
  48   1          uchar state;
  49   1      
  50   1          EA = 0;		//关CPU中断
  51   1          IE1 = 0;	//由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零
  52   1      
  53   1          state = IR;	//IR为SJA1000的中断寄存器
  54   1          if( state & 0x01)	//若IR.0=1--接收中断
  55   1          {	//接收数据帧
C51 COMPILER V6.12  CAN_SELF                                                               06/20/2008 08:56:27 PAGE 2   

  56   2              RX_buffer[0] =  RBSR;
  57   2              RX_buffer[1] =  RBSR1;
  58   2              RX_buffer[2] =  RBSR2;
  59   2              RX_buffer[3] =  RBSR3;
  60   2              RX_buffer[4] =  RBSR4;
  61   2              RX_buffer[5] =  RBSR5;
  62   2              RX_buffer[6] =  RBSR6;
  63   2              RX_buffer[7] =  RBSR7;
  64   2              RX_buffer[8] =  RBSR8;
  65   2              RX_buffer[9] =  RBSR9;
  66   2              RX_buffer[10] =  RBSR10;
  67   2              RX_buffer[11] =  RBSR11;
  68   2              RX_buffer[12] =  RBSR12;
  69   2              RXD_flag = 1;	//接收标志置位,以便进入接收处理程序
  70   2              CMR = 0X04;		//CMR.2=1--接收完毕,释放接收缓冲器
  71   2              state = ALC;	//释放仲裁随时捕捉寄存器(读该寄存器即可)
  72   2              state = ECC;	//释放错误代码捕捉寄存器(读该寄存器即可)
  73   2          }
  74   1      
  75   1          IER = 0x01;		// IER.0=1--接收中断使能
  76   1          EA = 1;			//重新开启CPU中断
  77   1      }
  78          
  79          ///////////////////////////////////////////////
  80          //函数:main
  81          //说明:主函数
  82          //入口:无
  83          //返回:无
  84          ///////////////////////////////////////////////
  85          void main(void)
  86          {
  87   1      	init_mcu();
  88   1      	init_sja1000();
  89   1      	while(1)
  90   1      	{
  91   2              rxd_deal();		//接收处理程序
  92   2              txd_deal();		//发送处理程序
  93   2              led_show(0,Txd_data);	//数码管1-2显示发送数据子程序
  94   2              led_show(1,Rxd_data+3);	//数码管3-4显示接收数据子程序		
  95   2      	}	
  96   1      }
  97          
  98          ///////////////////////////////////////////////
  99          //函数:init_mcu
 100          //说明:单片机I/O口初始化
 101          //		主要是各中断寄存器的初始化
 102          //入口:无
 103          //返回:无
 104          ///////////////////////////////////////////////
 105          void init_mcu(void)
 106          {
 107   1          SJA_RST = 1;	//CAN总线复位管脚复位无效
 108   1          SJA_CS = 0;		//CAN总线片选有效
 109   1          EX1 = 1;	//开MCU外部中断INT1
 110   1          IT1 = 0;	//MCU外部中断INT1设置为电平触发,该中断口连接CAN总线接收中断口
 111   1          IT0 = 1;	//MCU外部中断INT0设置为下降沿触发
 112   1          EX0 = 1;	//开MCU外部中断INT0
 113   1          EA = 1; 	//开MCU总中断
 114   1          SJA_CS = 1;		//CAN总线片选无效,使得对数据总线的操作不会影响SJA1000。	
 115   1      }
 116          
 117          ///////////////////////////////////////////////
C51 COMPILER V6.12  CAN_SELF                                                               06/20/2008 08:56:27 PAGE 3   

 118          //函数:init_sja1000
 119          //说明:独立CAN控制器SJA1000的初始化
 120          //入口:无
 121          //返回:无
 122          ///////////////////////////////////////////////
 123          void init_sja1000(void)
 124          {
 125   1          uchar state;
 126   1          uchar ACRR[4];
 127   1          uchar AMRR[4];
 128   1      
 129   1      // 接收代码寄存器
 130   1          ACRR[0] = 0x11;
 131   1          ACRR[1] = 0x22;
 132   1          ACRR[2] = 0x33;
 133   1          ACRR[3] = 0x44;	
 134   1      
 135   1      // 接收屏蔽寄存器,只接收主机发送的信息
 136   1          AMRR[0] = 0x00;
 137   1          AMRR[1] = 0X00;
 138   1          AMRR[2] = 0x00;
 139   1          AMRR[3] = 0x00;	
 140   1      
 141   1      // 使用do--while语句确保进入复位模式
 142   1          do
 143   1          {
 144   2              MODR  = 0x09;	// 设置MOD.0=1--进入复位模式,以便设置相应的寄存器
 145   2      		state = MODR;	
 146   2          }
 147   1          while( !(state & 0x01) );
 148   1      
 149   1      // 对SJA1000部分寄存器进行初始化设置
 150   1          CDR  = 0x88;	// CDR为时钟分频器,CDR.3=1--时钟关闭, CDR.7=0---basic CAN, CDR.7=1---Peli CAN
 151   1          BTR0 = 0x31;	// 总线定时寄存器0 ;总线波特率设定
 152   1          BTR1 = 0x1c;	// 总线定时寄存器1 ;总线波特率设定
 153   1          IER  = 0x01;	// IER.0=1--接收中断使能;  IER.1=0--关闭发送中断使能
 154   1          OCR  = 0xaa;	// 配置输出控制寄存器
 155   1          CMR  = 0x04;	// 释放接收缓冲器
 156   1      
 157   1      // 初始化接收代码寄存器
 158   1          ACR0 = ACRR[0];
 159   1          ACR1 = ACRR[1];
 160   1          ACR2 = ACRR[2];
 161   1          ACR3 = ACRR[3]; 
 162   1      
 163   1      // 初始化接收屏蔽寄存器
 164   1          AMR0 = AMRR[0];
 165   1          AMR1 = AMRR[1];
 166   1          AMR2 = AMRR[2];
 167   1          AMR3 = AMRR[3]; 
 168   1      
 169   1      // 使用do--while语句确保进入自接收模式
 170   1          do
 171   1          {
 172   2      		MODR   = 0x04;	//MOD.2=1--进入自接收模式,MOD.3=0--双滤波器模式
 173   2      		state  = MODR;
 174   2           }
 175   1          while( !(state & 0x04) );
 176   1      }

⌨️ 快捷键说明

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