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

📄 canbus.c

📁 CAN总线通讯例程,包含写缓冲区读缓冲区处理Can总线接收信息向Can总线发送信息Can接口芯片初始化CanBus接口芯片产生中断[INTR0] 等程序
💻 C
字号:
/********************************************  
对外接口 Can_Receive(从CanBus接收数据)  
         Can_Send(从CanBus发送数据)  
         INITCAN(初始化)  
         CanINTR(中断函数)  
         ChkEndC(检查帧发送结束)  
********************************************/   
#ifndef __CANTRANS_C__    
#define __CANTRANS_C__    
   
#include <AT89X51.H>    
   
#include "hal.h"    
#include "ChgPoint.h"    
   
#define _BUFSIZEC 0x0bff      //缓冲区长度    
#define _INTRPSW 0x27         //中断屏蔽    
#define _CANADD 0             //CAN接口芯片地址    
   
uchar xdata bufC[_BUFSIZEC];        //缓冲区    
uchar CheckCS = 0;   
uint des_c = 0;   
uint sou_c = 0;             //缓冲区写入,读出指针    
uchar xdata *canport = _CANADD;   
uint lenC = _BUFSIZEC;        //缓冲区长度    
    
void Can_Write(void);         //写缓冲区    
void Can_Read(uchar *buf);    //读缓冲区    
void rst_wdog(void);   
   
uchar Can_Receive(uchar *buf)   //处理Can总线接收信息    
{   
  uchar i;   
  uint p;   
  uchar temp;   
  if(des_c == sou_c)   
    return(0);                //无数据送入则返回    
  p = sou_c;   
  for(i = 0;i < 3;i ++)   
    p = ChgPoint(p, lenC);           //总长度    
  temp = bufC[p] + 4;   
  for(i = 0;i < temp;i ++)           //读入数据    
    {   
      p = bufC[sou_c];   
      *buf = p;   
      buf ++;   
      sou_c = ChgPoint(sou_c, lenC);   
    }   
  return(1);   
}   
   
void Can_Send(uchar *buf)      //向Can总线发送信息    
{   
  uchar temp;   
  uchar i;   
  uchar te;   
  rst_wdog();   
  te = *buf;   
  *(canport + 19) = te;       //目的设备地址,DesDevID    
  buf ++;   
  te = *buf;   
  *(canport + 18) = te;       //源设备地址,SouDevID    
  buf ++;   
  te = *buf;   
  *(canport + 17) = te;       //命令字,Type    
  buf ++;   
  te = *buf;   
  *(canport + 16) = te | 0x80;       //数据长度,Length    
  buf ++;   
  *(canport + 20) = 0;       //保留位    
  for(i = 0;i < temp;i ++)   
    {   
      te = *buf;   
      buf ++;   
      *(canport + 21 + i) = te; //写入Data    
    }   
  *(canport + 1) = 0x01;            //发送信息    
  CheckCS = 1;   
}   
   
void INITCAN()                       //Can接口芯片初始化    
{   
  uchar i;   
  uchar dev = 0;   
  P1 = 0xff;   
  dev = (P1>>2)&0x3c;   
  P3 = 0xff;   
  dev = dev|((P3<<5)&0x01);   
  dev = dev|((P3<<3)&0x02);  //本机设备号    
  *canport = 0x09;              //单验收滤波器,复位状态    
  *(canport + 31) = 0x80;         //PeliCan模式,启用CLKOUT引脚,供应时钟频率为晶振频率的1/2    
  for(i = 0;i < 8;i ++)   
    *(canport + 16 + i)= 0xff;  //验收代码和屏蔽代码均被置为0xff    
  *(canport + 18) = dev;          //本机设备号写入验收代码,即协议中规定的DesDevID处    
  *(canport + 22) = 0;           //验收屏蔽位     
  *(canport + 6) = 0x71;          //总线定时器0    
  *(canport + 7) = 0xb4;          //总线定时器1    
  *(canport + 8) = 0x1a;          //输出控制    
  *canport = 0x08;              //正常状态    
  *(canport + 4) = _INTRPSW;   
}   
   
uchar ChkEndC()   
{   
  return(CheckCS);   
}   
   
void CanINTR() interrupt 0 using 1  //CanBus接口芯片产生中断(INTR0)    
{   
  uchar sta;   
  uchar temp;   
  EX0 = 0;   
  sta = *(canport + 3);     //读中断寄存器    
  temp = sta & 0x20;   
  if(temp == 0x20)   
    INITCAN();    
  temp = sta & 0x04;   
  if(temp == 0x04)   
    INITCAN();                  //消极错误中断,错误报警中断,均导致重启    
  temp = sta & 0x02;   
  if(temp == 0x02)              //发送中断处理    
    CheckCS = 0;    
  temp = sta & 0x01;   
  if(temp == 0x01)          //接收中断,接收数据    
    Can_Write();   
  EX0 = 1;   
}   
   
void Can_Write()           //写缓冲区    
{   
  uchar temp;   
  uchar i;   
  uint p = 0;   
  temp = *(canport + 16) & 0x0f;           //获得长度    
  p = des_c;   
  for(i = 0;i < (temp + 3);i ++)   
    {   
      p = ChgPoint(p, lenC);   
      if(p == sou_c)                        //缓冲区溢出则丢弃该帧    
        {      
          *(canport + 1) = 0x04;   
          return;   
        }    
    }   
  bufC[des_c] = *(canport + 19);            //写入DesDevID    
  des_c = ChgPoint(des_c, lenC);            //des_c ++    
  bufC[des_c] = *(canport + 18);            //写入SouDevID    
  des_c = ChgPoint(des_c, lenC);   
  bufC[des_c] = *(canport + 17);            //写入Type    
  des_c = ChgPoint(des_c, lenC);   
  bufC[des_c] = temp;                       //写入Length    
  des_c = ChgPoint(des_c, lenC);       
  for(i = 0;i < temp;i ++)   
    {   
      bufC[des_c] = *(canport + 21 + i);    //写入Data    
      des_c = ChgPoint(des_c, lenC);   
    }   
  *(canport + 1) = 0x04;                    //释放缓冲区    
}   
   
#endif 

⌨️ 快捷键说明

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