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

📄 can-0401.c

📁 这是我从朋友那搞到的pic学习资料
💻 C
字号:
/* ****************************************************************
** 功能描述: 接收到来自PC机串口通信发来的数据后,将所有接收数据用CAN 转发到从实验板(从CAN)
*************************************************************** */
#include	"pic18.h"							/* PIC18系列的头文件 */
char	CAN_TX_Adress_H,CAN_TX_Adress_L;	/* CAN 发送邮箱标识符高低字节 */
char	CAN_RX_Adress_H,CAN_RX_Adress_L;	/* CAN 接收邮箱标识符高低字节 */
int	CAN_FLAG;							/* =1接收到CAN 数据,=0未接收到数据 */
unsigned	char	receive_count=0;				/* 232串口接收数据个数寄存器 */
unsigned	char	send_count=0;					/* 232串口发送数据个数寄存器 */
unsigned	char	*pointer;						/* 232串口发送指针 */
unsigned	char	SciReceiveFlag;			/*=1串口收到8个数据,=0未收到8个数据*/
unsigned	char	receive232[20];			/* 232串口接收数据数组 */
unsigned	char	send232[20];				/* 232串口发送数据数组 */

/* ****************************************************************
** 函 数 名: initial()
** 功能描述: 系统初始化子程序,放在程序首部
*************************************************************** */
void	initial()
{
	INTCON=0x00;					/* bit7-bit0:关总中断 */
	ADCON1=0X07;					/* 设置数字输入输出口 */
	PIE1=0;							/* PIE1 的中断不使能 */	
	PIE2=0;							/* PIE2 的中断不使能 */	
	PIE3=0;							/* PIE3 的中断不使能 */	
}
	
/* ****************************************************************
** 函 数 名: sciinitial()
** 功能描述: 串行通讯初始化子程序
*************************************************************** */
void	sciinitial()
{
	SPBRG=25;						/* 4M,波特率9600时为SPBRG=25 */
	TXSTA=0x04;						/* 选择异步高速方式传输8位数据 */
	RCSTA=0x80;						/* 允许串行口工作使能 */
	TRISC=TRISC|0X80;				/* RC7(RX)设置为输入方式 */
	TRISC=TRISC&0Xbf;				/* RC6(TX)设置为输出 */
	PIE1=PIE1|0x20;					/* 允许串行通讯接口接收中断使能 */
	RCIP=0;							/* 设置SCI接收中断为低优先级中断 */
	PIE1=PIE1|0x10;					/* 允许中断发送 */
	TXIP=0;							/* 低优先级中断 */
	CREN=1;						/* 允许串口接收数据 */
//	TXEN=1;						/* 允许串口发送数据 */
}

/* ****************************************************************
** 函 数 名: initcan()
** 功能描述: CAN初始化子程序,采用标准标识符,正常工作模式
*************************************************************** */
void	initcan()
{
	/* ************设置对CAN进行配置***************  */
	TRISB=(TRISB|0X08)&0XFB;		/*设置CANRX/RB3输入,CANTX/RB2输出*/
	CANCON=0X80;					/* CANCON,bit7-5:1XX请求配置 */
	while((CANSTAT&0X80)==0)		/* CAN状态寄存器。bit7-5:100配置方式 */
	{							
		;
	}								/* 等待进入CAN配置模式OPMODE=100 */
	/* ************设置对CAN进行配置***************  */

	/*  ***********波特率设置 ************************** */
	BRGCON1=0X01;				/* Sync_Seg(bit7-6)=1TQ,BRP(bit5-0)=1,
								则TQ=((2*(BRP+1))/Fosc=4/4M=1us */
	BRGCON2=0X90;			/*bit7=1自由编程,bit6=0总线在采样点采样1
次;phase_Seg1(bit5-3)=3TQ;Prog_Seg(bit2-0)=1TQ*/
	BRGCON3=0X42;			/* 设置Phase_Seg2(bit2-0)=3TQ */
	/* 标称位时间=TQ*(Sync_Seg+ Prop_Seg+ Phase_seg1+ Phase_seg2)
=(1+1+3+3)TQ=8TQ,    位率=1/(8*1U)=0.125MHz */

	/* 设置发送邮箱0标识符 :00110011111=0x019F */
	CAN_TX_Adress_H=0x33;		//CAN高地址标识符,应与发送方标识符相同
	CAN_TX_Adress_L=0xe0;		//CAN低地址标识符
	CAN_TX_Adress_L=CAN_TX_Adress_L&0xe0;

	/* 设置接收邮箱0标识符 :10011001010=0x04CA */
	CAN_RX_Adress_H=0x99;		//CAN高地址标识符
	CAN_RX_Adress_L=0x55;		//CAN低地址标识符,应与发送方标识符相同
	CAN_RX_Adress_L=CAN_RX_Adress_L&0xe0;

	/*  ******设置发送邮箱0和初始发送的数据*****  */
	TXB0CON=0X03;					/* bit1-0:发送优先级,设置TXB0为最高优先级3 */
	TXB0SIDL=CAN_TX_Adress_L&0xe0;/* bit3=0标准标识符,bit7-5:标准标识符2-0位*/
	TXB0SIDH=CAN_TX_Adress_H;	/* 标准标识符的10-3位*/
	TXB0DLC=0X08;					/* 设置数据长度为8个字节 */
	TXB0D0=0X00;					/* 写发送缓冲器数据区数据初值 */
	TXB0D1=0X01;					/* 写发送缓冲器数据区数据初值 */
	TXB0D2=0X02;
	TXB0D3=0X03;
	TXB0D4=0X04;
	TXB0D5=0X05;
	TXB0D6=0X06;
	TXB0D7=0X07;

	RXB0SIDL=CAN_RX_Adress_L&0xe0;/* bit3=0标准标识符,bit7-5:标准标识符2-0位*/
	RXB0SIDH=CAN_RX_Adress_H;		/* 标准标识符的10-3位 */
	RXB0CON=0X20;						/* bit6-5=01只接收有效的标准标识符信息 */
	RXB0DLC=0X08;						/* 设置接收缓冲器0数据区长度8个字节 */
	RXB0D0=0X02;						/* 初始化接收缓冲器0的数据区数据 */
	RXB0D1=0X03;						/* 初始化接收缓冲器0的数据区数据 */
	RXB0D2=0X04;
	RXB0D3=0X05;
	RXB0D4=0X00;
	RXB0D5=0X00;
	RXB0D6=0X00;
	RXB0D7=0X00;

	/* *******初始化接收滤波器0和接收屏蔽**************** */
	RXF0SIDH=CAN_RX_Adress_H;		
	RXF0SIDL=CAN_RX_Adress_L&0xe0;	/*高3位为标识符低3位,低5位是配置 */
	RXM0SIDH=0Xff;
	RXM0SIDL=0Xe0;				/* 11个1表示接收11位标识符进行滤波,标识符
不同不接收;若全为0,若正确信息,全部接收*/
		
	/* *******设置CAN工作模式**************************** */
	CANCON=0X00;					//=0X40,进入自测试模式;=0x00,正常操作模式
	while((CANSTAT&0XE0)!=0)		/* 检测CAN配置完成 */
	{
		;
	}

	/* 初始化CAN的中断,PIR3为CAN的外围中断标志寄存器 */
	PIR3=0X00;					/* 清所有CAN中断标志*/
	PIE3=PIE3|0X01;				/* 使能接收缓冲器0的接收中断 */
	IPR3=IPR3|0X01;				/* 接收缓冲器0的接收中断为最高优先级 */
}

/* ****************************************************************
** 函 数 名: interrupt	HI_ISR()
** 功能描述: 高优先级中断子程序:RXB0接收邮箱0接收中断子程序
*************************************************************** */
void interrupt	HI_ISR()
{
	if(RXB0IF==1)
	{
  		CAN_FLAG=1;				/* 置接收到 CAN 数据 */
		RXB0IF=0;					/* 清接收中断标志 */
		RXB0FUL=0;					/* bit7=0,打开接收缓冲器接收新信息 */
	}
}

/* ****************************************************************
** 函 数 名: interrupt low_priority	LOW_ISR()
** 功能描述: 低优先级中断子程序:232接收发送中断子程序
*************************************************************** */
void	interrupt low_priority	LOW_ISR()
{
	if(RCIF==1)						/* 232接收中断 */
	{
		RCIF=0;						/* 清接收中断标志 */
		receive232[receive_count]=RCREG;		/* 接收数据并存储 */
		receive_count++;				/* 接收计数器加1 */
		if(receive_count>7)				/* 接收到8个数据 */
		{
			receive_count=0;			/* 接收计数器清0 */
			SciReceiveFlag=1;			/* 置接收到数据标志 */
		}
	}
	else	if(TXIF==1)					/* 232发送中断 */
	{
		TXIF=0;						/* 不能用软件清0	 */
		if(send_count>7)				/* 发送完8个数据 */
		{
			TXEN=0;				/* 关发送使能 */
			return;
		}
		else
			{
				send_count++;			/* 发送计数器加1 */
				TXREG=*pointer++;	/* 发送数据,发送指针加1 */
			}
	}
}

main()
{
	initial();							/* 系统初始化子程序 */
	sciinitial();						/* 串行通讯初始化子程序 */
	initcan();							/* CAN设置初始化 */
	IPEN=1;							/* 使能中断高低优先级 */
	INTCON=INTCON|0xc0;			/* 开总中断、开外围接口中断 */
	TXB0REQ=0;						/* TXB0REQ=0 关发送 */
	while(1)
	{
		if(SciReceiveFlag==1)			/* 接收到232通信 */
		{		
			TXB0CON=TXB0CON&0xf7;	/*bit3:TXREQ=0, 关请求发送*/
			SciReceiveFlag=0;
			pointer=&receive232[0];
			TXB0D0=*pointer++;			/* 用接收数据来更新发送数据 */
			TXB0D1=*pointer++;
			TXB0D2=*pointer++;
			TXB0D3=*pointer++;
			TXB0D4=*pointer++;
			TXB0D5=*pointer++;
			TXB0D6=*pointer++;
			TXB0D7=*pointer++;
			TXB0CON=TXB0CON|0x08;	/* 请求发送,bit3:TXREQ=1 */
			while(TXB0IF!=1)
			{
				;
			}							/* 等待发送完成 */
		}

		if(CAN_FLAG==1)				/* 接收到CAN通信 */
		{
			CAN_FLAG=0;				/* 接收到标志 */
			send232[0]=RXB0D0;
			send232[1]=RXB0D1;
			send232[2]=RXB0D2;
			send232[3]=RXB0D3;
			send232[4]=RXB0D4;
			send232[5]=RXB0D5;
			send232[6]=RXB0D6;
			send232[7]=RXB0D7;
			send_count=0;					/*  发送计数器清0 */
			pointer=&send232[0];			/* 指向发送的第一个数据地址 */
			TXREG=*pointer++;			/* 发送第一个数据 */
			TXEN=1;					/* 允许发送数据 */	
		}
	}
}

⌨️ 快捷键说明

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