📄 stepbystep.c
字号:
#include <Reg52.h>
#include <SJA1000.h>
void init_port();//初始开I/O口
void init_cpu();
void INIT_SJA1000();
void INIT_SJA1000_CYC();
void MCU_SENT_TO_CAN();
void SJA1000_SEND();
void SJA1000_RECEIVE();
void SetBaund();
void URT_SENT(); //URT SENT
//void URT_SENDIN();
void SJA1000_RECEIVE();
//void SJA1000_RECEIVE_IN_INTERR();
void checklink();
//void checkbound();
unsigned char wait_data();
//void changebound();
void delay();
sbit S_MODE=P1^1;
sbit LED1=P1^2;
sbit LED2=P1^3;
unsigned char CAN_RXD_BUF[13];
unsigned char CAN_TXD_BUF[13];
unsigned char r_buf[15]; //URT RECEIVE BUFFER
unsigned char t_buf[15]; //URT SEND BUFFER
unsigned char temp,can_temp,i,m,count_time,can_length,j,k,l,receive_count,BTR0_NUM,BTR1_NUM;
bit URT_RECEIVE=0,link=0,UTR_SENDING=0,URT_SENDING=0;
bit receive_err=0,receive_succeed=0,setbound=0;
bit send_comply=0,baund=0;
void main(void)
{
init_cpu();
init_port();
TJA1050_CLOSE;
INIT_SJA1000();
TJA1050_WORK;
SetBaund();
EX0=1;
/* BTR0_NUM=BTR0_500Kbps;
BTR1_NUM=BTR1_500Kbps; */
ES=1;
i=0;
REN=1;
m=0;
IT0=1;
EA=1;
while(1)
{
LED1=0;
while(!wait_data());
LED1=1;
checklink();
// checkbound();
if(link)
{
URT_SENT();
LED1=0;
for(i=0;i<14;i++)
{
r_buf[i]=0;
}
i=0;
LED1=1;
goto loop;
}
/* else if(baund)
{
URT_SENT();
BTR0_NUM=r_buf[5];
BTR1_NUM=r_buf[6];
changebound();
for(i=0;i<14;i++)
{
r_buf[i]=0;
}
i=0;
P2=0x69;
goto loop;
} */
else
{
LED2=0;
EX0=1;
INIT_SJA1000_CYC();
TJA1050_WORK;
receive_err=0;
MCU_SENT_TO_CAN();
REN=0;
ES=0;
EA=1;
LED2=0;
while(!receive_err);
receive_err=0;
SJA1000_RECEIVE();
EA=0;
if(receive_succeed)
{
r_buf[0]=can_length+1;
for(i=0;i<can_length;i++)
{
r_buf[i+1]=CAN_RXD_BUF[i];
}
/* for(i=0;i<14;i++)
{
P2=r_buf[i];
for(j=0;j<255;j++)
for(k=0;k<255;k++)
for(l=0;l<4;l++)
;
} */
ES=1;
i=0;
REN=1;
m=0;
IT0=1;
EA=1;
URT_SENT();
}
}
loop: link=0;
receive_err=0;
// init_cpu();
// init_port();
SetBaund();
EX0=1;
ES=1;
REN=1;
IT0=1;
EA=1;
TJA1050_CLOSE;
}
}
void init_port()
{
P0=0x00;
P1=0xff;
LED1=0;
LED2=0;
delay();
LED1=1;
LED2=1;
// P2=0xFE;
}
void delay()
{
unsigned char i,j,k;
for(i=0;i<255;i++)
for(j=0;j<255;j++)
for(k=0;k<5;k++)
;;
}
void init_cpu()
{
ES=0;
EX0=1;
TMOD=0x00;
REN=0;
IT0=1;
TL0=0;
TH0=0;
TR0=0;
EA=0;
}
void INIT_SJA1000() /*initSJA1000*/
{
SJA1000_ADDRESS=SJA1000_MODEL; //指向模式寄存器
*SJA1000_ADDRESS=SJA1000_RESET_MODEL; //进入复位模式
while(!(*SJA1000_ADDRESS&SJA1000_RESET_MODEL)); //等待进入复位模式
SJA1000_ADDRESS=SJA1000_CLOCKDIR; //指向时钟分频寄存器
*SJA1000_ADDRESS=SJA1000_CDR_COMMAND; //使用Peli CAN模式,CLOCK使用2分频输出
SJA1000_ADDRESS=SJA1000_ENINTERR; //指向中断使能寄存器
*SJA1000_ADDRESS=SJA1000_IER_COMMAND; //开放接收,数据溢出,错误报警中断
SJA1000_ADDRESS=SJA1000_OUTCONTR; //指向输出控制寄存器
*SJA1000_ADDRESS=SJA1000_OUT_COMMAND; //正常输出模式
SJA1000_ADDRESS=SJA1000_BUSTIME0; //指向总线定时0寄存器
*SJA1000_ADDRESS=0x01; //选择500Kbps
SJA1000_ADDRESS=SJA1000_BUSTIME1; //指向总线定时1寄存器
*SJA1000_ADDRESS=0x05; //选择500Kbps
SJA1000_ADDRESS=SJA1000_RBSA; //指向RX缓冲区起始地址寄存器
*SJA1000_ADDRESS=SJA1000_FIFO_ADD; //接收缓冲区FIFO起始为内部RAM的0地址
SJA1000_ADDRESS=SJA1000_AMRRX0; //指向验收屏蔽寄存器,所有位均参加验收
*SJA1000_ADDRESS=0x18;
SJA1000_ADDRESS=SJA1000_AMRRX1;
*SJA1000_ADDRESS=0x2f;
SJA1000_ADDRESS=SJA1000_AMRRX2;
*SJA1000_ADDRESS=AMR_CODE2;
SJA1000_ADDRESS=SJA1000_AMRRX3;
*SJA1000_ADDRESS=AMR_CODE3;
SJA1000_ADDRESS=SJA1000_ACRRX0; //指向验收代码寄存器,送ID码
*SJA1000_ADDRESS=0xfd;
SJA1000_ADDRESS=SJA1000_ACRRX1;
*SJA1000_ADDRESS=0x00;
SJA1000_ADDRESS=SJA1000_ACRRX2;
*SJA1000_ADDRESS=ACR_ID2;
SJA1000_ADDRESS=SJA1000_ACRRX3;
*SJA1000_ADDRESS=ACR_ID3;
SJA1000_ADDRESS=SJA1000_TX_ERR; //指向发送错误寄存器
*SJA1000_ADDRESS=SJA1000_CLEAR_TX_ERR; //清除错误
SJA1000_ADDRESS=SJA1000_RX_ERR; //指向发送错误寄存器
*SJA1000_ADDRESS=SJA1000_CLEAR_TX_ERR; //清除发送错误
SJA1000_ADDRESS=SJA1000_ALC; //指向仲裁丢失捕捉寄存器
temp=*SJA1000_ADDRESS; //通过读取清除
SJA1000_ADDRESS=SJA1000_ECC; //指向错误代码捕捉寄存器
temp=*SJA1000_ADDRESS; //通过读取清除
SJA1000_ADDRESS=SJA1000_MODEL; //指向模式寄存器
*SJA1000_ADDRESS=SJA1000_WORK_MODEL; //设置双滤波接收,进入工作模式
while(*SJA1000_ADDRESS&SJA1000_RESET_MODEL); //等待进入工作模式
}
void SJA1000_SEND()
{
LED2=0;;
SJA1000_ADDRESS=SJA1000_STATE; //指向状态寄存器
temp=*SJA1000_ADDRESS;
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(temp&SJA1000_RECEIVING); //如正在接收,则等待
do
{
temp=*SJA1000_ADDRESS; //读出当前状态
}while(!(temp&SJA1000_SENT_OVER)); //如正在发送,则等待
do
{
SJA1000_ADDRESS=SJA1000_STATE;
temp=*SJA1000_ADDRESS; //读出当前状态
}
while(!(temp&SJA1000_SENT_LOCK)); //如发送缓冲区被锁定,则等待释放
SJA1000_ADDRESS=SJA1000_TXBUF;
for(j=0;j<11;j++) //发送到CAN缓冲区
{
*(SJA1000_ADDRESS+j)=CAN_TXD_BUF[j];
}
SJA1000_ADDRESS=SJA1000_COMMAND; //指向命令寄存器
*SJA1000_ADDRESS=SJA1000_SENT_COMMAND; //发送请求命令
LED2=1;
}
void sja1000_receiving () interrupt 0 using 0
{
receive_err=1;
// SJA1000_RECEIVE_IN_INTERR();
return;
}
void SJA1000_RECEIVE()
{
unsigned char data can_temp,j,k,Length;
bit FF,RTR;
receive_err=0;
LED2=0;;
SJA1000_ADDRESS=SJA1000_STATE; //指向状态寄存器
can_temp=*SJA1000_ADDRESS; //读状态
if(can_temp&SJA1000_BUS_ERR) //0xc3 //检查总线状态是否有错
{
if(can_temp&SJA1000_BUS_CLOSE) //0x80 //检查是否是总线关闭状态
{
SJA1000_ADDRESS=SJA1000_INTERR; //读中断寄存器,清除总线错误中断
can_temp=*SJA1000_ADDRESS;
for(k=0;k<255;k++)
for(j=0;j<255;j++)
;
;
k=0;
j=0;
SJA1000_ADDRESS=SJA1000_MODEL; //指向模式寄存器
*SJA1000_ADDRESS=SJA1000_WORK_MODEL; //设置双滤波接收,进入工作模式
while(*SJA1000_ADDRESS&SJA1000_RESET_MODEL); //等待进入工作模式
}
else
{
SJA1000_ADDRESS=SJA1000_INTERR; //读中断寄存器,检查中断类型
can_temp=*SJA1000_ADDRESS;
if(can_temp&SJA1000_DATA_OVER_INTERR) //0x08 //检查是否是数据溢出中断
{
SJA1000_ADDRESS=SJA1000_COMMAND; //指向命令寄存器
*SJA1000_ADDRESS=SJA1000_CLEAR_DATA_OVER; //清除数据溢出
}
else
{
if(can_temp&SJA1000_RI_INTERR) //检查是否是接收中断
{
SJA1000_ADDRESS=SJA1000_RXBUF; //指向接收数据寄存器首址
CAN_RXD_BUF[0]=*SJA1000_ADDRESS; //读RX帧信息
FF=CAN_RXD_BUF[0]&0x80; //格式
RTR=CAN_RXD_BUF[0]&0x40; //远程?
Length=CAN_RXD_BUF[0]&0x0F; //长度
if(Length>0x08)
Length=0x08;
SJA1000_ADDRESS++;
CAN_RXD_BUF[1]=*SJA1000_ADDRESS;
SJA1000_ADDRESS++;
CAN_RXD_BUF[2]=*SJA1000_ADDRESS;
if(FF)
{
SJA1000_ADDRESS++;
CAN_RXD_BUF[3]=*SJA1000_ADDRESS;
SJA1000_ADDRESS++;
CAN_RXD_BUF[4]=*SJA1000_ADDRESS;
}
for(i=0;i<Length;i++)
{
if(FF)
{
SJA1000_ADDRESS++;
CAN_RXD_BUF[i+5]=*SJA1000_ADDRESS;
}
else
{
SJA1000_ADDRESS++;
CAN_RXD_BUF[i+3]=*SJA1000_ADDRESS;
}
}
if(FF)
{
can_length=Length+5;
}
else
{
can_length=Length+3;
}
SJA1000_ADDRESS=SJA1000_COMMAND; //指向命令寄存器
*SJA1000_ADDRESS=SJA1000_RELEASE_FIFO; //释放接收缓冲器
receive_succeed=1;
if(RTR)
receive_succeed=1; //置接收成功标志
}
else
{
receive_succeed=0;
SJA1000_ADDRESS=SJA1000_COMMAND; //指向命令寄存器
*SJA1000_ADDRESS=SJA1000_RELEASE_FIFO; //释放接收缓冲区
SJA1000_ADDRESS=SJA1000_ALC; //指向仲裁丢失寄存器
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -