⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 采用C语言编写
💻 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 + -