CAN现场总线.rar

源代码在线查看: 00-can驱动程式(节点一).c

软件大小: 391 K
上传用户: l550253832
关键词: CAN 现场总线
下载地址: 免注册下载 普通下载 VIP

相关代码

				//	00-CAN驱动程式(-).c
				//	程式是利用CAN学习版上的硬件资源(数码管,中断健)
				//  建立的点对点的驱动程式
				//  akuei2上 10-10-09
				
				#include "reg52.h"
				#include "sja1000.h"
				#define uchar unsigned char
				
				//i0脚定义
				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,Click;
				
				//函数声明
				void Display(void);
				void CAN_TXD(void);
				void CAN_RXD(void);
				
				//1毫秒延迟函数
				void Delay_1ms(int x)
				{
					int j;
					for(;x>0;x--)
						for(j=125;j>0;j--);
				}
				
				//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';			//源节点地址为 CAN2
					ACR[1]='A';
					ACR[2]='N';
					ACR[3]='1';		//全部标示符屏蔽
					AMR[0]=0x00;
					AMR[1]=0x00;
					AMR[2]=0x00;
					AMR[3]=0x03;
				
					TXD_Buffer[0]=0x88;	//EFF格式,数据长度8 的 TX帧信息
					TXD_Buffer[1]='C';	//目的标示符为CAN1
					TXD_Buffer[2]='A';
					TXD_Buffer[3]='N';
					TXD_Buffer[4]='2';
					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					{
						RXD_Buffer[i]=0x00;
					}
				
					TXD_Data=0x00;			//发送数据初始化
					RXD_Data=0x00;			//接收数据初始化
				}
				
				//CPU初始化
				void Init_CPU(void)
				{
					SJACS=1;		// 使片选无效
					SJARST=1;		// 硬件复位无效
				
					IT0=1;			// 外部中断0为电平触发方式
					IT1=0;			// 外部中断1为跳电沿触发方式
					EX0=1;			// 外部中断0使能
					EX1=1;			// 外部中断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();
					}
				}
				
				//数码管显示函数
				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					{
						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;                   //释放错误代码捕捉寄存器
					}
				}
				
				//外部中断0函数-点击中断
				void Ir_EX0(void) interrupt 0
				{
					Delay_1ms(10);		//软件消抖
				
					EA=0;				//关闭全局使能
					EX0=0;				//外部中断0使无效
					Click++;			
					if(Click>=100) Click=0;
					TXD_Data=Click;		//发送数据赋值
					TXD_Buffer[5]=TXD_Data;
					CAN_TXD();			//调用发送函数
					EX0=1;				//外部中断0使能
					EA=1;				//全局中断使能
				
				}
				
				//外部中断1函数-RXFIFO饱和中断
				void Ir_EX1(void) interrupt 2
				{
					EA=0;				//关闭全局使能
					EX1=0;				//外部中断1使无效
					CAN_RXD();			//调用接收函数
					RXD_Data=RXD_Buffer[5];	//接收数据变量赋值
					EX1=1;				//外部中断1使能
					EA=1;				//全局中断使能
				}
							

相关资源