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

📄 basiccan_final1.c

📁 设计了一个基于51单片机的CAN节点
💻 C
📖 第 1 页 / 共 3 页
字号:

	if((shiwei!=0)|((shiwei==0)&((qianwei!=0)|(baiwei!=0))))
	{
   		P14=0;
		P15=1;
		P17=1;
		P0=~dispbitcode[shiwei];
    	P17=0;
    	delay(5);
	}

   	P14=1;
	P15=1;
	P17=1;
	P0=~dispbitcode[gewei];
    P17=0;
    delay(5);
	
	EA=1;
}


/*void u2_to_u10(uchar change_data)
{
	dispbuf[3]=change_data/1000;//将change_data的个位,十位,百位,千位分别存放在SetSystemBuf中
	change_data=change_data%1000;
	dispbuf[2]=change_data/100;
	change_data=change_data%100;
	dispbuf[1]=change_data/10;
	dispbuf[0]=change_data%10;
}*/

//初始化SJA_1000,设置相关参数
 uchar  SJA_1000_Init(void)
{ 
  uchar data status=0;
  delay(10);

  BandRateBuf = ByteRate_1000k;//默认波特率为1000k

  BCAN_ENTER_RETMODEL();//使CAN控制器进入复位工作模式

  if(BCAN_CREATE_COMMUNATION())//检测CAN控制器的接口是否正常,若返回1,则不正常
    {
    status = CAN_INTERFACE_ERR;
    return(status);
  }

  if(BCAN_SET_BANDRATE(BandRateBuf))//初始化系统默认值波特率1000kbps,若返回1,表示波特率未能设置
  {
  	status=CAN_INITBTR_ERR;
	return(status);
  }

  if(BCAN_SET_OBJECT(0xaa,0xff))//设置检收代码寄存器(ACR)、接收屏蔽寄存器(AMR)的参数
                                //0xff表示检收代码寄存器所有的位对检收滤波器是“无关的”
  {
    status =CAN_INITOBJECT_ERR;
    return(status);
  }

//输出控制寄存器OCR=0xaa表示采用正常输出模式,TX1悬空,时钟分频寄存器CDR=0x48表示采用BasicCAN模式,CBP被置位,
//只有RX0起作用。CLOCK OFF置1使外部CLKOUT引脚失效 
  if(BCAN_SET_OUTCLK(0xaa,0x48))//设置SJA1000的输出模式和时钟分频
  {
    status =CAN_INITOUTCTL_ERR;
    return(status);
  }

  if(BCAN_QUIT_RETMODEL())//使CAN控制器退出复位工作模式
  {
    status = CAN_QUITRESET_ERR;
    return(status);
  }
  
  SJA_BCANAdr=REG_CONTROL;//设置控制寄存器,在操作模式进行
  *SJA_BCANAdr=0X1E;//开启溢出中断、错误中断、发生和接收中断
  
  return  status; 
}


      
void main()
{	
    delay(100);
    
	IT0=0;//外中断0为电平触发方式
	      
    TMOD=0x60;//计数器1以工作方式2工作,以TR1启动定时器
	TH1=0xFF;
	TL1=0xFF;//一次计数则中断(T1负跳变时计一次)
	TR1=1;//启动计数
	
	ET1=1;//允许计数器1中断
	
	EX0=1;//允许外中断0中断

	EA=1;//中断总允许
    
    if(SJA_1000_Init()==0)
        dispbuf=0;//表示初始化成功
    else
        dispbuf=1;
	 
	while(1)
	{
		display(dispbuf);
	}	 
      	 				   
}



//该函数现实键盘扫描,去抖动,实现要求功能
void keyboard() interrupt 3 using 0
{
	static uchar num_send=0;//定义一个静态变量,并初始化为0,用于计算S1键按下的次数,即要发送的数据
	static uchar ADC_send=0;
	static uchar num_rate=0x0D;//用于记录S3按下的次数,从而智能的选择波特率
	uchar key_code;//用于存储所按下的键值
	ET1=0;//关闭计数器1中断
	delay(20);//去抖动,等待20ms
	if(!T1)
	{
		key_code=P1&0x0F;//读取P1口的前4位,即P10-P13
		switch(key_code)
		{
			case 0x0E://按下S1键的情况:设置发送数据,每按一次加1
//				EX0=0;//关闭外中断0
				num_send++;				
				dispbuf=num_send;//将num_send转化为可以显示的十进制数,并存入SetSystemBuf中
				break;

				case 0x0D://按下S2键的情况:将设置好的数据发送出去
				//EX1=0;//关闭外中断1
				send_data[0]=0x01;//标识符为1010 1010 000
				send_data[1]=0x04;
				send_data[2]=num_send;
				BCAN_DATA_WRITE(send_data);//将数据存放到REG_TxBuffer
				delay(10);
				BCAN_CMD_PRG(TR_CMD);//发送数据到CAN总线上,成功是否在中断判断
				dispbuf=num_send;
				num_send=0;//复位发送的数据
//				EX0=1;//开外中断0
				break;

				case 0x0B://按下S3键的情况:设置波特率
				//EX1=0;//关闭外中断1
				num_rate--;
				BCAN_ENTER_RETMODEL();//使CAN控制器进入复位工作模式
				BCAN_SET_BANDRATE(num_rate);//设置波特率
				dispbuf=band_rate[num_rate];
				BCAN_QUIT_RETMODEL();//使CAN控制器退出复位工作模式				
				if(!num_rate)
				num_rate=0x0D;
				break;
				
				case 0x07://按下S4的情况:开始接收AD的数据并显示
				OE=0;
				ST=0;
				ST=1;
				ST=0;
				OE=1;
				dispbuf=P0;
				ADC_send=P0;
				OE=0;

			   	send_data[0]=0x01;//标识符为1010 1010 000
				send_data[1]=0x21;
				send_data[2]=ADC_send;
				BCAN_DATA_WRITE(send_data);//将数据存放到REG_TxBuffer
				delay(10);
				BCAN_CMD_PRG(TR_CMD);//发送数据到CAN总线上,成功是否在中断判断

//				dispbuf=7;//显示P,表示推出复位
				//EX1=1;//开外中断1
				break;
			default:
				break;							
		}	
	}
	ET1=1;//开计数器中断					
}

//该中断实现接收显示,并当出现错误是给予显示:
void SJA_int() interrupt 0 using 3
{
	uchar reg_int; //存放中断寄存器的数据
	uchar rcv_buf[10];//接收数据存储
	EX0=0;//关闭外中断0
	SJA_BCANAdr=REG_INTERRUPT;//读取中断寄存器的数据
	reg_int=*SJA_BCANAdr;

	if(reg_int&0x01) //接收中断处理
	{
	 	BCAN_DATA_RECEIVE(rcv_buf);
	 	
		dispbuf=rcv_buf[2];//显示数据
//		display();
		//SetSystemBuf[1]=rcv_buf[3];
		//SetSystemBuf[2]=rcv_buf[4];
		//SetSystemBuf[3]=rcv_buf[5];
		BCAN_CMD_PRG(RRB_CMD);//释放接收缓存区
		P14=1;
		P15=1;
		P17=1;
		P0=~dispbitcode[10];
    	P17=0;
    	delay(500);
	}
    else if(reg_int & 0x02)
    {
    P14=1;
	P15=1;
	P17=1;
	P0=~dispbitcode[17];
    P17=0;
    delay(500);
//	dispbuf=17;//若是发送中断,则显示H,表示发送成功
    }

    else if(reg_int & 0x04)
    {
    	P14=1;
		P15=1;
		P17=1;
		P0=~dispbitcode[16];
	   	P17=0;
    	delay(500);   
		//dispbuf=16;//若是错误中断,则显示-,表示有错误产生
    }

    else if(reg_int & 0x08)
    {
        P14=1;
		P15=1;
		P17=1;
		P0=~dispbitcode[19];
    	P17=0;
    	delay(500);
	
		//dispbuf=19;//若是数据溢出中断,则显示L,表示有数据溢出中断
    }

	else
	{
		P14=1;
		P15=1;
		P17=1;
		P0=~dispbitcode[18];
    	P17=0;
    	delay(500);
	
	//dispbuf=18;//表示唤醒中断,显示P
	}


	EX0=1;//开外中断0
}

⌨️ 快捷键说明

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