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

📄 can.c

📁 此原程序是dsp2407上自带的can接口的低层代码
💻 C
字号:
#pragma DATA_SECTION(s_wCANCommBuffer,"RamData")
#include <Main.h>

#define COMMSTATUS_INIT			0x0000
#define COMMSTATUS_RCV_HEAD		0x1111
#define COMMSTATUS_RCV_DATA		0x2222
#define COMMSTATUS_SNDOPEN		0x3333
#define COMMSTATUS_SNDING		0x4444
#define COMMSTATUS_SNDCLOSE		0x5555

static unsigned short s_wCANCommBuffer[COMMBUFFERSIZE];
static unsigned short s_wCANRcvData;
static unsigned short s_wCANCommStatus;
static unsigned short s_wCANCountTimeout;
static unsigned short* s_pCANRcvPointer;
static unsigned short* s_pCANRcvEndPointer;
static unsigned short* s_pCANSndPointer;
static unsigned short* s_pCANSndEndPointer;
/*******************************************************************/

static void InitCAN(void)
{
	CANIMR = 0x0000;
	CANIFR = CANIFR;
	CANMDER = 0x0000;
	CANMCR = 0x3400;
	while(!(CANGSR&0x0010));
	CANBCR1 = 0x0265;
	switch(CANCOMMBAUDRATE)
	{
	case BAUDRATE_5k: CANBCR1 = 0x037f; CANBCR2 = 255; break;
	case BAUDRATE_10k: CANBCR2 = 199; break;
	case BAUDRATE_20k: CANBCR2 = 99; break;
	case BAUDRATE_50k: CANBCR2 = 39; break;
	case BAUDRATE_125k: CANBCR2 = 15; break;
	case BAUDRATE_250k: CANBCR2 = 7; break;
	case BAUDRATE_500k: CANBCR2 = 3; break;
	case BAUDRATE_1M: CANBCR2 = 1; break;
	default: CANBCR2 = 3; break;
	}
	CANMCR = 0x2400;
	while(CANGSR&0x0010);
	CANLAM0L = 0x0000;
	CANLAM0H = 0x0000;
	CANMSGID0L = 0x0000;
	CANMSGID0H = 0x1ffc;
	CANRCR |= 0x1111;
	CANMDER = 0x0001;
	OnInitCANRTR();
}

static void InitCommStatus(void)
{
	s_wCANCountTimeout = 6000;
	s_wCANCommStatus = COMMSTATUS_INIT;
	OnCANCommClose();
}

static void CANSendPackage(void)
{
	unsigned short wCountSend;
	if(s_pCANSndPointer>=s_pCANSndEndPointer) return;
	wCountSend = (unsigned short)(s_pCANSndEndPointer-s_pCANSndPointer);
	if(wCountSend>8) wCountSend = 8;
	CANTCR |= 0x4400;
	CANMDER &= 0xffff^0x0010;
	CANMSGID4L = 0x0000;
	CANMSGID4H = 0x1ff8;
	CANMSGCTRL4 = wCountSend;
	CANMBX4A = s_pCANSndPointer[0]+(s_pCANSndPointer[1]<<8);
	CANMBX4B = s_pCANSndPointer[2]+(s_pCANSndPointer[3]<<8);
	CANMBX4C = s_pCANSndPointer[4]+(s_pCANSndPointer[5]<<8);
	CANMBX4D = s_pCANSndPointer[6]+(s_pCANSndPointer[7]<<8);
	s_pCANSndPointer += wCountSend;
	CANMDER |= 0x0010;
	CANTCR |= 0x0040;
}

static void CANReceivePackage(void)
{
	s_pCANRcvPointer[0] = CANMBX0A&0xff;
	s_pCANRcvPointer[1] = CANMBX0A>>8;
	s_pCANRcvPointer[2] = CANMBX0B&0xff;
	s_pCANRcvPointer[3] = CANMBX0B>>8;
	s_pCANRcvPointer[4] = CANMBX0C&0xff;
	s_pCANRcvPointer[5] = CANMBX0C>>8;
	s_pCANRcvPointer[6] = CANMBX0D&0xff;
	s_pCANRcvPointer[7] = CANMBX0D>>8;
}

/*******************************************************************/
void OnInitCAN(void)
{
	InitCAN();
	InitCommStatus();
}

void OnTaskCAN(void)
{
	unsigned short wCRC;
	unsigned short wCountSend;
	if(s_wCANCommStatus!=COMMSTATUS_SNDOPEN) return;
	InitCAN();
	wCRC = CalculateCRC(s_wCANCommBuffer,s_pCANRcvEndPointer-s_wCANCommBuffer);
	if(wCRC==0)
	{
		wCountSend = CommTaskProcess(s_wCANCommBuffer);
		if(wCountSend)
		{
			s_pCANSndPointer = s_wCANCommBuffer;
			s_pCANSndEndPointer = s_wCANCommBuffer+wCountSend;
			wCRC = CalculateCRC(s_wCANCommBuffer,wCountSend);
			*s_pCANSndEndPointer++ = (unsigned short)(wCRC&0xff);
			*s_pCANSndEndPointer++ = (unsigned short)(wCRC>>8);
			s_wCANCountTimeout = 6000;
			s_wCANCommStatus = COMMSTATUS_SNDING;
			return;
		}
	}
	InitCommStatus();
}

void OnPollingCAN(void)
{
	if(s_wCANCountTimeout>0)
	{
		s_wCANCountTimeout--;
		if(s_wCANCountTimeout==0) OnInitCAN();
	}
	switch(s_wCANCommStatus)
	{
	case COMMSTATUS_INIT:
		s_wCANCommStatus = COMMSTATUS_RCV_HEAD;
		break;
	case COMMSTATUS_RCV_HEAD:
		if(CANRCR&0x0010)
		{
			if((CANMSGCTRL0&0x000f)==8)
			{
				s_pCANRcvPointer = s_wCANCommBuffer;
				CANReceivePackage();
				s_wCANRcvData = s_wCANCommBuffer[0];
				if(s_wCANRcvData==CANCOMMADDRESS||s_wCANRcvData==0)
				{
					OnCANCommOpen();
					s_wCANCountTimeout = 6000;
					s_wCANRcvData = s_wCANCommBuffer[1];
					if(s_wCANRcvData==0x03)
					{
						s_pCANRcvPointer = s_wCANCommBuffer+8;
						s_pCANRcvEndPointer = s_wCANCommBuffer+8;
						s_wCANCommStatus = COMMSTATUS_SNDOPEN;
						CANRCR |= 0x1111;
						break;
					}
					else if(s_wCANRcvData==0x10)
					{
						s_pCANRcvPointer = s_wCANCommBuffer+8;
						s_wCANRcvData = s_wCANCommBuffer[4]+(s_wCANCommBuffer[5]<<8);
						s_pCANRcvEndPointer = s_wCANCommBuffer+9+s_wCANRcvData*2;
						if(s_wCANRcvData>125) s_pCANRcvEndPointer++;
						if(s_pCANRcvEndPointer<=s_wCANCommBuffer+COMMBUFFERSIZE)
						{
							s_wCANCommStatus = COMMSTATUS_RCV_DATA;
							CANRCR |= 0x1111;
							break;
						}
					}
				}
			}
			CANRCR |= 0x1111;
			OnInitCAN();
		}
		break;
	case COMMSTATUS_RCV_DATA:
		if(CANRCR&0x0010)
		{
			CANReceivePackage();
			s_pCANRcvPointer += CANMSGCTRL0&0x000f;
			if(s_pCANRcvPointer>=s_pCANRcvEndPointer) s_wCANCommStatus = COMMSTATUS_SNDOPEN;
			CANRCR |= 0x1111;
		}
		break;
	case COMMSTATUS_SNDOPEN:
		break;
	case COMMSTATUS_SNDING:
		if(!(CANTCR&0x0040)&&!(CANGSR&0x0001))
		{
			CANSendPackage();
			if(s_pCANSndPointer>=s_pCANSndEndPointer) s_wCANCommStatus = COMMSTATUS_SNDCLOSE;
		}
		break;
	case COMMSTATUS_SNDCLOSE:
		if(!(CANTCR&0x0040)&&!(CANGSR&0x0001)) OnInitCAN();
		break;
	default:
		OnInitCAN();
		break;
	}
	OnPollingCANRTR();
}

⌨️ 快捷键说明

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