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

📄 scan.c

📁 单片机C51环境下的CAN通讯程序
💻 C
字号:
#include<AT89X52.H>                            //加载头文件
#include<SJA_BCANCONF.H>                       //加载变量定义模块
#include<SJA_BCANFUNC.C>                       //加载子程序模块文件
void Init_Cpu(void);
void Init_T2(void);
void Sja_1000_Init(void);
unsigned char data  r_data[25],temp_data[9];   //定义变量
unsigned char data  send_data[10],rcv_data[10];
unsigned char data  sub=0x00;
unsigned char bdata flag_init;
unsigned int  data m=0,n=0,i=0,j=0,sign=0;
sbit rcv_flag=flag_init^0;
sbit err_flag=flag_init^2;
void main(void)
    {
     Sja_1000_Init();                            //初始化CAN控制器SJA1000
     Init_T2();                                  //初始化定时器2
     Init_Cpu();                                 //初始化单片机
     flag_init=0x00;
     while(1)
      {
       if(rcv_flag)
       {
        rcv_flag=0;                            //有接收中断,则单片机进行处理
        BCAN_DATA_RECEIVE(rcv_data);
        BCAN_CMD_PRG(0X04);                    //清空缓冲区
        }
       if(err_flag)                            //err-flag=1表示错误中断
       {
        err_flag=0;
        Sja_1000_Init();
        }
       }
     }

void ex0_int(void) interrupt 0 using 1         //外部中断0服务子程序
     {
      SJA_BCANAdr=REG_INTERRUPT;
      flag_init=*SJA_BCANAdr;                  //查看保存中断源
      }

void Serial_Int(void) interrupt 4  using 2     //串口中断服务子程序
     {
      r_data[n]=SBUF;
      n++;
      SCON=0xd0;
      if(n>=2)
       {
        if(r_data[n-1]==0xdb&&r_data[n-2]!=0xdc)   //判断是否帧起始符
         { 
          n=1;
          r_data[0]=0xdb;
          }
        }
      for(i=14;i<25;i++)                       //判断是否帧结束符
       {
         if(r_data[i]==0xde&&(i-2)==r_data[3])
         {
          m=i;
          i=25;
          }
         else m=0;
         }                         
      if(m==0&&n>=15)                          //发现废帧或干扰帧则丢弃
       {
        n=0;
    	}
      if(m!=0)                                 //校验和
       {
        for(i=1;i<=m-2;i++)
          {
           sub=sub+r_data[i];
           }
        if(sub==r_data[m-1])                   //校验正确则取数据
        {
         for(i=4;i<=m-2;)
         {
          if(r_data[i]==0xdc)
          {
           temp_data[j]=r_data[i+1];
           i=i+2;j++;sign++;
           }
          else
           {
            temp_data[j]=r_data[i];
            i++;j++;sign++;
            }
          if(sign==3)
           {
            send_data[0]=0xaa;
            send_data[1]=0x03;
            send_data[2]=temp_data[0];
            send_data[3]=temp_data[1];
            send_data[4]=temp_data[2];
            BCAN_DATA_WRITE(send_data);
            BCAN_CMD_PRG(0x01);                //调发送请求
            }
          if(sign==6)
           {
            send_data[0]=0xaa;
            send_data[1]=0x03;
            send_data[2]=temp_data[3];
            send_data[3]=temp_data[4];
            send_data[4]=temp_data[5];
            BCAN_DATA_WRITE(send_data);
            BCAN_CMD_PRG(0x01);                //调发送请求
            }
          if(sign==9)
           {
            send_data[0]=0xaa;
            send_data[1]=0x03;
            send_data[2]=temp_data[6];
            send_data[3]=temp_data[7];
            send_data[4]=temp_data[8];
            BCAN_DATA_WRITE(send_data);
            BCAN_CMD_PRG(0x01);                //调发送请求 
            i=25;
            }
          }
        } 
        for(i=0;i<25;i++)                      //正确帧发送完毕或遇到错误帧均清零各参数
          {
            r_data[i]=0;
           }   
         sub=0x00;
         n=0;
         j=0;
         sign=0;            
        }
      }

void Init_Cpu(void)                            //开中断
     {
      EA=1;
      ES=1;
      EX0=1;
      }

void Init_T2(void)                             //初始化串口和定时器2
     {   
/*      SCON =  0x50;     //串口工作方式1
      TMOD |= 0x20;     //T1,初值自动重装
      TH1  =  0xe8;     //波特率9600bps  @ 11,0592M
      TL1  =  0xe8; 
      TR1  =  1;        //开始计数
      IE  |=  0x90;     //开放串口中断              */
     
      SCON=0xd0;        //串口工作方式3
      T2CON=0x34;       //定时器2设为波特率发生器模式
      RCAP2H=0xfe;      //波特率1200bps,晶振11.0592MHz 
      RCAP2L=0xe0;
      TH2=0xfe;
      TL2=0xe0;
      TR2=1;            //定时器2开中断       
      }

void Sja_1000_Init(void)                       //CAN控制器初始化子程序
     {
      BCAN_ENTER_RETMODEL();                   //申请进入复位状态
      BCAN_SET_BANDRATE(0x0e);                 //设置波特率为1000Kb/s
      BCAN_SET_OBJECT(0xaa,0xff);              //设置ACR AMR
      BCAN_SET_OUTCLK(0xaa,0x48);              //设置输出方式禁止clkout
      BCAN_QUIT_RETMODEL();                    //退出复位状态
      SJA_BCANAdr=REG_CONTROL;                 //送控制寄存器地址
      *SJA_BCANAdr|=0x1e;                      //开放错误中断和接收中断
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -