|
发表于 2003-11-5 22:37:40
|
显示全部楼层
求CANbus的c语言应用
#include "REG52.H"
#include "SJA_BCANCONF.H"
#include "VIIC_C51.h"
#include "ZLG7290.h"
#include "string.h"
#include "intrins.h"
void Init_Cpu(void);
void Init_T0(void);
void Sja_1000_Init(void);
void disp_ok(void);
void disp_err(void);
void delay(unsigned int k);
//void send(unsigned char a);
void display(unsigned char display_buffer[5]);
bit flag_sec=0;
unsigned char data a[5];
unsigned char data send_data[10],rcv_data[10];
unsigned char data databuf,sec_data,send_num=0,second1=0;
unsigned char data Tmod_data;
unsigned char bdata flag_init;
sbitSDA=P1^0;
sbitCLK=P1^1;
unsignedcharcodeled[20]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x89,0x8C};
unsignedchardatadisplay_bit;
unsigned char secd;
sbit rcv_flag=flag_init^0;
sbit send_flag=flag_init^1;
sbit err_flag=flag_init^2;
void main(void)
{
Sja_1000_Init();//initialize Sja1000
Init_T0();//initialize T0
Init_Cpu();//initialize mcu
flag_init=0x00;
while(1)
{
SJA_BCANAdr=REG_STATUS;
flag_init=*SJA_BCANAdr;
//if(rcv_flag)//if there is receive interrupt
{
rcv_flag=0;
BCAN_DATA_RECEIVE(rcv_data);
BCAN_CMD_PRG(0x04);
a[4]=send_num/16;
a[3]=send_num%16;
a[2]=0x0;
a[1]=rcv_data[3]/16;
a[0]=rcv_data[3]%16;
//disp_ok();
}
if(flag_sec)//
{
// if (secd<0x8)
//{
//send_data[0]=0xaa;//Basic can
flag_sec=0;//send data if reach 1 s
second1++;
send_data[0]=0x08;//Pelican
send_data[1]=0xaa;
send_data[2]=0x00;
send_data[3]=secd;
BCAN_DATA_WRITE(send_data);
BCAN_CMD_PRG(0x3);
// }
}
/*if (err_flag)
{
err_flag=0;
disp_err();
Sja_1000_Init();
}*/
display(a);
delay(10);
}
}
void ex0_int(void) interrupt 2 //using 1
{
SJA_BCANAdr=REG_INTERRUPT;
flag_init=*SJA_BCANAdr;
if(send_flag==1) send_num++;
}
void T0_int(void) interrupt 1 using 1
{
static unsigned char ii=0;
TR0=0;
TH0=0x80;
TL0=0x60;
secd++;
//ii++;
if(ii>0x14) {flag_sec=0;}
else {ii++;flag_sec=1;}
TR0=1;
}
void Init_Cpu(void)
{
PX1=1;
IT1=1;
EX1=1;
ET0=1;
EA=1;
sec_data=0x10;
}
void Init_T0(void)
{
Tmod_data=TMOD;
Tmod_data&=0xf0;
Tmod_data|=0x01;
TMOD=Tmod_data;
TH0=0x80;
TL0=0x60;
TR0=1;
sec_data=0x20;
secd=0x00;
}
void Sja_1000_Init(void)
{
bit s;
s=BCAN_CREATE_COMMUNATION();
s=BCAN_ENTER_RETMODEL();
s=BCAN_SET_OUTCLK(0xaa,0xc8);//Pelican
s=BCAN_SET_BANDRATE(0x09);
s=BCAN_SET_OBJECT(0xaa,0xff);
s=BCAN_SET_MOD();
s=BCAN_QUIT_RETMODEL();
SJA_BCANAdr=REG_IER;
*SJA_BCANAdr=0x03;
}
void disp_ok(void)
{
a[0]=0x01;
a[1]=0x0D;
a[2]=0x15;
a[3]=0X15;
a[4]=0X10;
}
void disp_err(void)
{
a[0]=0x18;
a[1]=0x15;
a[2]=0x18;
a[3]=0x18;
a[4]=0x0E;
}
bit BCAN_CREATE_COMMUNATION(void)
{
SJA_BCANAdr=REG_TEST; //访问测试寄存器
*SJA_BCANAdr =0xaa; //写入测试值
if(*SJA_BCANAdr == 0xaa)
{
return 0; //读测试正确
}
else
{
return 1;
}
}
bit BCAN_ENTER_RETMODEL(void)
{
unsigned char TempData;
SJA_BCANAdr = REG_CONTROL; //访问地址指向控制寄存器
TempData= *SJA_BCANAdr; //保存原始值
*SJA_BCANAdr=(TempData|0x01); //置位复位请求
if((*SJA_BCANAdr&0x01) == 1)
{
return 0;
}
else
{
return 1;
}
}
bit BCAN_QUIT_RETMODEL(void)
{
unsigned char TempData;
SJA_BCANAdr = REG_CONTROL; //访问地址指向控制寄存器
TempData = *SJA_BCANAdr; //保存原始值
*SJA_BCANAdr=(TempData&0xfe); //清除复位请求
if((*SJA_BCANAdr&0x01) == 0)
{
return 0; //
}
else
{
return 1; //退出成功
}
}
unsigned charcodeSJA_BTR_CODETAB[]={
0x53,0x2F, // ;20KBPS的预设值
0x87,0xFF, //;40KBPS的预设值
0x47,0x2F, //;50KBPS的预设值
0x83,0xFF, //;80KBPS的预设值
0x43,0x2f, //;100KBPS的预设值
0x03,0x1c, //;125KBPS的预设值
0x81,0xfa, //;200KBPS的预设值
0x01,0x1c, //;250KBPS的预设值
0x80,0xfa, //;400KBPS的预设值
0x00,0x1c, //;500KBPS的预设值
0x80,0xb6, //;666KBPS的预设值
0x00,0x16, //;800KBPS的预设值
0x00,0x14 //;1000KBPS的预设值
};
bit BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)
{
unsigned char BTR0_num,BTR1_num;
BTR0_num = SJA_BTR_CODETAB[CAN_ByteRate*2];
BTR1_num = SJA_BTR_CODETAB[CAN_ByteRate*2+1];
//将波特率的的预设值装入sja1000的总线定时器
SJA_BCANAdr=REG_BTR0; //访问地址指向总线定时寄存器0
*SJA_BCANAdr=BTR0_num; //写入参数
if(*SJA_BCANAdr != BTR0_num)//校验写入值
{
return 1;
}
SJA_BCANAdr=REG_BTR1; //访问地址指向总线定时寄存器0
*SJA_BCANAdr=BTR1_num; //写入参数
if(*SJA_BCANAdr != BTR1_num)//校验写入值
{
return 1;
}
return 0;
}
bit BCAN_SET_OBJECT(unsigned char BCAN_ACR,unsigned char BCAN_AMR)
{
SJA_BCANAdr=REG_TxBuffer5; //访问地址指向验收屏蔽寄存器(AMR)
*SJA_BCANAdr=BCAN_AMR; //写入参数
*(SJA_BCANAdr+1)=BCAN_AMR;
*(SJA_BCANAdr+2)=BCAN_AMR;
*(SJA_BCANAdr+3)=BCAN_AMR;
if(*SJA_BCANAdr != BCAN_AMR) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_TxBuffer1; //访问地址指向验收代码寄存器(ACR)
*SJA_BCANAdr=BCAN_ACR; //写入参数
if(*SJA_BCANAdr != BCAN_ACR) //校验写入值
{
return 1;
}
return 0;
}
bit BCAN_SET_OUTCLK (unsigned char Out_Control,
unsigned char Clock_Out)
{
SJA_BCANAdr=REG_OCR ; //访问地址指向输出控制寄存器
*SJA_BCANAdr=Out_Control; //写入参数
if(*SJA_BCANAdr != Out_Control)//校验写入值
{
return 1;
}
SJA_BCANAdr=REG_CDR; //访问地址指向输出控制寄存器
*SJA_BCANAdr=Clock_Out; //写入参数
if(*SJA_BCANAdr != Clock_Out)//校验写入值
{
return 1;
}
return 0;
}
bit BCAN_DATA_WRITE(unsigned char *SendDataBuf)
{
unsigned char TempCount;
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x08) == 0) //判断上次发送是否完成
{
return1;
}
if((*SJA_BCANAdr&0x04)==0) //判断发送缓冲区是否锁定
{
return1;
}
SJA_BCANAdr = REG_TxBuffer1; //访问地址指向发送缓冲区1
if((SendDataBuf[0]&0x40)==0) //判断RTR,从而得出是数据帧还是远程帧
{
TempCount =(SendDataBuf[0]&0x0f)+3; //输入数据帧
}
else
{
TempCount =3; //远程帧
}
memcpy(SJA_BCANAdr,SendDataBuf,TempCount);
return 0;
}
bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf)
{
unsigned char TempCount;
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x01)==0) //判断报文是否有效
{
return 1;
}
SJA_BCANAdr = REG_RxBuffer1; //访问地址指向接收缓冲区2
if((*SJA_BCANAdr&0x40)==0) //如果是数据帧
{
TempCount=(*SJA_BCANAdr&0x0f)+3; //计算报文中数据的个数
}
else
{
TempCount=3;
}
SJA_BCANAdr = REG_RxBuffer1; //访问地址指向接收缓冲区1
memcpy(RcvDataBuf,SJA_BCANAdr,TempCount);//读取接收缓冲区的报文
return 0;
}
bit BCAN_SET_MOD(void)
{
unsigned char TempData;
SJA_BCANAdr=REG_CONTROL;
TempData= *SJA_BCANAdr;
*SJA_BCANAdr=(TempData|0x04);
if ((*SJA_BCANAdr&0x04)==0)
{
return 1;
}
SJA_BCANAdr=REG_EMLR;
*SJA_BCANAdr=0xc0;
return 0;
}
bit BCAN_CMD_PRG(unsigned char cmd)
{
SJA_BCANAdr=REG_COMMAND; //访问地址指向命令寄存器
*SJA_BCANAdr=cmd; //启动命令字
switch(cmd)
{
/*case TR_CMD: //发送请求命令
return 0;
break;
*/
case SRR_CMD://自接收请求
return0;
break;
case AT_CMD: //夭折发送命令
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x20)==0)//判断是否正在发送
{
return 0;
}
else
{
return 1;
}
break;
case RRB_CMD: //释放接收缓冲区
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x01)==1)//判断是否释放成功
{
return 1;
}
else
{
return 0;
}
break;
case COS_CMD: //清除超载状态
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x02)==0)//判断清除超载是否成功
{
return 0;
}
else
{
return 1;
}
break;
/* case GTS_CMD: //进入睡眠状态命令
return 0;
break;*/
default:
return 1;
break;
}
}
voiddelay(unsigned int k)
{unsignedinti,j;
for(i=0;i<k;i++)
for(j=0;j<100;j++);
}
voiddisplay(unsigned char display_buffer[5])
{
ZLG7290_SendBuf(display_buffer,5);
}
这是一个CAN的自测试程序,加外两个头文件是显示和I2C的头,你自己按自己的要求取舍。我现在也正在做这个方面的东东,以后多交流了。 |
|