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

📄 pic18f4580_can_rs232_picc8.35.c

📁 pic18F458单片机实现can和rs232通信。
💻 C
📖 第 1 页 / 共 2 页
字号:
//Function(函数功能): 串口初始化,波特率:9600bps                        //
//Input(输入参数类型):void                                              //
//Output(输出参考类型):void                                             //
//Return(返回信息):无                                                   //
//////////////////////////////////////////////////////////////////////////
void InitUSART(void)
{
 TRISC6 = 0;                 //RC6-TX
 TRISC7 = 1;                 //RC7-RX
 BAUDCON=0x00;          //8位波特率发生器
 SPBRG = ((Fosc/BAUDRATE)/64)-1; //8位,异步,低速
 TXSTA = 0b00100010;    //异步模式,8位发送,发送使能,低速
 RCSTA = 0b10010000;    //使能串口,8位接收,使能连续接收
 RCIF = 0;              //串口接收中断标志清零
 RCIE = 1;              //使能串口接收中断
 RCIP = 0;              //低优先级
 NOP(); 
}
//************************************************************************


//////////////////////////////////////////////////////////////////////////
//                             子函数                                   //
//Function name(函数名称):InitTMR0                                      //
//Create date(创建日期):2007.8.1                                        //
//created by(创建人):夏红峰                                             //
//E-mail:master_0722@sina.com/master_0722@yahoo.com                     //
//Function(函数功能):用于确定串口数据流的长度                           //
//Input(输入参数类型):void                                              //
//Output(输出参考类型):void                                             //
//Return(返回信息):无                                                   //
//////////////////////////////////////////////////////////////////////////
void InitTMR0(void)
{
 //禁止TMR0,8位定时器/计数器,内部指令周期时钟,使用前分频器,1:128分频
 T0CON = 0b01010110;    
 TMR0IF = 0;            //TMR0中断标志位清零
 TMR0IE = 1;            //TMR0中断使能
 TMR0IP = 1;            //TMR0中断优先级高
 TMR0 = TMR0data;       //延时3个串口接收到的字节
 NOP();
}
//************************************************************************


//////////////////////////////////////////////////////////////////////////
//                             子函数                                   //
//Function name(函数名称):InitCAN                                       //
//Create date(创建日期):2007.8.1                                        //
//created by(创建人):夏红峰                                             //
//E-mail:master_0722@sina.com/master_0722@yahoo.com                     //
//Function(函数功能): CAN初始化                                         //
//Input(输入参数类型):void                                              //
//Output(输出参考类型):void                                             //
//Return(返回信息):无                                                   //
//////////////////////////////////////////////////////////////////////////
void InitCAN(void)
{
 TRISB2 = 0;                      //设置CANRX-RB3输入,CANTX-RB2输出
 TRISB3 = 1;
 CANCON_0 = 0x80;  //请求进入CAN配置模式,REQOP=100   
 while(( CANSTAT_0 & 0b11100000 ) != 0x80){;} //等待进入CAN配置模式OPMODE=100  	
 
 //设置CAN波特率125kbps,在Fosc=20MHz时,Tbit=8us,假设BRP=09h
 //则Tq=[2*(1+BRP)]/Fosc=2*(1+9)/(20MHz)=1us
 //normal bit rate=8Tq,SJW=00,Sync_Seg=1Tq,Prog_Seg=1Tq
 //Phase_Seg1=3Tq,Phase_Seg2=3Tq
 BRGCON1 = 0x09;
 BRGCON2 = 0x90;	
 BRGCON3 = 0x42;         
	
 RXB0CON = 0x60;		 //接收所有有效信息,这样就不需要设置过滤屏蔽器了
 RXB1CON = RXB0CON; 	 //做同样处理
 
 CIOCON	 = 0x00;	     //当“隐性”时,CANTX引脚驱动到高阻状态,禁止CAN捕捉
 ECANCON=0x00; //选择模式0

 CANCON_0 = 0x00;					   //请求正常方式 
 while((CANSTAT_0&0x80) != 0x80){;}    //等待进入正常模式
 
 //初始化CAN的中断,PIR3为CAN的外围中断标志寄存器 
 RXB0IF = 0;            //CAN接收缓冲器0中断标志位清零
 RXB0IE = 1;            //使能CAN接收缓冲器0的接收中断 
 RXB0IP = 1;            //接收缓冲器0的接收中断为高优先级	
 NOP();    
}
//************************************************************************


//////////////////////////////////////////////////////////////////////////
//                            主程序                                    //
//////////////////////////////////////////////////////////////////////////
void main(void)
{   
 unsigned char sendnum;	
 NOP(); 
 Initial();                  //IO口初始化
 InitUSART();                //串口初始化
 InitTMR0();                 //定时器0初始化
 InitCAN();				     //内部CAN寄存器设置初始化
 IPEN = 1;					 //使能中断优先级
 INTCON |= 0xC0;		     //开放所有高低优先级中断   
 while(1)
	  {
	   if(RD0 == 0)          //如有S1按键按下,发送标准帧
	     {
		  while(RD0 == 0);   //等待S1按键释放
		  TXB0CON = 0x03;    //设置为发送最高优先级
		  TXB0SIDH = 0xFF;   //SID10--SID3
		  TXB0SIDL = 0xE0;   //SID2--SID0
		  TXB0DLC = 0x08;    //发送数据长度为8字节
		  TXB0D0=0x00;	     //发送的数据 
		  TXB0D1=0x11;
		  TXB0D2=0x22;
		  TXB0D3=0x33;
		  TXB0D4=0x44;
		  TXB0D5=0x55;
		  TXB0D6=0x66;
		  TXB0D7=0x77;	
		  TXB0REQ = 1;	          //请求发送
		  while(TXB0REQ == 1);    //等待发送成功
		  RD1 = 1;         	      //发送成功,则点亮RD1
		  DelayNmSec(100);        //延时0.1s
		  RD1 = 0;                //熄灭RD1
	     }

	   if(RC0 == 0)          //如有S2按键按下,发送扩展帧
	     {
		  while(RC0 == 0);   //等待S2按键释放
		  TXB0CON = 0x03;    //设置为发送最高优先级
		  TXB0SIDH = 0xFF;   //EID28--21
		  TXB0SIDL = 0xEB;   //EID20--EID18,扩展帧使能,EID17--EID16
		  TXB0EIDH = 0xFF;   //EID15--EID8
		  TXB0EIDL = 0xFF;   //EID7--EID0
		  TXB0DLC = 0x08;    //发送数据长度为8字节
		  TXB0D0=0x00;	     //发送的数据 
		  TXB0D1=0x11;
		  TXB0D2=0x22;
		  TXB0D3=0x33;
		  TXB0D4=0x44;
		  TXB0D5=0x55;
		  TXB0D6=0x66;
		  TXB0D7=0x77;	
		  TXB0REQ = 1;	          //请求发送
		  while(TXB0REQ == 1);    //等待发送成功
		  RC1 = 1;         	      //发送成功,则点亮RC1
		  DelayNmSec(100);        //延时0.1s
		  RC1 = 0;                //熄灭RC1
	     }
	     	     
	   if(USARTreceive_flag == 1) //接收到符合要求的串口数据流 
		 {		
		  USARTreceive_flag = 0;       //串口转发再允许
		  TXB0CON = 0x03;         //设置为发送最高优先级
		  pointer = &receive232[1];
		  TXB0SIDH = *pointer++;       //发送的标识符
		  TXB0SIDL = *pointer++;
		  TXB0EIDH = *pointer++;
		  TXB0EIDL = *pointer++;
		  TXB0DLC = *pointer++;        //发送的数据长度
		  TXB0D0 = *pointer++;		   //发送的数据
		  TXB0D1 = *pointer++;
		  TXB0D2 = *pointer++;
		  TXB0D3 = *pointer++;
		  TXB0D4 = *pointer++;
		  TXB0D5 = *pointer++;
	      TXB0D6 = *pointer++;
		  TXB0D7 = *pointer++;
		  TXB0REQ = 1;	               //请求发送
		  while(TXB0REQ == 1);         //等待发送成功
		  if(TXB0EXIDE == 0)//如果是标准帧
		    {
		     RD1 = 1;         	       //发送成功,则点亮RD1
		     DelayNmSec(100);          //延时0.1s
		     RD1 = 0;                  //熄灭RD1				    
			}
		  if(TXB0EXIDE == 1)//如果是扩展帧
		    {
		     RC1 = 1;         	       //发送成功,则点亮RC1
		     DelayNmSec(100);          //延时0.1s
		     RC1 = 0;                  //熄灭RC1				    
			}		  				 
		 }
		 
	   if(CANreceive_flag == 1)		   //接收到来自CAN总线的数据 
		 {		  
		  CANreceive_flag = 0;  	   //接收标志位清零		  
          send232[0] = RXB0SIDH;       //接收到的标准标识符高字节
          send232[1] = RXB0SIDL;       //接收到的标准标识符低字节
          send232[2] = RXB0EIDH;       //接收到的扩展标识符高字节(看RXB0EXID而定)
          send232[3] = RXB0EIDL;       //接收到的扩展标识符低字节(看RXB0EXID而定)
          send232[4] = RXB0DLC;        //接收到的数据长度
          send232[5] = RXB0D0;         //接收到的数据
		  send232[6] = RXB0D1;
		  send232[7] = RXB0D2;
		  send232[8] = RXB0D3;
		  send232[9] = RXB0D4;
		  send232[10] = RXB0D5;
		  send232[11] = RXB0D6;
		  send232[12] = RXB0D7;
		  if(RXB0EXID == 0)            //标准帧的话
		    {
             RD1 = 1;         	       //接收成功,则点亮RD1
		     DelayNmSec(100);          //延时0.1s
		     RD1 = 0;                  //熄灭RD1	
		    }
		  if(RXB0EXID == 1)            //扩展帧的话
		    {
             RC1 = 1;         	       //接收成功,则点亮RC1
		     DelayNmSec(100);          //延时0.1s
		     RC1 = 0;                  //熄灭RC1	
		    }
          send_count=13;               //串口转发13字节
          for(sendnum=0;sendnum<send_count;sendnum++) //转发到串口
             {
	          TXREG = send232[sendnum];	
              while(TRMT == 0);        //等待串口发送完一字节
             }	        		 
		 }      
	  }
}
//************************************************************************


//////////////////////////////////////////////////////////////////////////
//                             子函数                                   //
//Function name(函数名称):DelayNmSec                                    //
//Create date(创建日期):2007.8.1                                        //
//created by(创建人):夏红峰                                             //
//E-mail:master_0722@sina.com/master_0722@yahoo.com                     //
//Function(函数功能): 延时N*1ms,最大65.5秒                             //
//Input(输入参数类型):unsigned int N                                    //
//Output(输出参考类型):void                                             //
//Return(返回信息):无                                                   //
//////////////////////////////////////////////////////////////////////////
void DelayNmSec(unsigned int N)
{
 unsigned int j;
 while(N--)
 	   for(j=0;j<MILLISEC;j++);
}
//************************************************************************



⌨️ 快捷键说明

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