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

📄 main.c

📁 单片机控制的USB与can转换源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}

//函数原型:void CAN_INT1(void) interrupt 0
//无参数,无返回值
//说明:外部中断0服务函数
void CAN_INT0(void) interrupt 0
{
//	INT8U SJA_INT_IR;
	INT8U i;

	EA= 0;
  SJA_CANAdr= SJA_IR;
  i= *SJA_CANAdr;
//	SJA_INT_IR= SJA_IR;			//采集中断寄存器
	switch(i)
	{
		case 0x01:						//SJA1000接收中断
				CAN_DATA_RECEIVE(RecDataFromCan);  //CAN bus接收数据,存入RecDataFromCan;
		break;
		case 0x02:						//SJA1000发送中断
					;
	  break;
	  default:							//其他中断,如仲裁丢失、唤醒等
	  		SJA_Init();
	  break;
	}
	SJA_CANAdr= SJA_RMC;			//将报文计数器减1
	i= *SJA_CANAdr;
	SJA_CANAdr= SJA_CMR;								//释放接收缓冲器
	*SJA_CANAdr= 0x04;
  EA= 1;
}

/*
//数据池处理
//USB数据先接收,接收后判别,如果前两个字节是30 aa,这表明是参数配置数据
//其他数据直接是CAN BUS数据,转发到CAN bus上去
void RecDataFromUSBDeal(void)
{
	INT8U i, j, k;
	//判断是否有数据输入
	if(RecDataFromUsbLength)
	{
	    if((RecDataFromUsb[0]==0x30)&&(RecDataFromUsb[1]==0xaa))   //如果USB总线上输入得数据头两字节是:30 aa,并且数据长度是13,则数据是CAN参数设置数据
	    {
			  i2c_write(0x01, RecDataFromUsb[2]);
              i2c_write(0x02, RecDataFromUsb[3]);
              i2c_write(0x05, RecDataFromUsb[4]);
              i2c_write(0x06, RecDataFromUsb[5]);
              i2c_write(0x07, RecDataFromUsb[6]);
              i2c_write(0x08, RecDataFromUsb[7]);
              i2c_write(0x09, RecDataFromUsb[8]);
              i2c_write(0x0A, RecDataFromUsb[9]);
              i2c_write(0x0B, RecDataFromUsb[10]);
              i2c_write(0x0C, RecDataFromUsb[11]);
              RecDataFromUsbLength= 0;

	    }
	    else if((RecDataFromUsb[0]==0x30)&&(RecDataFromUsb[1]==0x55)&&(RecDataFromUsbLength==2))  //如果USB总线输入数据为:30 55,表明上位机是在查询CAN总线参数
	    {
	    	RecDataFromCanLength= 12;
	    	RecDataFromCan[0]= 0x30;
	    	RecDataFromCan[1]= 0x55;
	    	for(i=0;i<10;i++)
	    	  RecDataFromCan[(2+i)]=  i2c_read((0x02+ i));
	    	  RecDataFromUsbLength= 0;
	    }
	    else                     //其他数据均为需要转发到CAN bus上得数据
	    {
				if((datanum- DataNum1)> 0x0D)		//判断SumDataFromUsb数据池空间是否足够
				{
						for(i= 0; i< RecDataFromUsbLength; i++)				//将数据移入数据池
							SumDataFromUsb[DataNum1+i]= RecDataFromUsb[i];
						FrameNumFromUsb++;														//置标志位
						DataNum1= DataNum1+ RecDataFromUsbLength;
						RecDataFromUsbLength= 0x00;     //清标志位
				}
				else   //数据池满时处理,将最先进数据池的数据清除
				{
						k= SumDataFromUsb[0];
						for(i= 0; i< k; k++)
						for(j= 0; j< datanum; j++)
									SumDataFromUsb[j]= SumDataFromUsb[j+1];
				}
	    }
	}

}*/

//数据池数据处理 RecDataFromCAN
void RecDataFromCANDeal(void)
{
		unsigned char i,*j;
		if(RecDataFromCanLength)		//判断CAN是否有数据输入
		{
						j= EmptyData;
						for(i= 0; i< RecDataFromCanLength; i++)
						//将数据移入数据池
            {
								*EmptyData= RecDataFromCan[i];
                EmptyData++;
            }
						EmptyData= j+ 0x0d;
						if(EmptyData> &SumDataFromCan[datanum])
									EmptyData= &SumDataFromCan[0];
						RecDataFromCanLength= 0;
		}
}

//开中断
void MCU_INT(void)
{
	EA= 1;
	EX0= 1;         //外部中断0使能
  IT0= 0;					//外部中断0低电平触发
  IE0= 0;					//清外部中断0标志位

	EX1= 1;			//外部中断1使能
	PX1= 1;			//中断优先级为高
	IT1= 0;			//外部中断1低电平触发
	IE1= 0;			//清外部中断1标志位

	//串口设置
	//串口操作模式为2,波特率位9600bps/s
	//开串口接收跟发送中断
	TMOD= 0x20;      //选择定时器1,16位
	TL1= 0xfd;	     //定时器初值0xfdH
	TH1= 0xfd;
	SCON= 0x50; 	 //选择模式2
	PCON = 0x00;
  TR1= 1;
	ES= 1;
}

//单片机初始化
void Main_Init(void)
{
	CH375_Init( );		//USB初始化
	SJA_Init();				//SJA初始化
	MCU_INT();				//开中断
	LED_Low= 0;
	USBINFlag= 0;
}

//主函数
void main(void)
{
	unsigned char i;
	unsigned char *buf,*DataBufTemp;						//定义指针
	Main_Init();					//初始化

	while(1)							//循环
	{
			//判断是否有数据需要转发到CAN总线
			if(RecDataFromUsbLength)				//判断DataToCan是否有数据,该数据用于发送到CAN总线上;
			{
				SJA_CANAdr= SJA_SR;			//采集SJA1000T状态
				i= *SJA_CANAdr;
				if((i&0xF8)==0x40)			//判断SJA1000发送缓冲区是否锁定,逻辑1,未锁定;逻辑0,锁定
				{
								CAN_DATA_WRITE(RecDataFromUsb);					//往SJA1000的发送缓冲区写入数据
								RecDataFromUsbLength= 0;									//归零标志位
				}
			}
			//判断是否有数据需要转发到USB总线
			if(DataToUsbLength)				//判断DataToUsb是否有数据,该数据用于发送到USB总线上;
			{
				if(USBINFlag==0)			 //查询USB发送Buffer是否占用,逻辑1,占用;逻辑0,未占用
				{
						CH375_WR_CMD_PORT(CMD_WR_USB_DATA7);  //向USB端点2的发送缓冲区写入数据块
	    			CH375_WR_DAT_PORT(DataToUsbLength);  //首先写入后续数据长度
            buf= DataToUsb;  //指向缓冲区
	   				do{
									CH375_WR_DAT_PORT(*buf);  //写入数据到CH375
									buf++;
	    			}while(--DataToUsbLength);

						//置标志位
						USBINFlag= 1;                  //表明CH372的发送BUFFER锁定
				}
			}
			else if(EmptyData!= CurrentData)  //判断数据池,逻辑1,数据池还有数据;逻辑0,数据池空
		 {
				if((*CurrentData&0x80)==0x80)						//判断该帧数据长度
								DataToUsbLength= (*CurrentData&0x0F)+ 5;
				else
								DataToUsbLength= (*CurrentData&0x0F)+ 3;
				
				DataBufTemp= CurrentData;								//保存当前数据指针

				for(i= 0; i< DataToUsbLength; i++)			//从数据池导出数据
				{			 
								DataToUsb[i]= *CurrentData;
							 	CurrentData++;
				}
				CurrentData= DataBufTemp+ 0x0d;  			//数据池指针处理
				
				if(CurrentData> SumDataFromCan[datanum])
						CurrentData= &SumDataFromCan[0];	
		 }

		 RecDataFromCANDeal();
		 //RecDataFromUSBDeal();
	}
}

//********************************************
//I2C function define
//i2c_write(地址,数据),写一个字节
void i2c_write(unsigned char Address,unsigned char WData)
{
	do{
		i2c_start();
		i2c_send8bit(0xA0);
	}while(i2c_ack());
	i2c_send8bit(Address);
	i2c_ack();
	i2c_send8bit(WData);
	i2c_ack();
	i2c_stop();
}
//i2c_read(地址,数据),读一个字节
unsigned char i2c_read(unsigned char Address)
{
	unsigned char c;
	do{
		i2c_start();
		i2c_send8bit(0xA0);
	}while(i2c_ack()); //=1,表示无确认,再次发送
	i2c_send8bit(Address);
	i2c_ack();

	do{
		i2c_start();
		i2c_send8bit(0xA1);
	}while(i2c_ack());
	c=i2c_receive8bit();
	i2c_ack();
	i2c_stop();
	return(c);
}
//发送开始信号
void i2c_start(void)
{
  SDA=1;   //发送起始条件的数据信号
  _Nop();
  SCL=1;
  _Nop();    //起始条件建立时间大于4.7us,延时
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SDA=0;   //发送起始信号
  _Nop();    // 起始条件锁定时间大于4μs
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SCL=0;   /*钳住I2C总线,准备发送或接收数据 */
  _Nop();
  _Nop();
}

void i2c_stop(void)
{
  SDA=0;  /*发送结束条件的数据信号*/
  _Nop();   /*发送结束条件的时钟信号*/
  SCL=1;  /*结束条件建立时间大于4us*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SDA=1;  /*发送I2C总线结束信号*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();
}
//发送接收确认信号
bit i2c_ack(void)
{
	bit ack;
	SDA = 1;
	SCL = 1;
    _Nop();
    _Nop();               /*保证时钟高电平周期大于4μs*/
    _Nop();
    _Nop();
    _Nop();
	if(SDA==1)
		ack= 1;
	else
		ack= 0;
	SCL= 0;
	return ack;
}


//送八位数据
void i2c_send8bit(unsigned char b)
{
	unsigned char a;
	for(a=0;a<8;a++)
	{
		if ((b << a ) & 0x80)
			SDA = 1;
		else
			SDA = 0;
		SCL = 1;
		_Nop();
        _Nop();               //保证时钟高电平周期大于4μ
        _Nop();
        _Nop();
        _Nop();
		SCL = 0;
	}
}


//接收八位数据
unsigned char i2c_receive8bit(void)
{
	unsigned char a;
	unsigned char b= 0;
	for(a= 0; a< 8; a++)
	{
		SCL = 1;
		_Nop();
        _Nop();               //保证时钟高电平周期大于4μ
        _Nop();
        _Nop();
        _Nop();
		b=b<<1;
	if(SDA==1)
		b=b|0x01; 			//按位或
	SCL = 0;
	}
	return b;
}

//led test
void Led_display(void)
{
		unsigned int i;
		for(i=5000; i>0; i++)  LED_Low= 0;
		for(i=5000; i>0; i++)  LED_Low= 1;
}

⌨️ 快捷键说明

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