📄 cantrans.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 + -