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

📄 can.c

📁 基于DSP2407的CAN总线通信程序。该程序应用在石油大学201项目交流互馈实验台
💻 C
字号:
/*-------------------------------------------------------------------------------------------
File Name: CAN.c
Function: 采集整流柜、变流柜1、变流柜2传过来的数,并把它们中的部分数据通过串口发给数显表显示
Date:8/20/2003
-------------------------------------------------------------------------------------------*/

/*include C standard file*/
#include	"stdio.h"
#include	"math.h"
/*include head files*/
#include	"f243_c.h" 
/*#include	"c_pwm1.h"*/
#include    "CAN.h" 

void delay(double time)
{
	double i;
	for (i = 0; i < time; i++)
	{   
		*WDKEY = 0x5555;
		*WDKEY = 0xAAAA;
		i++; i--;
	}
}

void CAN_init()
{
		
	*MCR = 0x1000;      	    /*change configuration request,set CCR=1*/
 	while (!(*GSR & 0x0010));   /*wait for change configuration enable CCE=1*/
	*BCR2 = 0x0004; 		    /*set BRP=1,TQ=(BRP+1)/Iclk*/
	*BCR1 = 0x0523; 		    /*resynchronize on the falling edge only,SJW=1,sample only once,
 						         TSEG1=4,TSEG2=3,Baud rate=20m/(1+1)*(4+3+1+1+1)=1 Mbit/s */
	*MCR = 0x0000;		        /*return in normal operation*/ 
 	while (*GSR & 0x0010);      /*wait for change configuration disable CCE=0*/
	*MDER = 0x00C0;             /*mail2,3 is Receive and disable all mailbox */
	
}

void SCI_init()
{ 
                        	 
	*SCICCR = 0x07;    /* 1 stop bit,no parity,8 char bits, async mode, idle line protocal*/
              
    *SCICTL1 = 0x02;   /*Enable TX; Disalbe RX,RX ERR ,SLEEP,TXWAKE*/
                    
    *SCICTL2 = 0x00;   /* Disable RX INT, Disable TX INT */
              
    *SCIHBAUD = 0x01;
    *SCILBAUD = 0x03;  /* Baud rat =9600 bps */
                       /*BRR=259,波特率=20MHz/[(259+1)*8]=9600 bps*/
    
    temp = *SCITXBUF;  /* Clear the buffers */
    temp = *SCITXBUF;    	
    	
	*SCICTL1 = 0x2A;
    *SCITXBUF = 0x00;

} 

void serial_commu(void)
{  
   /*测试数显表用到*/
   /*Motor_Current++;
   if(Motor_Current >= 0) Motor_Current = -1000; 
   Motor_Volage++;
   if(Motor_Volage >= 0)  Motor_Volage = -1000; 
   DC_Current --;
   if(DC_Current <= -100)    DC_Current = 0; 
   DC_Volage --;
   if(DC_Volage <= -100)     DC_Volage = 0; 
   Motor_Speed ++;
   if(Motor_Speed >= 2000)   Motor_Speed = 1500; 
   Motor_Torque++;
   if(Motor_Torque >= 2000)  Motor_Torque = 1500; 
   Motor_Field ++;
   if(Motor_Field >= 2000)   Motor_Field = 1500; 
   MRun_Fault ++;
   if(MRun_Fault >= 2000)    MRun_Fault = 1500; */
   
   /*伺控台数显表顺序上下左右依次为1,2,3,4号*/
   num[0]=Motor_Current; num[1]=Motor_Volage; num[2]=DC_Current;  num[3]=DC_Volage;
   num[4]=Motor_Speed;   num[5]=Motor_Torque; num[6]=Motor_Field; num[7]=MRun_Fault;
   /*变流柜2,3数显表顺序上下左右依次为1,2,3,4号*/
   /*num[0]=AC_Volage;    num[1]=AC_Current;  num[2]=DC_Current;    num[3]=DC_Volage;
   num[4]=Motor_Torque; num[5]=Motor_Speed; num[6]=Motor_Field;   num[7]=MRun_Fault; */
   
   s = 0;
   for (i=0; i<8; i++)
   { 
     
     ++s;
     num1 = s/10;
     num2 = (s - num1*10); 
     
     if(num[i] >= 0)  numb = num[i];
 	 else if(num[i] < 0)  numb = ~num[i]+1;
     
     thousand = (uint)(numb/1000);
     hundred = (uint)((numb - thousand*1000)/100);
     ten = (uint)((numb - thousand*1000-hundred*100)/10);
     indiv = (uint)((numb - thousand*1000-hundred*100-ten*10));
     
     dis_num[0]=num1; dis_num[1]=num2; dis_num[2]=thousand; dis_num[3]=hundred;
     dis_num[4]=ten;  dis_num[5]=indiv;
     
     for (j =0; j<6; j++)
     { 
      
       
       switch (dis_num[j])
        {
         case  0:   dis_num[j] = 0x30;  break;
         case  1:   dis_num[j] = 0x31;  break;
         case  2:   dis_num[j] = 0x32;  break;
         case  3:   dis_num[j] = 0x33;  break;
         case  4:   dis_num[j] = 0x34;  break;
         case  5:   dis_num[j] = 0x35;  break;
         case  6:   dis_num[j] = 0x36;  break;
         case  7:   dis_num[j] = 0x37;  break;
         case  8:   dis_num[j] = 0x38;  break;
         case  9:   dis_num[j] = 0x39;  break;
         }
       
      }
     
     if(i <4 )         num_array[5]=0x31; 
	 else if(i >= 4)        num_array[5]=0x30;     /*num_array[5]=0x30时显示数显表的第二行*/
     if(num[i] >= 0)   num_array[6]=0x2b; 
	 else if(num[i] < 0)    num_array[6]=0x2d;     /*num_array[6]=0x2d时数显表显示负值*/
        
     num_array[0]=0x04; num_array[1]=dis_num[0]; num_array[2]=dis_num[1]; num_array[3]=0x57;
     num_array[4]=0x30; /*num_array[5]=0x31; num_array[6]=0x2d;*/ num_array[7]=dis_num[2];
     num_array[8]=dis_num[3]; num_array[9]=dis_num[4]; num_array[10]=dis_num[5];
     num_array[11]=0x2e; num_array[12]=0x05;

    for (k = 0; k < 13; k++)
    {
		while(!(*SCICTL2 & 0x80))
		{
			*WDKEY = 0x5555;
			*WDKEY = 0xAAAA;
		}
    	*SCITXBUF = num_array[k];
    	 
    	delay(30);
    	
    	while(!(*SCICTL2 & 0x40))
        {
       		*WDKEY = 0x5555;
			*WDKEY = 0xAAAA;
	    }  
    		
   	}
   		
   if(s >= 4) 	s = 0;
   /*if(i >=3 )   s = 0; */
  }
     	
}   


void sik_prog(void)
{
   sint temp, temp_pa, temp_pb, temp_pd;
   temp_pa = *PADATDIR;
   temp_pb = *PBDATDIR;
   temp_pd = *PDDATDIR;

   /*级位与DSP读数的对应关系:*/   
   temp = *PBDATDIR;                
   stage = (temp & 0x0001) << 5;       /*IOPB0-->XT5*/    /*码排列 XT5,XT6,XT7,XT7,XT8,XT9,XT10*/
   temp = *PBDATDIR;
   stage += ((temp & 0x0002) >> 1);    /*IOPB1-->XT10*/
   temp = *PBDATDIR;
   stage += ((temp & 0x0004) >> 1);    /*IOPB2-->XT9*/
   temp = *PBDATDIR;
   stage += ((temp & 0x0008) >> 1);    /*IOPB3-->XT8*/
   temp = *PADATDIR;
   stage += ((temp & 0x0040) >> 3);     /*IOPA6-->XT7*/
   temp = *PADATDIR;
   stage += ((temp & 0x0080) >> 3);    /*IOPA7-->XT6*/
   
   switch(stage)
   {
   		case  0: stage = 0; break;
   		case 49: stage = 1; break;
   		case 56: stage = 2; break;
   		case 41: stage = 3; break;
   		case 44: stage = 4; break;
   		case 61: stage = 5; break;
   		case 52: stage = 6; break;
   		case 37: stage = 7; break;
   		case 38: stage = 8; break;
   		case 55: stage = 9; break;
   		case 62: stage = 10;break;
   		default: stage = 11;break;
   }
   stage_array[t_step] = stage;        
   
   
   temp = *PDDATDIR;                   
   level = (temp & 0x0040) >> 4;       /*IOPD6-->XT3*/ /*码排列 XT3,XT2,XT1*/
   temp = *PDDATDIR;
   level += ((temp & 0x0080) >> 6);    /*IOPD7-->XT2*/
   temp = *PBDATDIR;
   level += ((temp & 0x0080) >> 7);    /*IOPB7-->XT1*/
   
   switch(level)
   {
   		case 0: level = 0; break;      
   		case 2: level = 1; break;      /*go forward*/
   		case 3: level = 2; break;      /*forward break*/
   		case 4: level = -1; break;     /*bake off*/
   		case 5: level = -2; break;     /*bake break*/
   	
   }           
   level_array[t_step] = level;  
   
   t_step++;
   if (t_step >= T_PER_MAX)   t_step = 0;
}   



void ADC2_start()
{
   ADC2_START;	 
   while(!(ADC2_BUSY));		
   while (ADC2_BUSY);	
   temp = ADC2_DATA;      /*read ADC1 and ADC2 result in sequence*/
   temp = ADC2_DATA;
   suk_sam = ADC2_DATA;
   temp = ADC2_DATA;
   ADC2_STOP;
   suk_sam &= 0x0FFF; 
   if (suk_sam >= 2048)  suk_sam -= 4096;
   suk_sam_temp = (float)suk_sam;
   suk_sam = (int)(suk_sam_temp*1.8181818182);  
} 


 
void CAN_transmit(int data_addr, int stage, int level, int suk_sam)
{
	h++;
	if(h <= 4)
	*PDDATDIR |= 0x1010;
	else if((h > 4) && (h <= 8))
	*PDDATDIR &= ~0x0010;
	else  h = 0;
	 
	if((*TCR & 0x4000))     *TCR = 0x4000;	
	*MDER &= ~0x0010;          /*disable mailboxe 4*/
	*MCR = 0x0100; 		       /*set change data field request*/
	
	*MSGID4H = 0x8000;	        /*MBOX0、1 为接收邮箱,MBOX4、5为发送邮箱,MBOX2、3可配置为接收或发送邮箱*/
	*MSGID4L = data_addr; 	   /*extended identifier,no acceptance mask,don't reply to the remote 
						        requests,high identifier bits=0,low identifier byte=data_addr*/
	*MSGCTRL4 = 0x0006;	       /*data frame,data length=6*/
	
	*MBX4B = stage;            /*邮箱发送次序为

⌨️ 快捷键说明

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