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

📄 00-rs232-can.c

📁 CAN现场总线.rar
💻 C
字号:
//00-RS232-CAN.c
//RS232-CAN转换的例子程式
//akuei2 31-10-09

#include "reg52.h"
#include "sja1000.h"
#include "intrins.h"
#define uchar unsigned char

//IO口定义
sbit SJACS=P2^0;
sbit SJARST=P2^3;

//数码管码,位选码定义
uchar code Led_Code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
uchar code Led_Select[]={0xef,0xdf,0xbf,0x7f}; 

//变量声明
uchar ACR[4],AMR[4],TXD_Buffer[13],RXD_Buffer[13],TXD_Data,RXD_Data;
uchar Click;
bit Flag_232RXD,Flag_CANRXD;

//函数声明
void Display(void);
void CAN_TXD(void);
void CAN_RXD(void);
void RS232_TXD(void);

//50微秒延迟函数
void Delay_50us(int t)
{
	uchar j; 
    t--;
	for(;t>0;t--)  
   		for(j=19;j>0;j--);
}

//数据初始化函数
void Init_Data(void)
{
	int i;

	ACR[0]='C';
	ACR[1]='A';
	ACR[2]='N';
	ACR[3]=0x01;
	AMR[0]=0xff;
	AMR[1]=0xff;
	AMR[2]=0xff;
	AMR[3]=0xff;

	TXD_Buffer[0]=0x88;
	TXD_Buffer[1]='C';
	TXD_Buffer[2]='A';
	TXD_Buffer[3]='N';
	TXD_Buffer[4]=0x02;
	TXD_Buffer[5]=TXD_Data;
	TXD_Buffer[6]=0x00;
	TXD_Buffer[7]=0x00;
	TXD_Buffer[8]=0x00;
	TXD_Buffer[9]=0x00;
	TXD_Buffer[10]=0x00;
	TXD_Buffer[11]=0x00;
	TXD_Buffer[12]=0x00;

	for(i=0;i<13;i++)
	{
		RXD_Buffer[i]=0x00;
	}

	TXD_Data=0x00;
	RXD_Data=0x00;
}

//CPU初始化函数
void Init_CPU(void)
{
	SJACS=1;
	SJARST=1;
	
    SCON=0x50;           //串口工作方式1,允许接收
    PCON=0x80;           //波特率翻倍   
   	TMOD=0x20;           //T1用于串口波特率控制
   	TL1=0xfa;            //初始化T1,波特率为9600(晶振11.0592M)
   	TH1=0xfa;                    
  	TR1=1;               //开定时器
  	ES  = 1;             //打开串口中断

	IT0=1;
	IT1=0;
	EX0=1;
	EX1=1;

	EA=1;
	   
}

//CAN初始化函数
void Init_CAN(void)
{
   unsigned char bdata temp;   //建立存储在bdata中的临时变量temp
	
   do
   {
      MODR=0x09; 
	  temp=MODR;  //模式寄存器-设置复位模式而且单验收滤波模式
   }
   while(!(temp&0x01));  //判断

   CDR=0x88;     //时钟分频寄存器-设置PeliCAN模式,Clock off有效
   BTR0=0x31;    //总线时序寄存器-波特率为10kbps
   BTR1=0x1c;
   IER=0x01;      //中断使能寄存器-接收中断使能
   OCR=0xaa;     //输出控制寄存器-借签...
   CMR=0x04;     //命令寄存器-释放RXFIF0

   ACR0=ACR[0];      //接收代码寄存器-本节点地址位CAN0 
   ACR1=ACR[1]; 
   ACR2=ACR[2]; 
   ACR3=ACR[3];

   AMR0=AMR[0];    //接收屏蔽寄存器-无任何屏蔽
   AMR1=AMR[1]; 
   AMR2=AMR[2]; 
   AMR3=AMR[3];   //最后两位为无用位,必须设置为逻辑1

   do
   {
      MODR=0x08; 
	  temp=MODR;   //模式寄存器-推出复位模式,保持单验收滤波模式
   }
   while(temp&0x01);   //判断...
}   

//主函数
void main(void)
{
	Init_Data();
	Init_CPU();
	Init_CAN();
	while(1)
	{
		Display();
		if(Flag_232RXD)
		{
			Flag_232RXD=0;
			TXD_Buffer[5]=TXD_Data;
			CAN_TXD();
		}
		if(Flag_CANRXD)
		{
			Flag_CANRXD=0;
			RXD_Data=RXD_Buffer[5];
			RS232_CAN();
		}
	}
}

//数码管显示函数
void Display(void)
{
	int Digit[4],i;
	Digit[3]=TXD_Data/10;			//第一个数码管取千位
	Digit[2]=TXD_Data%10;		//第二个数码管取百位
	Digit[1]=RXD_Data/10;		//第三个数码管取十位
	Digit[0]=RXD_Data%10;			//第四个数码管取个位
	for(i=0;i<4;i++)
	{
		P0=Led_Code[Digit[3-i]];		//送数码管码
		P2=Led_Select[i];				//送位选码
		Delay_50us(20);					//延迟1微秒
	}
}

//CAN接收函数
void CAN_TXD(void)
{
	unsigned char bdata temp;

	do
	{
	  temp=SR;         //判断报文接收完毕?	
	}
	while(temp&0x10);    //SR.4=0 发送闲置,SR.4=1 发送状态中
	
	do
	{
	  temp=SR;         //判断最后报文请求?	
	}
	while(!(temp&0x08));  //SR.3=0 没有余报文请求,SR.3=1 还存在报文请求
	
	do
	{
	  temp=SR;         //判断TXFIFO是否锁定?
	}
	while(!(temp&0x04));  //SR.2=0 锁定,SR.2=1 开放

	TBSR0=TXD_Buffer[0];
	TBSR1=TXD_Buffer[1];
	TBSR2=TXD_Buffer[2];
	TBSR3=TXD_Buffer[3];
	TBSR4=TXD_Buffer[4];
	TBSR5=TXD_Buffer[5];
	TBSR6=TXD_Buffer[6];
	TBSR7=TXD_Buffer[7];
	TBSR8=TXD_Buffer[8];
	TBSR9=TXD_Buffer[9];
	TBSR10=TXD_Buffer[10];
	TBSR11=TXD_Buffer[11];
	TBSR12=TXD_Buffer[12];

	CMR=0x01;       //命令寄存器-发送请求
}

//CAN发送函数
void CAN_RXD(void)
{
	unsigned char temp;

	temp = IR;
	if( temp & 0x01)                   //判断是否接收中断
	{
		RXD_Buffer[0]=RBSR0;         //读取RXFIFO
		RXD_Buffer[1]=RBSR1;
		RXD_Buffer[2]=RBSR2;
		RXD_Buffer[3]=RBSR3;
		RXD_Buffer[4]=RBSR4;
		RXD_Buffer[5]=RBSR5;
		RXD_Buffer[6]=RBSR6;
		RXD_Buffer[7]=RBSR7;
		RXD_Buffer[8]=RBSR8;
		RXD_Buffer[9]=RBSR9;
		RXD_Buffer[10]=RBSR10;
		RXD_Buffer[11]=RBSR11;
		RXD_Buffer[12]=RBSR12;

		CMR = 0X04;                  //释放RXFIFO中的空间
		temp = ALC;                   //释放仲裁随时捕捉寄存器
		temp = ECC;                   //释放错误代码捕捉寄存器
	}

	IER = 0x01;// .0=1--接收中断使能;

}

//串口发送函数
void RS232_TXD( void )
{
    EA = 0;					//关闭所有中断
    ES = 0;					//关闭串口中断,采用查询发送方式
    TI = 1;
    while(TI)
    {
        TI = 0;				//一字节发送完后清除标志位
        SBUF = RXD_Data;	//can接收到的数据发送出去
        while(!TI);			//等待发送
        TI = 0;
    }
    ES = 1;					//打开串口中断
    EA = 1;					//打开中断
}

//CAN接收中断
void Ir_EX1(void) interrupt 2
{
	EA=0;
	EX1=0;
	CAN_RXD();
	Flag_CANRXD=1;
	EX1=1;
	EA=1;
}

//串口接收据函数
void RS232_RXD( void ) interrupt 4   
{
    EA = 0;					//关闭所有中断
    ES = 0;					//关闭串口
    if(RI==1)
    {
        RI = 0;
        TXD_Data = SBUF;
		Flag_232RXD=1;
    }
    ES = 1;					//打开串口
    EA = 1;					//打开中断
}

⌨️ 快捷键说明

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