📄 main.c
字号:
#include "STC12C5410AD.H"
#include "sja_bcanconf.h"
#include <intrins.h>
#include <string.h>
#define uchar unsigned char
#define nop _nop_()
//////////模拟地址总线复用///////////////
uchar sja_read(uchar addr);
void sja_write(uchar addr,uchar dat);
///
void InitCPU(void); //初始化函数
void InitUart(void);
void Init_Timer(void);
/// ///////////PPT.C子程序//////////// 10月12号加////////////
//extern void flash();
extern void Init_sys(uchar **ROM_BUF);
extern void roral(uchar *DATA_BUF,uchar **ROM_DAT);
extern void delay(uchar t);
extern uchar temp_send(uchar *ROM_a);
extern uchar dis();
void receive_prc();
////////////////////////////////////////////////////////////
//void Exe_Scon(uchar cmd);
bit UartRcvGood=0;//串口一帧数据接受好标志
bit CanRcvGood=0;//CAN数据一帧接受好标志
bit CanSendSucc=0;//CAN数据一帧发送好标志
bit Time_Out=0; //时间溢出标志位
uchar data Send_count=0; //发送计数
uchar data CanRcvCount=0; //计数接受到的数据帧
uchar data SJA_BCAN;
unsigned char idata RcvBuf[10]={0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50}; //接收数据缓冲区
unsigned char idata SendBuf[10]={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55}; //发送数据缓冲区
uchar data TimerCount=0; //用于计算进入定时中断的次数
unsigned char data boardaddr;
uchar Config_SJA(void); //配置sja1000
void CanRcv_Prg(void); //can总线数据接收后处理
void CanErr_Prg(void); //发现错误后处理
void CanDtOver_Prg(void); //超载处理
void CanWui_Prg(void); //唤醒中断处理
//void CantoSpi(void); //CAN正确接收到数据后通过Spi接口发送出去
bit CanSend_Prg(void); //can发送数据
bit BCAN_INIT( unsigned char BTR0_num,
unsigned char BTR1_num,
unsigned char BCAN_ACR,
unsigned char BCAN_AMR,
unsigned char BCAN_ORC,
unsigned char BCAN_CDR
) ;
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总线唤醒中断
sbit status=CanBusFlag^5;
sbit sja_ale=P3^4;
sbit sja_rd =P3^1;
sbit sja_wr =P3^0;
sbit sja_cs =P0^3;
void Delay_200us(unsigned int _time200us);
/*-------------------------------------------------------------------------------------------
外部中断0处理程序
-------------------------------------------------------------------------------------------*/
void ex0_Interrpt(void) interrupt 0 using 1
{
//保存sja1000中断标志
CanBusFlag=sja_read(REG_INTERRUPT);
}
/*-------------------------------------------------------------------------------------------
main程序
-------------------------------------------------------------------------------------------*/
//sbit rest_sja=P3^7;
void main(void)
{ //板上地址
uchar i=0,j;
for(j=0;j<4;j++)
{
for(i=0;i<250;i++)
{
delay(250);
delay(250);
delay(250);
delay(250);
}
for(i=0;i<250;i++)
{
delay(250);
delay(250);
delay(250);
delay(250);
}
}
//InitCPU(); //CPU初始化,开放中断和串口
//定时器0初始化
Send_count =0; //发送数据计数器
CanRcvCount=0;
boardaddr=0x01; //板上地址
status=0;
while(1)P1=dis()&0xff;
status=BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41) ;
while(1)
{
if(status!=0)
{
status=BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41) ;
i++;
}
else
break;//初始化成功,则跳出
if(i==4&&status!=0)
{
P1=~0x0b; //初始化SJA1000不成功,则用LED显示出错,2006年10月1日晚21点16分
while(1);
}
}
if(status!=0)
{
while(1);
}
InitCPU();
EA=1;
CanSend_Prg();
while(1)
{
//roral(SendBuf+2,ROM_a);
if(_testbit_(CanRcv_Good)) CanRcv_Prg(); //是接收中断标志//wan2006年3月10日,需要修改
if(_testbit_(CanSend_Good)) CanSend_Prg(); //是发送中断标志//2006年3月20日注释,因为接点是在接受到数据之后根据数据来做决定是否发送CAN数据
if(_testbit_(CanErrFlag)) CanErr_Prg(); //是错误中断标志
if(_testbit_(CanDtOverFlag))CanDtOver_Prg();//是超载中断标志接受程序中已有超载处理
if(_testbit_(CanWuiFlag)) CanWui_Prg(); //是唤醒中断标志
// if(CanRcvGood==1) CantoSpi(); //把接收到的数据发送到DSP
//receive_prc();
}
}
void InitCPU(void)
{
//EA =0;
IT0 =1; //边缘响应中断0
EX0 =1; //允许外部中断0
PX0 =1;
//外部中断0优先级为高
EA=0;
}
/*-------------------------------------------------------------------------------------------
/*用定时中断实现延时300ms
/*用于系统时间定时
说明: 在使用时要注意先要初始化定时器0同时要注意允许计数
-------------------------------------------------------------------------------------------*/
void Timer_iterrupt(void) interrupt 1 using 2
{
TimerCount++;
if(TimerCount==250) //延时50ms
{
TR0 = 0;
TimerCount=0;
Time_Out=1;
}
}
void Init_Timer(void)
{
TMOD |= 0x02; //T0,初值自动重装
TH0 = 18; //设置定时初值
TL0 = 72; //每发生一次中断,时间为200us
TimerCount=0;
IE |= 0x02;
}
void CanRcv_Prg(void)
{
unsigned char TempCount,i;
//访问地址指向状态寄存器
//判断报文是否有效
if((sja_read(SJA_BCAN)&0x01)==0x01)
{ // 如果报文有效,
//访问地址指向接收缓冲区2
//如果是数据帧
if((sja_read(REG_RxBuffer2)&0x10)==0)
TempCount=(sja_read(REG_RxBuffer2)&0x0f)+2; //计算报文中数据的个数
else
TempCount=2;
//访问地址指向接收缓冲区1
// 读取接收缓冲区的报文
for(i=0;i<TempCount;i++)
{
SendBuf[i]=sja_read(REG_RxBuffer1+i);
delay(50);
}
//SJA_BCAN =REG_COMMAND;
// *SJA_BCAN=0x04; //释放接收缓冲区
sja_write(REG_COMMAND,0x04);
//这里要给发送节点回一个远程应答帧
}
}
bit CanSend_Prg(void) //can发送数据,写于2006年3月13日晚
{
char data temp1,i;
//统计远程帧发送数
if(sja_read(REG_STATUS)&0x80!=0x0)//判定总线是否关闭
{
P1=~0x01; //如果进入循环,则总线处于关闭状态。
return 1;
}
if(sja_read(REG_STATUS)&0x40!=0x0)//判定是否处于出错状态
{
P1=~0X02; //如果进入循环,则处于出错状态
return 1;
}
if(sja_read(REG_STATUS)&0x30!=0x0) //CAN总线处于发送状态或接收状态,这时总线不为空闲状态。
{
TR0=1;
while((sja_read(REG_STATUS)&0x30!=0x0)&&(TR0!=0))//延时等待
{
P1=~0x03;
}
//出了上面这个循环,我要判断是怎么出了这个循环
if((sja_read(REG_STATUS) & 0x20)== 0x20)//经过一段时间延时,还处于发送状态,则肯定有问题。&&(TR0==0)
{
BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41) ;
//return 1;
}
else //这时已不处于发送状态,要把延时给关掉
{
TR0=0;
TH0 = 72; //设置定时初值
TL0 = 72;
TimerCount=0;
CanSendSucc=0;
}
}
while((sja_read(REG_STATUS)&0x04)==0x0) //判定发送缓冲区是否为空
{ //等待发送缓冲器为空
sja_write(REG_CONTROL,0x01);
delay(200);
while((sja_read(REG_CONTROL)&0x01)!=0x1)
{
sja_write(REG_CONTROL,0x01);
delay(200);
}
BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41) ;
}
//**************************测试用
RcvBuf[0]=0x01;
RcvBuf[1]=0x8;
RcvBuf[2]=0x6;
RcvBuf[3]=0x7;
RcvBuf[4]=0x8;
RcvBuf[5]=0x9;
RcvBuf[6]=0xa;
RcvBuf[7]=0xb;
RcvBuf[8]=0xc;
RcvBuf[9]=0xd;
SJA_BCAN=REG_TxBuffer1;
if((RcvBuf[1]&0x10)!=0x10)
temp1=(RcvBuf[1]&0x0f)+2;
else
temp1=2;
for(i=0;i<temp1;i++)
{
sja_write(SJA_BCAN++,RcvBuf[i]);
}
sja_write(REG_COMMAND,0x01);
delay(50);
i=sja_read(REG_STATUS);
TR0=0;
CanSendSucc=0;
for(i=0;i<100;i++)
{
delay(50);
if((sja_read(REG_STATUS) & 0x20)!=0x20)
break;
}
TH0 = 18; //设置定时初值
TL0 = 72;
TimerCount=0;
Time_Out=0;
if((sja_read(REG_STATUS) & 0x20)!=0x20)
{
Time_Out=1; //发送时间溢出,
//启动定时器,为接受CAN总线上的信息帧准备?
sja_write(REG_CONTROL,0x01);
delay(200);
while((sja_read(REG_CONTROL)&0x01)!=0x1)
{
sja_write(REG_CONTROL,0x01);
delay(200);
}
BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41) ;
while(1)
; //测试用,到时候要去掉
return 1;//就是根据这个信息来判断发送是否有问题 。
}
return 0;
}
bit BCAN_INIT( unsigned char BTR0_num,
unsigned char BTR1_num,
unsigned char BCAN_ACR,
unsigned char BCAN_AMR,
unsigned char BCAN_ORC,
unsigned char BCAN_CDR
)
{
unsigned char TempData;//BTR0_num,BTR1_num;
// SJA_BCAN=REG_TEST; //访问测试寄存器
sja_write(REG_TEST,0xaa);
delay(50); //写入测试值
if(sja_read(REG_TEST)!=0xaa)
{
return 1; //读测试正确
}
//访问地址指向控制寄存器
//保存原始值
TempData =sja_read(REG_CONTROL);
delay(50); //置位复位请求
sja_write(REG_CONTROL,TempData|0x01);
delay(200);
sja_write(REG_CONTROL,TempData|0x01);
delay(200);
if((sja_read(REG_CONTROL)&0x01) != 1)
{
return 1;
}
sja_write(REG_BTR0,BTR0_num);
delay(100);
if(sja_read(REG_BTR0)!= BTR0_num) //校验写入值
{
return 1;
}
sja_write(REG_BTR1,BTR1_num); delay(50);
if(sja_read(REG_BTR1)!= BTR1_num) //校验写入值
{
return 1;
}
sja_write(REG_ACR,BCAN_ACR);
delay(50);
if(sja_read(REG_ACR)!= BCAN_ACR) //校验写入值
{
return 1;
}
sja_write(REG_AMR,BCAN_AMR);delay(50);
if(sja_read(REG_AMR) != BCAN_AMR) //校验写入值
{
return 1;
}
sja_write(REG_OCR,BCAN_ORC);delay(50);
if(sja_read(REG_OCR) !=BCAN_ORC)//校验写入值
{
return 1;
}
sja_write(REG_CDR,BCAN_CDR);
delay(200);
sja_write(REG_CONTROL,0x1e);
delay(200);
if((sja_read(REG_CONTROL)&0x01) != 0)
{
return 1; //退出成功
}
return 0;
}
void CanErr_Prg(void)
{
BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41);
}
void CanDtOver_Prg(void)
{
BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41);
}
void CanWui_Prg(void)
{
BCAN_INIT(0x53,0xa3,boardaddr,0x0,0xaa,0x41);
}
void sja_write(uchar addr,uchar dat)
{
sja_ale=0;
sja_wr=1;
sja_rd=1;
sja_cs=1;
sja_ale=1;
P2=addr;
sja_ale=0;
sja_cs=0;
nop;
//nop;
P2=dat;
nop;
//nop;
sja_wr=0;
//nop;
nop;
nop;
sja_wr=1;
sja_cs=1;
//sja_
}
uchar sja_read(uchar addr)
{
uchar t;
sja_ale=0;
sja_wr=1;
sja_rd=1;
sja_cs=1;
sja_ale=1;
//nop;
P2=addr;
//nop;
sja_ale=0;
nop;
P2=0XFF;
nop;
sja_cs=0;
sja_rd=0;
nop;
//nop;
nop;
t=P2;
nop;
nop;
sja_rd=1;
sja_cs=1;
return t;
}
//////////////////
void receive_prc() //接收处理
{
temperature_level=RcvBuf[2];
mute=RcvBuf[3]&0x80;
low_cut=RcvBuf[3]&0x40;
crossover=RcvBuf[3]&0x20;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -