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

📄 cantrans.c

📁 这是一本
💻 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 + -