📄 main.c
字号:
/************************************************************************
* 广州周立功单片机发展有限公司 http://www.zlgmcu.com *
************************************************************************/
/************************************************************************
* *
* SJA1000 BasicCAN模式的通讯测试 *
* *
************************************************************************/
/************************************************************************
* *
* 目的: 建立直观的BasicCAN测试平台 *
* 文件名: main.c *
* *
* 模块名: sjanetdemo *
* *
* 目标系统: 任何基于任何兼容8051指令的微处理器同SJA1000组成的CAN系统*
* *
* 应用语言: Keil C51 *
* *
************************************************************************
* 版本 :V1.0 *
* *
************************************************************************
* 广州周立功单片机发展有限公司 保留所有的版权 *
************************************************************************/
#include <reg66x.h>
#include <intrins.h>
#include "time_module.C"
#include "sja_bcanconf.h"
#include "668I2C.H"
#define uchar unsigned char
#define ulong unsigned long
#define uint unsigned int
static uchar data SetSystemBuf[10]; //系统设置数据缓冲区
static uchar data BandRateBuf; //设置总线波特率值缓冲区
static uchar idata EditMsSendCount; //编辑自动发送的频率
static uchar idata EditMsSendSave; //保存自动发送的频率
static uchar idata SendDataCount; //发送数据显示
static uchar bdata CanBusFlag=0; //can标志
sbit CanRcv_Good=CanBusFlag^0; //成功接收标志
sbit CanSend_Good=CanBusFlag^1; //成功发送标志
sbit CanErrFlag=CanBusFlag^2; //can总线错误标志
sbit CanDtOverFlag=CanBusFlag^3; //can总线超载标志
sbit CanWuiFlag=CanBusFlag^4; //can总线唤醒中断
uchar idata DispBuf[4],RcvBuf[4],buf[10];
unsigned char xdata *SJA_BCANAddress;
void CanSend(void);
void InitCPU(void); //初始化函数
// 配置sja1000
uchar Config_SJA(void); //配置sja1000
void CanRcv_Prg(void); //can总线数据接收后处理
void CanSend_Prg(void); //can发送数据
void CanErr_Prg(void); //发现错误后处理
void CanDtOver_Prg(void); //超载处理
void CanWui_Prg(void); //唤醒中断处理
void AutoSendDataToCanBus(void); //自动发送
uchar status,couter1,couter2;
// 外部中断0
/*-------------------------------------------------------------------------------------------
外部中断0处理程序
-------------------------------------------------------------------------------------------*/
void ex0_Val(void) interrupt 0 using 1
{
SJA_BCANAddress=REG_INTERRUPT;
CanBusFlag=*SJA_BCANAddress; //保存sja1000中断标志
}
/*-------------------------------------------------------------------------------------------
main程序
-------------------------------------------------------------------------------------------*/
void main(void)
{
//状态字
for(couter1=0;couter1<250;couter1++)
for(couter2=0;couter2<250;couter2++);
DispBuf[0]=1;
DispBuf[1]=2;
DispBuf[2]=3;
DispBuf[3]=4;
ISendStr(0x50,0x30,DispBuf,4);
for(couter1=0;couter1<250;couter1++)
for(couter2=0;couter2<250;couter2++);
status=Config_SJA(); //配置sja1000
InitCPU();
for(couter1=0;couter1<250;couter1++)
for(couter2=0;couter2<250;couter2++); //初始化,开外中断0和串口中断
if(status!=0)
{
couter1=3;
ISendStr(0x50,0x30,(uchar*)&couter1,1); //配置sja1000出现错误,改DISPBUF[].
}
TimeOut_Start(20); //20*50us=1ms,定时周期1ms
buf[0]=0xaa; //ID10-3
buf[1]=0x08; //数据帧8个有效数据
buf[2]=0x05;
buf[3]=0x05;
buf[4]=0x05;
buf[5]=0x05;
buf[6]=0x05;
buf[7]=0x05;
buf[8]=0x05;
buf[9]=0x05;
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
while(1)
{
if(_testbit_(T0IR)) //1ms时间到
{
AutoSendDataToCanBus();
TimeOut_Start(20); //20*50us=1ms,定时周期1ms
}
for(couter1=0;couter1<250;couter1++)
for(couter2=0;couter2<250;couter2++);
if(_testbit_(CanRcv_Good)) CanRcv_Prg(); //是接收中断标志
if(_testbit_(CanSend_Good)) CanSend_Prg(); //是发送中断标志
if(_testbit_(CanErrFlag)) CanErr_Prg(); //是错误中断标志
if(_testbit_(CanDtOverFlag))CanDtOver_Prg();//是超载中断标志
if(_testbit_(CanWuiFlag)) CanWui_Prg(); //是唤醒中断标志
}
}
static bit CanSendFlag=1; //移位计数
void CanSend(void) //发送键
{
if(!CanSendFlag)
{
BCAN_DATA_WRITE(SetSystemBuf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
}
}
void InitCPU(void)
{
EA =1;
IT0 =1;
EX0 =1;
PX0 =1;
}
uchar Config_SJA(void)
{
uchar data status=0;
Delay_50us(100) ;
TimeOut_Start(20); //设置开始计时、看是否配置超市
BandRateBuf = ByteRate_1000k;
BCAN_ENTER_RETMODEL(); //复位 成功返回1 只是发储复位请求
if(BCAN_CREATE_COMMUNATION()) //检测控制器接口是否正常,发出测试值,失败返回1
{
status = CAN_INTERFACE_ERR; //返回0XFF
couter1=2;
ISendStr(0x50,0x30,(uchar*)&couter1,1); //配置sja1000出现错误,改DISPBUF[].
return(status);
}
if(BCAN_SET_BANDRATE(BandRateBuf)) //初始化系统默认值波特率100kbps,正确返回0
{
status = CAN_INITBTR_ERR ; //返回0XFB
couter1=4;
ISendStr(0x50,0x30,(uchar*)&couter1,1); //配置sja1000出现错误,改DISPBUF[].
return(status);
}
if(BCAN_SET_OBJECT(0xaa,0x00)) //验收代码及接收屏蔽,ACR=0XAA,AMR=0X00,正确返回0
{
status =CAN_INITOBJECT_ERR; //返回0XFC
couter1=5;
ISendStr(0x50,0x30,(uchar*)&couter1,1); //配置sja1000出现错误,改DISPBUF[].
return(status);
}
if(BCAN_SET_OUTCLK(0xaa,0x48)) //输出模式及分频,写入OCR=0xaa,CDR=0X48,正确返回0
{
status =CAN_INITOUTCTL_ERR; //0XFA
couter1=6;
ISendStr(0x50,0x30,(uchar*)&couter1,1); //配置sja1000出现错误,改DISPBUF[].
return(status);
}
if(BCAN_QUIT_RETMODEL()) //结束复位状态,对00H寄存器0位写0
{
status = CAN_QUITRESET_ERR; //0XFD
couter1=7;
ISendStr(0x50,0x30,(uchar*)&couter1,1); //配置sja1000出现错误,改DISPBUF[].
return(status);
}
SJA_BCANAddress=REG_CONTROL;
*SJA_BCANAddress=0X1E; //对00H寄存器写0X1E----对溢出、错误、发送、接收中断使能。
couter1=8;
ISendStr(0x50,0x30,(uchar*)&couter1,1); //配置sja1000出现错误,改DISPBUF[].
for(couter1=0;couter1<250;couter1++)
for(couter2=0;couter2<250;couter2++);
return status; //返回0,表示正常
}
//
void CanRcv_Prg(void)
{
uchar data status ,couter1;
if(BCAN_DATA_RECEIVE(buf)) //接收数据
{
status=0xe9;
DispBuf[0]=9;
ISendStr(0x50,0x30,DispBuf,4);
}
else //接收成功
{
ISendStr(0x50,0x30,buf,4);
if(BCAN_CMD_PRG(0x04)); //释放接收缓冲区
if((buf[1]&0x10)!=0) //是否远程帧
{
switch(buf[1]&0x0f)
{ //远程帧处理
case 0: //请求发送命令字为0c1h的命令帧
buf[1]=(buf[1]&0xe0)|0x06;
buf[2]=0xc1;
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
break;
case 1:
buf[1]=(buf[1]&0xe0)|0x06;
buf[2]=0xc2;
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
break;
case 2:
buf[1]=(buf[1]&0xe0)|0x06;
buf[2]=0xc3;
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
break;
case 3:
buf[1]=(buf[1]&0xe0)|0x06;
buf[2]=0xc4;
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
break;
case 4:
buf[1]=(buf[1]&0xe0)|0x06;
buf[2]=0xc5;
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
break;
case 5:
buf[1]=(buf[1]&0xe0)|0x06;
buf[2]=0xc6;
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
break;
case 6:
case 7:
case 8:
case 9:
default:
break;
}
}
else
{
buf[2]++;
for(couter1=3;couter1<10;couter1++)
buf[couter1]=buf[2];
BCAN_DATA_WRITE(buf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
} //数据帧
}
}
//
void CanSend_Prg(void) //can发送数据
{
}
void CanErr_Prg(void) //发现错误后处理
{
Config_SJA(); //
}
void CanDtOver_Prg(void) //超载处理
{
BCAN_CMD_PRG(COS_CMD);
}
void CanWui_Prg(void) //唤醒中断处理
{
}
void UartRcv_Prg(void) //串口接收到数据处理
{
BCAN_DATA_WRITE(RcvBuf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
}
//自动发送
void AutoSendDataToCanBus(void)
{
/* uchar i;
if((DispBuf[1]==0x05)&&(DispBuf[2]==0x0d))
{
if(EditMsSendCount ==0){
EditMsSendCount = EditMsSendSave;
SendDataCount++;
SetSystemBuf[0]++;
SetSystemBuf[1]=0x08;
for(i=2;i<10;i++)
SetSystemBuf[i]=SendDataCount;
BCAN_DATA_WRITE(SetSystemBuf); //将编辑的数据发送到can总线
BCAN_CMD_PRG(TR_CMD);
DispBuf[3]=SendDataCount>>4;
DispBuf[4]=SendDataCount&0x0f;
}
else{
EditMsSendCount--;
}
}*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -