找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2513|回复: 1
打印 上一主题 下一主题
收起左侧

CAN总线点对点带滤波的单片机例程源码

[复制链接]
跳转到指定楼层
楼主
ID:307221 发表于 2018-4-13 11:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CAN总线学习资料
A板按键发送一个字节:SJA1000 125kbps
B板接收显示一个字节:SJA1000 125Kbps

CAN点对点带滤波的单片机源程序如下:
  1. #include  "stdio.h"
  2. #include  "string.h"
  3. #include  "intrins.h"
  4. #include  "Function.h"
  5. #include  "reg51.h"
  6. void CAN_Send_anylength(unsigned char *CAN_TX_Buf,unsigned char length1);
  7. void display(unsigned char num);
  8. //定义SJA1000的基址
  9. //#define SJA_BaseAdr  0X7F00
  10. #define SJA_BaseAdr  0XFE00   //P2.0
  11. // 控制寄存器

  12. #define         REG_CONTROL       SJA_BaseAdr+0x00       //内部控制寄存器
  13. #define         REG_COMMAND       SJA_BaseAdr+0x01       //命令寄存器
  14. #define         REG_STATUS        SJA_BaseAdr+0x02       //状态寄存器
  15. #define         REG_INTERRUPT     SJA_BaseAdr+0x03       //中断寄存器
  16. #define         REG_INTENABLE     SJA_BaseAdr+0x04       //中断使能寄存器
  17. #define         REG_BTR0          SJA_BaseAdr+0x06       //总线定时寄存器0
  18. #define         REG_BTR1          SJA_BaseAdr+0x07       //总线定时寄存器1
  19. #define         REG_OCR           SJA_BaseAdr+0x08       //输出控制寄存器
  20. #define         REG_TEST          SJA_BaseAdr+0x09       //测试寄存器

  21. #define         REG_RESVER1       SJA_BaseAdr+0x0A       //保留1
  22. #define         REG_ARBITRATE     SJA_BaseAdr+0x0B       //仲裁丢失捕捉
  23. #define         REG_ERRCATCH      SJA_BaseAdr+0x0C       //错误代码捕捉
  24. #define         REG_ERRLIMIT      SJA_BaseAdr+0x0D       //错误报警限额

  25. #define         REG_RXERR         SJA_BaseAdr+0x0E         //接收错误计数器
  26. #define         REG_TXERR         SJA_BaseAdr+0x0F         //发送错误计数器

  27. #define         REG_ACR1          SJA_BaseAdr+0x10       //验收代码寄存器
  28. #define         REG_ACR2          SJA_BaseAdr+0x11       //验收代码寄存器
  29. #define         REG_ACR3          SJA_BaseAdr+0x12       //验收代码寄存器
  30. #define         REG_ACR4          SJA_BaseAdr+0x13       //验收代码寄存器
  31. #define         REG_AMR1          SJA_BaseAdr+0x14       //验收屏蔽寄存器
  32. #define         REG_AMR2          SJA_BaseAdr+0x15       //验收屏蔽寄存器
  33. #define         REG_AMR3          SJA_BaseAdr+0x16       //验收屏蔽寄存器
  34. #define         REG_AMR4          SJA_BaseAdr+0x17       //验收屏蔽寄存器

  35. // 发送缓冲区寄存器
  36. #define         REG_TXBuffer1     SJA_BaseAdr+0x10         //发送缓冲区1
  37. #define         REG_TXBuffer2     SJA_BaseAdr+0x11         //发送缓冲区2
  38. #define         REG_TXBuffer3     SJA_BaseAdr+0x12         //发送缓冲区3
  39. #define         REG_TXBuffer4     SJA_BaseAdr+0x13         //发送缓冲区4
  40. #define         REG_TXBuffer5     SJA_BaseAdr+0x14         //发送缓冲区5
  41. #define         REG_TXBuffer6     SJA_BaseAdr+0x15         //发送缓冲区6
  42. #define         REG_TXBuffer7     SJA_BaseAdr+0x16         //发送缓冲区7
  43. #define         REG_TXBuffer8     SJA_BaseAdr+0x17         //发送缓冲区8
  44. #define         REG_TXBuffer9     SJA_BaseAdr+0x18         //发送缓冲区9
  45. #define         REG_TXBuffer10    SJA_BaseAdr+0x19         //发送缓冲区10
  46. #define         REG_TXBuffer11    SJA_BaseAdr+0x1A         //发送缓冲区11
  47. #define         REG_TXBuffer12    SJA_BaseAdr+0x1B         //发送缓冲区12
  48. #define         REG_TXBuffer13    SJA_BaseAdr+0x1C         //发送缓冲区13

  49. // 接收缓冲区寄存器
  50. #define         REG_RXBuffer1       SJA_BaseAdr+0x10       //接收缓冲区1
  51. #define         REG_RXBuffer2       SJA_BaseAdr+0x11       //接收缓冲区2
  52. #define         REG_RXBuffer3      SJA_BaseAdr+0x12        //接收缓冲区3
  53. #define         REG_RXBuffer4       SJA_BaseAdr+0x13       //接收缓冲区4
  54. #define         REG_RXBuffer5      SJA_BaseAdr+0x14        //接收缓冲区5
  55. #define         REG_RXBuffer6     SJA_BaseAdr+0x15         //接收缓冲区6
  56. #define         REG_RXBuffer7     SJA_BaseAdr+0x16         //接收缓冲区7
  57. #define         REG_RXBuffer8     SJA_BaseAdr+0x17         //接收缓冲区8
  58. #define         REG_RXBuffer9     SJA_BaseAdr+0x18         //接收缓冲区9
  59. #define         REG_RXBuffer10     SJA_BaseAdr+0x19        //接收缓冲区10
  60. #define         REG_RXBuffer11     SJA_BaseAdr+0x1A        //接收缓冲区11
  61. #define         REG_RXBuffer12     SJA_BaseAdr+0x1B        //接收缓冲区12
  62. #define         REG_RXBuffer13     SJA_BaseAdr+0x1C        //接收缓冲区13

  63. #define         REG_RXCOUNT       SJA_BaseAdr+0x1D         //RX报文计数器
  64. #define         REG_RBSA          SJA_BaseAdr+0x1E         //接收缓冲区起始地址
  65. #define         REG_CDR           SJA_BaseAdr+0x1F         //时钟分频寄存器
  66. //功能说明:   CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为24MHZ*/
  67. #define         BTR0_Rate_10k      0xEF          //20KBPS的预设值
  68. #define         BTR1_Rate_10k      0xFF          //20KBPS的预设值

  69. /*
  70. 功能说明:   CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ*/

  71. #define         BTR0_Rate_20k      0x53          //20KBPS的预设值
  72. #define         BTR1_Rate_20k      0x2F          //20KBPS的预设值
  73. #define         BTR0_Rate_40k      0x87          //40KBPS的预设值
  74. #define         BTR1_Rate_40k      0xFF          //40KBPS的预设值
  75. #define         BTR0_Rate_50k      0x47          //50KBPS的预设值
  76. #define         BTR1_Rate_50k      0x2F          //50KBPS的预设值
  77. #define         BTR0_Rate_80k      0x83          //80KBPS的预设值
  78. #define         BTR1_Rate_80k      0xFF          //80KBPS的预设值
  79. #define         BTR0_Rate_100k     0x43          //100KBPS的预设值
  80. #define         BTR1_Rate_100k     0x2f          //100KBPS的预设值
  81. #define         BTR0_Rate_125k     0x03          //125KBPS的预设值
  82. #define         BTR1_Rate_125k     0x1c          //125KBPS的预设值
  83. #define         BTR0_Rate_200k     0x81          //200KBPS的预设值
  84. #define         BTR1_Rate_200k     0xFA          //200KBPS的预设值
  85. #define         BTR0_Rate_250k     0x01          //250KBPS的预设值
  86. #define         BTR1_Rate_250k     0x1c          //250KBPS的预设值
  87. #define         BTR0_Rate_400k     0x80          //400KBPS的预设值
  88. #define         BTR1_Rate_400k     0xfa          //400KBPS的预设值
  89. #define         BTR0_Rate_500k     0x00          //500KBPS的预设值
  90. #define         BTR1_Rate_500k     0x1c          //500KBPS的预设值
  91. #define         BTR0_Rate_666k     0x80          //666KBPS的预设值
  92. #define         BTR1_Rate_666k     0xb6          //666KBPS的预设值
  93. #define         BTR0_Rate_800k     0x00          //800KBPS的预设值
  94. #define         BTR1_Rate_800k     0x16          //800KBPS的预设值
  95. #define         BTR0_Rate_1000k    0x00          //1000KBPS的预设值
  96. #define         BTR1_Rate_1000k    0x14          //1000KBPS的预设值
  97. //BPS
  98. #define         ByteRate_10k       10 //24MHZ**********************
  99. #define         ByteRate_40k       40
  100. #define         ByteRate_50k       50
  101. #define         ByteRate_80k       80
  102. #define         ByteRate_100k      100
  103. #define         ByteRate_125k      125
  104. #define         ByteRate_200k      200
  105. #define         ByteRate_250k      250
  106. #define         ByteRate_400k      400
  107. #define         ByteRate_500k      500
  108. #define         ByteRate_800k      800
  109. #define         ByteRate_1000k     1000

  110. //命令字
  111. #define    TR_CMD     0X01
  112. #define    AT_CMD     0X02
  113. #define    RRB_CMD    0X04
  114. #define    COS_CMD    0X08
  115. #define    SRR_CMD    0X10
  116. #define    GTS_CMD    0X10
  117. //错误字

  118. #define CAN_INTERFACE_OK      0
  119. #define CAN_BUS_OK            0
  120. #define CAN_INTERFACE_ERR     0XFF
  121. #define CAN_ENTERSET_ERR      0XFE
  122. #define CAN_QUITSET_ERR       0XFD
  123. #define CAN_INITOBJECT_ERR    0XFC
  124. #define CAN_INITBTR_ERR       0XFB
  125. #define CAN_INITOUTCTL_ERR    0XFA
  126. #define CAN_INTCLKDIV_ERR     0XF9
  127. #define CAN_BUS_ERR           0XF8

  128. //系统指针,指向SJA1000

  129. unsigned char xdata *SJA_BCANAdr;
  130. unsigned char data Tmod_data;
  131. unsigned char run_lamp_flush_count = 0;
  132. unsigned char run_lamp_flush_time = 10;
  133. sbit  run_lamp = P1^0;
  134. unsigned char data send_data[10],RevceData[10];
  135. //unsigned int data rxbuffer[10]={REG_RXBuffer1,REG_RXBuffer2,REG_RXBuffer3,REG_RXBuffer4,REG_RXBuffer5,REG_RXBuffer6,REG_RXBuffer7,REG_RXBuffer8,REG_RXBuffer9,REG_RXBuffer10};
  136. //unsigned int data txbuffer[10]={REG_TXBuffer1,REG_TXBuffer2,REG_TXBuffer3,REG_TXBuffer4,REG_TXBuffer5,REG_TXBuffer6,REG_TXBuffer7,REG_TXBuffer8,REG_TXBuffer9,REG_TXBuffer10};
  137. //unsigned char data Send_CAN_Info_ID[5]={0x08,0x55,0xe0,0x55,0x55};
  138. //unsigned char data Send_CAN_Info_ID[5]={0x01,0x55,0xe0,0x55,0x55};
  139. unsigned char data Com_RecBuff[8]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08};
  140. //unsigned char data Com_RecBuff[8];
  141. unsigned char bdata flag_init;
  142. //*************************
  143. #define INBUF_LEN 8   //数据长度

  144. unsigned char inbuf1[INBUF_LEN];
  145. unsigned char checksum,count3=0;
  146. bit  read_flag=0;
  147. sbit P10=P1^0;
  148. sbit P11=P1^1;
  149. sbit P12=P1^2;
  150. sbit P13=P1^3;
  151. sbit P16=P1^6;
  152. sbit P37=P3^7;
  153. sbit P34=P3^4;

  154. sbit key=P2^5; //Button按键
  155. sbit P3_5=P3^5;//数码管位选
  156. sbit P2_6=P2^6;

  157. //***************************
  158. sbit rcv_flag=flag_init^0;
  159. sbit err_flag=flag_init^0;
  160. sbit CS=P2^0;
  161. //sbit RECOK=P3^4;
  162. unsigned char RECOK;
  163. unsigned int msg;
  164. /************************************************************************
  165. *函数原型: void init_serialcomm(void)            *
  166. *参数说明: 串口初始化                            *                                                             *
  167. *说明:     设值单片机的定时器1的方式选择波特率 。该子程序只能用于复位模式                     
  168. ************************************************************************/
  169. void init_serialcomm(void)
  170. {
  171.     SCON  = 0x50;       //SCON: serail mode 1, 8-bit UART, enable ucvr
  172.     TMOD |= 0x20;       //TMOD: timer 1, mode 2, 8-bit reload
  173.     PCON |= 0x80;       //SMOD=1;
  174.     TH1   = 0xF4;       //Baud:57600  fosc=11.0592MHz  
  175.     TL1   = 0xF4;       //baud:57600      fosc=22.1184MHz  0xFE
  176.     IE   |= 0x90;       //Enable Serial Interrupt
  177.     TR1   = 1;          // timer 1 run
  178.     // TI=1;
  179. }
  180. //定时器0初始化
  181. void timer0initial()
  182. {
  183.         TMOD |= 0x1;        //工作方式16位定时计数器
  184.         TH0=0xb8;TL0=0x00;  //50MS定时初值(T0计时用)
  185.     IE   |= 0x90;       //Enable Serial Interrupt
  186.     ET0=0;TR0=0;
  187. }
  188. //向串口发送一个字符
  189. void send_char_com(unsigned char ch)  
  190. {
  191.     SBUF=ch;
  192.     while(!TI);
  193.     TI=0;
  194. }

  195. //向串口发送一个字符串,strlen为该字符串长度
  196. void send_string_com(unsigned char *str,unsigned int strlen)
  197. {
  198.     unsigned int k=0;
  199.     do
  200.     {
  201.         send_char_com(*(str + k));
  202.         k++;
  203.     } while(k < strlen);
  204. }
  205. //定时器0中断,不够8个就在此发送
  206. void time_intt0(void) interrupt 1 using 2
  207. {
  208.   ET0=0;TR0=0;TH0=0xb8;TL0=0x00;
  209.   CAN_Send_anylength(inbuf1,count3);
  210.   count3=0;
  211.   memset(inbuf1,0,8);
  212. }
  213. //串口接收中断函数
  214. void serial () interrupt 4 using 1
  215. {  

  216.     if(RI)
  217.     {
  218.         
  219.         unsigned char ch;
  220.         RI = 0;
  221.         ET0=1;TR0=1;
  222.         ch=SBUF;
  223.       
  224.         {
  225.              inbuf1[count3]=ch;
  226.              count3=count3+1;
  227.              if( count3==INBUF_LEN)
  228.              {
  229.                  ET0=0;TR0=0;TH0=0xb8;TL0=0x00;//关闭定时中断,停止定时中断
  230.                  count3=0;
  231.                  /*P34=0;
  232.                  P10=!P10;
  233.                  P11=!P11;
  234.                  P12=!P12;
  235.                  P13=!P13;*/
  236.                  CAN_Send_anylength(inbuf1,8);
  237.                  memset(inbuf1,0,8);
  238.                  
  239.              }
  240.         
  241.     }
  242.     }
  243. }


  244. //***********************************************************************
  245. /************************************************************************
  246. *函数原型: bit BCAN_SET_OUTCLK( unsigned char Clock_Out)               *
  247. *参数说明:                                                             *
  248. *          Clock_Out:存放时钟分频寄存器(CDR)的参数设置                 *
  249. *返回值:                                                               *
  250. *           0 ;设置成功                                                *
  251. *           1 ;设置失败                                                *
  252. *说明:设置SJA1000的时钟分频 。该子程序只能用于复位模式                     
  253. ************************************************************************/
  254. bit BCAN_SET_OUTCLK(unsigned char Clock_Out)
  255. {
  256.   SJA_BCANAdr=REG_CDR;           

  257.   *SJA_BCANAdr=Clock_Out;        
  258.   if(*SJA_BCANAdr != Clock_Out)
  259.      return 1;
  260.    else
  261.      return 0;
  262. }

  263. /************************************************************************
  264. *函数原型: bit BCAN_SET_OBJECT(unsigned char  BCAN_ACR0,BCAN_ACR1,BCAN_ACR2,BCAN_ACR3     
  265.                                               BCAN_AMR0, BCAN_AMR1, BCAN_AMR2, BCAN_AMR3     
  266. *参数说明:                                                              *
  267. *    BCAN_ACR(0-3):存放验收代码寄存器(ACR)的参数设置                  *
  268. *    BCAN_AMR(0-3):存放接收屏蔽寄存器(AMR)的参数设置                  *
  269. *返回值:                                                                *
  270. *           0 ;设置成功                                                 *
  271. *           1 ;设置失败                                                 *
  272. *说明:设置CAN节点的通讯对象,允许接收的报文,是由AMR和ACR共同决定的.     *
  273. *************************************************************************/
  274. bit BCAN_SET_OBJECT(unsigned char  BCAN_ACR0,BCAN_ACR1,BCAN_ACR2,BCAN_ACR3,BCAN_AMR0,BCAN_AMR1,BCAN_AMR2,BCAN_AMR3)
  275. {
  276.   SJA_BCANAdr=REG_TXBuffer1;     

  277.   *SJA_BCANAdr=BCAN_ACR0;        //写入参数
  278.    
  279.   SJA_BCANAdr=REG_TXBuffer2;
  280.   *SJA_BCANAdr=BCAN_ACR1;

  281.   SJA_BCANAdr=REG_TXBuffer3;  
  282.   *SJA_BCANAdr=BCAN_ACR2;
  283.    
  284.   SJA_BCANAdr=REG_TXBuffer4;
  285.   *SJA_BCANAdr=BCAN_ACR3;  

  286.   //校验写入值
  287.   if(*SJA_BCANAdr != BCAN_ACR3)  return 1;
  288.   
  289.   SJA_BCANAdr=REG_TXBuffer5;      

  290.   *SJA_BCANAdr=BCAN_AMR0;     //写入参数
  291.   
  292.   SJA_BCANAdr=REG_TXBuffer6;         
  293.   *SJA_BCANAdr=BCAN_AMR1;

  294.   SJA_BCANAdr=REG_TXBuffer7;
  295.   *SJA_BCANAdr=BCAN_AMR2;

  296.   SJA_BCANAdr=REG_TXBuffer8;
  297.   *SJA_BCANAdr=BCAN_AMR3;
  298.   //校验写入值
  299.   if(*SJA_BCANAdr != BCAN_AMR3) return 1;

  300.   return 0;
  301. }

  302. /************************************************************************
  303. ;*函数原型:  bit BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)          *
  304. ;*返回值:                                                               *
  305. ;*           0 ;波特率设置成功                                          *
  306. ;*           1 ;波特率设置失败                                          *
  307. ;*                                                                      *
  308. ;*说明:设置CAN控制器SJA1000通讯波特率.SJA1000的晶振必须为16MHZ,         *
  309. ;*     其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于        *
  310. ;*     复位模式                                                         *  
  311. ;************************************************************************/
  312. bit BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)         //波特率选择
  313. {
  314.      unsigned char BR_Num= CAN_ByteRate,BTR0_num,BTR1_num;
  315.        switch (BR_Num)
  316.         {
  317.           case ByteRate_10k:
  318.                BTR0_num=0xef;
  319.                BTR1_num=0xff;
  320.                break;
  321.           case ByteRate_40k  :
  322.                BTR0_num=0x87;
  323.                BTR1_num=0xff;
  324.                break;
  325.           case ByteRate_50k:
  326.                //BTR0_num=0x47;
  327.                //BTR1_num=0x2f;
  328.                BTR0_num=0x0e;
  329.                BTR1_num=0x1c;
  330.                break;
  331.           case ByteRate_80k  :
  332.                //BTR0_num=0x83;
  333.                //BTR1_num=0xff;
  334.                BTR0_num=0x49;                      //ok
  335.                BTR1_num=0x1b;
  336.                break;
  337.           case ByteRate_100k  :
  338.                //BTR0_num=0x43;
  339.                //BTR1_num=0x2f;
  340.                BTR0_num=0x04;                       //ok
  341.                BTR1_num=0x1c;
  342.                break;
  343.           case ByteRate_125k  :                      //SJA1000的晶振为必须为16MHZ,波特率设置为125kpbs
  344.                BTR0_num=0x03;
  345.                BTR1_num=0x1c;
  346.                //BTR0_num=0x44;                        //ok
  347.                //BTR1_num=0x1f;
  348.                break;
  349.           case ByteRate_200k  ://24MHZ
  350.             //   BTR0_num=0xc5;  //
  351.              //  BTR1_num=0xa5;
  352.                BTR0_num=0x43;                        //ok
  353.                BTR1_num=0x1b;
  354.                break;
  355.           case ByteRate_250k  ://24MHZ
  356.             //   BTR0_num=0xc5;  //
  357.              //  BTR1_num=0xa5;
  358.                BTR0_num=0x01;                        //ok
  359.                BTR1_num=0x1c;
  360.                break;
  361.           /* case ByteRate_200k  ://24MHZ
  362.                BTR0_num=0x81;
  363.                BTR1_num=0xFA;
  364.                break;*/
  365.           case ByteRate_400k  :
  366.                BTR0_num=0x80;
  367.                BTR1_num=0xfa;
  368.                break;
  369.           case ByteRate_500k  :
  370.                BTR0_num=0x01;
  371.                BTR1_num=0x1c;
  372.                break;
  373.           case ByteRate_800k  :
  374.                BTR0_num=0x00;
  375.                BTR1_num=0x16;
  376.                break;
  377.           case ByteRate_1000k  :
  378.                BTR0_num=0x00;
  379.                BTR1_num=0x14;
  380.                break;
  381.           default :
  382.                return 1;
  383.                break;
  384.         }

  385.     SJA_BCANAdr=REG_BTR0;
  386.     *SJA_BCANAdr=BTR0_num;
  387.     if(*SJA_BCANAdr!=BTR0_num)
  388.       {return 1;}
  389.     SJA_BCANAdr=REG_BTR1;
  390.     *SJA_BCANAdr=BTR1_num;
  391.     if(*SJA_BCANAdr!=BTR1_num)
  392.       {return 1;}
  393.     return 0;
  394. }
  395. /************************************************************************
  396. *函数原型: bit BCAN_SET_CONTROL(unsigend char CMD)                     *
  397. *参数说明: 设置控制寄存器                                              *
  398. ************************************************************************/
  399. bit BCAN_SET_CONTROL(unsigned char CMD)
  400. {  unsigned char TempData;

  401.   SJA_BCANAdr=REG_CONTROL;   //SJA_BaseAdr+0x00  控制寄存器
  402.   TempData=  *SJA_BCANAdr;

  403.   *SJA_BCANAdr=CMD;

  404.   if (*SJA_BCANAdr == CMD)
  405.     return 0;
  406.   else
  407.     return 1;

  408. }
  409. /************************************************************************
  410. *函数原型:  bit   BCAN_CREATE_COMMUNATION(void)                        *
  411. *参数说明:  无                                                         *
  412. *返回值:                                                               *
  413. *           0 ; 表示SJA1000接口正常                                    *
  414. *           1 ; 表示SJA1000与处理器接口不正常                          *
  415. *说明:该函数用于检测CAN控制器的接口是否正常                            *
  416. ************************************************************************/
  417. bit BCAN_CREATE_COMMUNATION(void)
  418. {  
  419.     SJA_BCANAdr=REG_TEST;      
  420.     *SJA_BCANAdr=0xaa;       //写入测试值
  421.     if(*SJA_BCANAdr == 0xaa)
  422.        return 0;            //读测试正确
  423.     else
  424.        return 1;
  425.      
  426. }

  427. /************************************************************************
  428. *函数原型:      bit   BCAN_ENTER_RETMODEL(void)                        *
  429. *参数说明:  无                                                         *
  430. *返回值:                                                               *
  431. *           0 ; 表示成功进入复位工作模式                               *
  432. *           1 ; 表示不能进入复位工作模式                               *
  433. *                                                                      *
  434. *说明:      CAN控制器进入复位工作模式                                  *
  435. ************************************************************************/
  436. bit   BCAN_ENTER_RETMODEL(void)     //置位复位请求
  437. {
  438.     unsigned   char   TempData;
  439.     SJA_BCANAdr  = REG_CONTROL;   

  440.   TempData=  *SJA_BCANAdr;      
  441.     *SJA_BCANAdr=0x01;                 //置位复位请求 和双滤波模式
  442.     if((*SJA_BCANAdr&0x01) == 1)
  443.      return   0;
  444.     else
  445.       return   1;   
  446. }
  447. /************************************************************************
  448. *函数原型:   BCAN_CMD_PRG(unsigned char cmd)                           *
  449. *参数说明:  unsigned char cmd                                          *
  450. *返回值:                                                               *
  451. *           0 ; 请求成功                                               *
  452. *           1 ; 请求失败                                               *
  453. *                                                                      *
  454. *说明:      启动命令字                                                 *
  455. ************************************************************************/
  456. bit  BCAN_CMD_PRG(unsigned char cmd)
  457. {
  458.    SJA_BCANAdr=REG_COMMAND;            //访问地址指向命令寄存器
  459.    *SJA_BCANAdr=cmd;                   //启动命令字

  460.    switch(cmd)
  461.    {    case  TR_CMD:                    

  462.            return    0;
  463.            break;

  464.   case  SRR_CMD:      

  465.       return 0;
  466.      break;
  467.    
  468.   case  AT_CMD:                  

  469.             SJA_BCANAdr = REG_STATUS;   //访问地址指向状态寄存器   
  470.            if((*SJA_BCANAdr & 0x20)==0) //判断是否正在发送
  471.              return  0;
  472.            else
  473.              return  1;              
  474.            break;
  475.      case  RRB_CMD:                  
  476.            SJA_BCANAdr = REG_STATUS;   //访问地址指向状态寄存器   
  477.            if((*SJA_BCANAdr & 0x01)==1)
  478.               return  1;
  479.            else           
  480.               return  0;               
  481.            break;  
  482.      case  COS_CMD:                  

  483.            SJA_BCANAdr = REG_STATUS;   
  484.            if((*SJA_BCANAdr & 0x02)==0)//判断清除超载是否成功
  485.              return  0;
  486.            else
  487.              return  1;            
  488.            break;
  489.      default:
  490.              return  1;
  491.              break;
  492.    }
  493. }

  494. /****************************************************
  495. **函数原型:  void ex0_int(void) interrupt 0 //using 1
  496. **功    能:  中断接收函数
  497. **入口参数:   无
  498. **出口参数:   RevceData[]数组   
  499. **说    明:   当sja1000 收到正确的报文时,会产生int中断           
  500. *****************************************************/
  501. void ex0_int(void) interrupt 0 using 1
  502. {  
  503. unsigned char tt,tt1,length,i;
  504. /*msg++;
  505. if(msg==2)
  506.   {
  507.   msg=0;
  508.   P34=0;
  509.   P10=!P10;
  510.   P11=!P11;
  511.   P12=!P12;
  512.   P13=!P13;
  513.   }    */
  514. SJA_BCANAdr=REG_INTERRUPT;
  515. if((*SJA_BCANAdr)&0x01)                   //产生了接收中断
  516. {  
  517.     SJA_BCANAdr=REG_RXBuffer1;
  518.     tt=*SJA_BCANAdr;
  519.     tt1=*SJA_BCANAdr;
  520.     length=tt1&0x0F;
  521.      if ((tt&0x40)!=0x40)                   //数据帧   = 为远程帧
  522.      {  
  523.      SJA_BCANAdr =REG_RXBuffer4 ;           //宏定义的变量不能memcpy(RevceData,REG_RXBuffer4,8);
  524.      
  525.      memcpy(RevceData,SJA_BCANAdr,length);  //功能:由src所指内存区域复制count个字节到dest所指内存区域
  526.     //memcpy(Com_RecBuff,RevceData,8);      //测试用的主要是把接收到的数据在发出去,验证数据的正确
  527.                                             //以下代码是发送到串
  528.     for(i=0;i<length;i++)
  529.      send_char_com(RevceData[i]);
  530.          display(RevceData[0]);
  531.     /* send_char_com(RevceData[0]);
  532.      send_char_com(RevceData[1]);           
  533.      send_char_com(RevceData[2]);
  534.      send_char_com(RevceData[3]);
  535.      send_char_com(RevceData[4]);
  536.      send_char_com(RevceData[5]);
  537.      send_char_com(RevceData[6]);
  538.      send_char_com(RevceData[7]);*/
  539.      
  540.     // RECOK=1;                              //测试用的主要是把接收到的数据在发出去,验证数据的正确
  541.      }

  542.      BCAN_CMD_PRG(RRB_CMD);                  //释放SJA1000接收缓冲区,****已经修改

  543. }
  544. }

  545. unsigned char BCAN_DATA_WRITE(unsigned char *SendDataBuf)
  546. {  unsigned char temp;
  547.    
  548.     SJA_BCANAdr = REG_STATUS;   
  549.     temp=*SJA_BCANAdr;

  550.     if ((temp&0x08)==0) return  1;    //上次发送未完成
  551.     if ((temp&0x04)==0) return  2;    //发送缓冲区是否锁定
  552.     if ((temp&0x10)==0x10) return 3;  //判断是否正在接收   

  553.     SJA_BCANAdr = REG_RXBuffer1;      //访问地址指向发送缓冲区1,修改成头文件

  554.     memcpy(SJA_BCANAdr,SendDataBuf,4);   
  555.     BCAN_CMD_PRG(TR_CMD);             //请求发送         
  556.     return 0;
  557. }
  558. //CAN发送任意长度字节
  559. void CAN_Send_anylength(unsigned char *CAN_TX_Buf,unsigned char length1)
  560. {
  561.         unsigned char temptt;
  562.         loop:
  563.     SJA_BCANAdr = REG_STATUS;   
  564.          temptt=*SJA_BCANAdr;
  565.         //temptt=Read_SJA1000(REG_STATUS);
  566.         if((temptt&0x04)==0x00)  goto loop;               //循环检测等待                       
  567.         //可以向发送缓冲器写数据
  568.         {
  569.     SJA_BCANAdr = REG_RXBuffer1;      //访问地址指向发送缓冲区1,修改成头文件
  570.     *SJA_BCANAdr=length1;  
  571.     SJA_BCANAdr = REG_RXBuffer2;      //访问地址指向发送缓冲区1,修改成头文件
  572.     *SJA_BCANAdr=0x00;  
  573.      SJA_BCANAdr = REG_RXBuffer3;     //访问地址指向发送缓冲区1,修改成头文件
  574.     *SJA_BCANAdr=0x00;
  575.     SJA_BCANAdr = REG_RXBuffer4;
  576.     memcpy(SJA_BCANAdr,CAN_TX_Buf,length1);   
  577.         //数据发送请求
  578.     BCAN_CMD_PRG(TR_CMD);            //请求发送  
  579.         }
  580. }
  581. //CAN发送一个字节
  582. void CAN_Send_onebyte(unsigned char CAN_TX_data,unsigned char length1)
  583. {
  584.         unsigned char temptt;
  585.         loop:
  586.     SJA_BCANAdr = REG_STATUS;   
  587.          temptt=*SJA_BCANAdr;
  588.         //temptt=Read_SJA1000(REG_STATUS);
  589.         if((temptt&0x04)==0x00)  goto loop;               //循环检测等待                       
  590.         //可以向发送缓冲器写数据
  591.         {
  592.     SJA_BCANAdr = REG_RXBuffer1;      //访问地址指向发送缓冲区1,修改成头文件
  593.     *SJA_BCANAdr=length1;  
  594.     SJA_BCANAdr = REG_RXBuffer2;      //访问地址指向发送缓冲区1,修改成头文件
  595.     *SJA_BCANAdr=0x00;  
  596.      SJA_BCANAdr = REG_RXBuffer3;     //访问地址指向发送缓冲区1,修改成头文件
  597.     *SJA_BCANAdr=0x00;
  598.     SJA_BCANAdr = REG_RXBuffer4;
  599.     //memcpy(SJA_BCANAdr,CAN_TX_Buf,length1);  
  600.     *SJA_BCANAdr=CAN_TX_data;
  601.         //数据发送请求
  602.     BCAN_CMD_PRG(TR_CMD);            //请求发送  
  603.         }
  604. }


  605. /****************************************************
  606. **函数原型:   bit Sja_1000_Init(void)
  607. **功    能:   初始化SJA10000
  608. **入口参数:    无
  609. **返 回 值:     
  610.       0: 初始化成功
  611.       1: 复位失败
  612.       2:  测试sja1000失败
  613.       3: 设置失败
  614.       4: 设置验收滤波器失败
  615.       5: 设置波特率失败     
  616. *****************************************************/

  617. unsigned char Sja_1000_Init(void)
  618. {
  619. bit s;
  620. EA=0;                                 //关总中断
  621.    s=BCAN_ENTER_RETMODEL();
  622. if (s==1) return 1;
  623.     s=BCAN_CREATE_COMMUNATION();       //建立通信
  624.     if (s==1) return 2;

  625.   s=BCAN_SET_OUTCLK(0xC8);             //Pelican
  626. if (s==1) return 3;

  627.   s=BCAN_SET_OBJECT(0x01,0xe0,0x02,0xe0,0x00,0x0F,0x00,0x0F);//屏蔽寄存器,都设为无关,接收所有报文
  628.                                                             //当屏蔽位为1,不滤波,0就滤波必须相等
  629. //s=BCAN_SET_OBJECT(0x55,0xe0,0xaa,0xa1,0x00,0x00,0xff,0xff);//验收码&屏蔽码

  630. if (s==1) return 4;

  631. s=BCAN_SET_BANDRATE(ByteRate_125k);    //设置波特率125K 16MHZ
  632.     if (s==1) return 5;
  633.    
  634. SJA_BCANAdr=REG_OCR ;                  //输出控制寄存器  
  635.     *SJA_BCANAdr=0x1a;        
  636.     SJA_BCANAdr=REG_INTENABLE;      

  637.    *SJA_BCANAdr=0x1D;                  //设置中断,接收和发送中断
  638.    
  639.     // s=BCAN_SET_CONTROL(0x08);
  640.     SJA_BCANAdr=REG_CONTROL;            //退出 复位模式
  641.     *SJA_BCANAdr=*SJA_BCANAdr&0xfe;
  642.      if(*SJA_BCANAdr!=0x00)
  643.      return 6;

  644. //if (s==1) return 6;

  645.     EA=1;
  646. return 0;   
  647. }
  648. /****************************************************
  649. **函数原型:  void display(unsigned char num)
  650. **功    能:  数码管显示
  651. **入口参数:   要显示字符
  652. **出口参数:   无
  653. **说    明:   当SJA1000收到正确的报文时,然后显示出来           
  654. *****************************************************/
  655. unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
  656. void display(unsigned char num)  // 显示子函数

  657. {

  658.                 P3_5=0;//选通第一位数码管的阳极位选端,即给数码管的共阳极供电
  659.         P2_6=0;//选通第二位数码管的阳极位选端,即给数码管的共阳极供电
  660.         P1=table[num]; //将第num个显示编码送P0口
  661. }
  662. //***************************************************

  663. //初始化cpu

  664. //**************************************************
  665. void Init_Cpu(void)                                  //单片机初始化,开放外部中断0
  666. {
  667.      PX0=1;
  668.      EX0=1;
  669.      IT0=0;
  670.     // EA=1;
  671. }

  672. /****************************************************
  673. **函数原型:   void main(void)
  674. **功    能:   主程序部分:
  675. **入口参数:    无
  676. **返 回 值:     
  677. *****************************************************/

  678. void main(void)
  679. {  
  680.     unsigned char temptt,ss;
  681.         unsigned char num=0;

  682.     CS=0;                //片选择引脚
  683.     EA=0;
  684.     Init_Cpu();
  685.    
  686.    init_serialcomm();     //初始化串口
  687.    timer0initial();       //定时器0初始化
  688.     P34=0;                //选通数码管控制开关
  689.         display(11);                  //显示该板号A
  690.    //初始化SJA1000     
  691.    ss=Sja_1000_Init();
  692.    if (ss!=0)             //初始化失败
  693.       //send_string_com("init fail!");**********************
  694.       send_char_com(0xBB);              //测试专用发送到串口看状态   
  695.    else
  696.       EA=1; //初始化成功,开总中断
  697.    
  698.      //次标识位可以作为,串口接收完,置标志然后发送出去或者当作按键发送******
  699.    while(1)
  700.    {
  701.      
  702.      //CAN_Send_anylength(Com_RecBuff,8);
  703.      if(key==0)
  704.        {
  705.         delay10ms();
  706.                    while(key==0);
  707.         num=num+1;if(num==16) num=0;
  708.         CAN_Send_onebyte(num);      //发送按键状态
  709.       // CAN_Send_anylength(Com_RecBuff,8);
  710.             CAN_Send_onebyte(num,1);
  711.                 display(num);
  712.         if(num==16) num=0;
  713.         delay10ms();
  714.            }
  715.      
  716.      SJA_BCANAdr = REG_STATUS;   
  717.      temptt=*SJA_BCANAdr;         
  718.      delay_ms(100);
  719.   if ((temptt&0x40)==0x40)                     //读错误状态

  720.     {  
  721.     Sja_1000_Init();
  722.     send_char_com(0xee);                    //测试专用发送到串口看状态                     
  723.   }
  724.    }   

  725. }
复制代码

所有资料51hei提供下载:

点对点带滤波的例程.rar (122.38 KB, 下载次数: 35)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:171838 发表于 2019-3-22 18:21 | 只看该作者
为什么初始化失败啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表