📄 can.c
字号:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//描述: sja1000can总线处理函数
// CAN主要参数: PeliCAN模式,扩展帧EFF模式 &
// 29位标示码结构: &
// 本节点的地址: 0x11,0x22,0x33,0x00;可以接收全部节点的数据 &
// 目的节点地址:0x01,0x02,0x03,0x00;可以被能接收全部节点数据的节点接收 &
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#include <reg52.h>
#include <intrins.h>
#include <inc/can.h>
#include "inc/timer_pwm.h"
#include "inc/CPUIO_DEF.H"
#include "inc/EXT_PUBLIC_VARIABLE.H"
#include "inc/candul.H"
/**************************************************************************************
;;函数原型: void CAN_RXD( void ) interrupt 0
;;函数功能: CAN中断处理函数,包括接收中断和发送中断
;;函数输入: 无
;;函数输出: 无
;;函数返回值: 无
***************************************************************************************/
void CAN_RXD( void ) interrupt 0 using 3
{
uchar data Judge,tmpbuf[5];
// EA = 0;//关CPU中断
Judge = IR;
if( Judge & 0x01)
{//IR.0 = 1 接收中断
tmpbuf[0] = RBSR0; //标示
tmpbuf[1] = RBSR1; //id --地址
if( ((tmpbuf[0]&0xc0) == 0x80)&&(tmpbuf[1] == ADDRESS) )
{ //是扩展帧和数据帧并且是本机地址
if( CanRx.farmeSta ==NULL )
{
CanRx.farmeSta = FULL;
CanRx.farmeType = RBSR3; //命令类型
CanRx.farmeSubType = RBSR4; //子命令
CanRx.farmeLong = tmpbuf[0]&0x0f; //数据长度
CanRx.farmeData[0] = RBSR5;//数据
CanRx.farmeData[1] = RBSR6;//数据
CanRx.farmeData[2] = RBSR7;//数据
CanRx.farmeData[3] = RBSR8;//数据
CanRx.farmeData[4] = RBSR9;//数据
CanRx.farmeData[5] = RBSR10;//数据
CanRx.farmeData[6] = RBSR11;//数据
CanRx.farmeData[7] = RBSR12;//数据
CanRx.farmeData[8] = RBSR2; //帧计数
}
}
CMR = 0X04; //释放接收缓冲器
Judge = ECC; //释放错误代码捕捉寄存器
}
else if(Judge & 0x02)
{ //IR.1 = 1 发送中断
}
else if(Judge & 0x04)
{ //IR.2 = 1 错误报警中断
}
else if(Judge & 0x08)
{//IR.3 = 1 数据溢出中断
CMR = 0X10; //清楚数据溢出位
}
else if(Judge & 0x10)
{//IR.4 = 1 唤醒中断
}
else if(Judge & 0x20)
{//IR.5 = 1 错误消极中断
}
else if(Judge & 0x40)
{//IR.6 = 1 仲裁丢失中断
Judge = ALC;//释放仲裁随时捕捉寄存器
}
else
{//IR.7 = 1 总线错误中断
}
IER = 0x01;// .0=1--接收中断使能;
// EA = 1;//打开CPU中断
}
/**************************************************************************************
;;函数原型: void Rxd_deal(void)
;;函数功能: CAN接收处理函数
;;函数输入: 无
;;函数输出: 无
;;函数返回值: 无
;;主循环调用
***************************************************************************************/
void Rxd_deal(void)
{//////// 接收处理程序//////////////
uchar ucTxdBuf[8];
if( CanRx.farmeSta == FULL )
{
CanRx.farmeSta = NULL;
if( (CanRx.farmeType == MS_REST_STOP_CAR)|| (CanRx.farmeType == MS_STOP_CAR50_SLOW)||(CanRx.farmeType == MS_STOP_CAR100_SLOW)||
(CanRx.farmeType == MS_REST_STOP_CAR)||(CanRx.farmeType == MS_STOP_CAR50_FAST)||(CanRx.farmeType == MS_STOP_CAR100_FAST)||
(CanRx.farmeType == MS_ALLOW_IN_UPDATE_STA))
{
//数据接收正确应答
ucTxdBuf[0] = 0x00;//000000回复相应结果
CAN_TXD( MADDRESS,SM_RECEV_OK,UN_ACK,1,ucTxdBuf );
StopCar.sta = START;
StopCar.cmd = CanRx.farmeType;
}
else
{
switch( CanRx.farmeType )
{
case MS_SYS_SEELP://系统睡眠
break;
case MS_ALLOW_IN_UPDATE_STA://允许进入升级状态
break;
case MS_UPDATA_DATAS://升级数据帧
break;
case MS_VERIFY_DATAS://校验数据
break;
}
}
}
}//////// 接收处理程序//////////////
/**************************************************************************************
;;函数原型: void CAN_init( void )
;;函数功能: CAN初始化函数can2.0b
;;函数输入: 无
;;函数输出: 无
;;函数返回值: 无
***************************************************************************************/
void CAN_init( void )
{//SJA1000 的初始化
uchar bdata Judge;
do
{// .0=1---reset MODRe,进入复位模式,以便设置相应的寄存器
MODR = 0x09;
Judge = MODR ;
}
while( !(Judge & 0x01) );
CDR = 0x88; // CDR.3=1--时钟关闭, .7=0---basic CAN, .7=1---Peli CAN ,.2-.0 为000,2分频时钟频率为fosc/2
//10k
// BTR0 = 0x1d; //波特率为fosc=12m时brp.5-brp.0 = 011101,波特率为1m,tscl = 5us,tsjw=2*3=0us
// BTR1 = 0xdc; //10总线波特率设定 tseg1=1011(11),tseg2=100(4)位速率=tscl*(tseg1+tseg2+3)=5*20=100us(10k)
// 100K
BTR0 = 0x05; //波特率为fosc=12m时brp.5-brp.0 = 000101,波特率为1m,tscl = 1us,tsjw=2*3=0us
BTR1 = 0x25; //高速BTR1.7 =SAM=0;总线波特率设定 tseg1=0110(6),tseg2=011(3)位速率=tscl*(tseg1+tseg2+3)=1*10=10us(100k)
// 500k
// BTR0 = 0x00; //波特率为fosc=12m时brp.5-brp.0 = 000001,tscl = 1/6us,tsjw=2*3=0us
// BTR1 = 0x36; //10总线波特率设定 tseg1=0101(6),tseg2=010(3)位速率=tscl*(tseg1+tseg2+1)=1*10=10us(500k)
IER = 0x01; //.0=1--接收中断使能; .1=0--关闭发送中断使能
OCR = 0xaa; // 配置输出控制寄存器
CMR = 0x04; //释放接收缓冲器
ACR = ADDRESS; //本节点地址0x04
ACR1 = 0;
ACR2 = 0;
ACR3 = 0; //初始化标示码
AMR = 0;
AMR1 = 0xff;
AMR2 = 0xff;
AMR3 = 0xff; //初始化掩码
do
{//确保退出复位模式
MODR = 0x08; //单滤波
Judge = MODR ;
}
while( Judge & 0x01 );
}
/**************************************************************************************
;;函数原型: void CAN_TXD( uchar ucAddress,uchar ucCmd,uchar ucSubCmd,uchar ucLong,uchar *PData )
;;函数功能: CAN发送函数
;;函数输入: ucAddress地址,,ucCmd命令,ucSubCmd子命令,ucLong长度,*PData数据指针
;;函数输出: 无
;;函数返回值: 无
***************************************************************************************/
void CAN_TXD( uchar ucAddress,uchar ucCmd,uchar ucSubCmd,uchar ucLong,uchar *PData )
{
uchar data Judge;
//初始化数据信息
// EA = 0; //关中断
do
{
Judge = SR;
// LED_RED = 0;//
}
while( Judge & 0x10 ); //SR.4=1 正在接收,等待
do
{
Judge = SR;
// LED_RED = 0;//
}
while(!(Judge & 0x08)); //SR.3=0,发送请求未处理完,等待
do
{
Judge = SR;
// LED_RED = 0;//
}
while(!(Judge & 0x04)); //SR.2=0,发送缓冲器被锁。等待
// LED_RED = !LED_RED;
// LED_GRE = !LED_GRE;//灯闪烁
TBSR0 = 0x80|(ucLong&0x0f); //.7=0扩展帧;.6=0数据帧; .3.2.1.0=数据长度8
TBSR1 = ucAddress; //目的节点地址
TBSR2 = 0; //
TBSR3 = ucCmd; //
TBSR4 = ucSubCmd; //
TBSR5 = *PData++;
TBSR6 = *PData++;
TBSR7 = *PData++;
TBSR8 = *PData++;
TBSR9 = *PData++;
TBSR10 = *PData++;
TBSR11 = *PData++;
TBSR12 = *PData++;
CMR = 0x01;//置位发送请求
// EA = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -