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

📄 can.c

📁 关于2407控制电机及数据通讯的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
   CANMBX2A=0x0000;  /*邮箱2信息初始化*/
   CANMBX2B=0x0000;
   CANMBX2C=0x0000;
   CANMBX2D=0x0000;
    
   CANMCR=0x0103; 
   CANMSGID3H=0x6000; /*设置邮箱3的控制字及ID,IDE=0标准标示符,AME=0禁止屏蔽,标准方式为MSGID2H[12-2]*/
   CANMSGID3L=0x0000;  
   CANMSGCTRL3=0x08; /*数据长度DCL=8,RTR=0数据帧*/ 
   CANMBX3A=0x0201;  /*邮箱3信息初始化*/
   CANMBX3B=0x0403;
   CANMBX3C=0x0605;
   CANMBX3D=0x0807;
   CANMCR=0x0480;/*DBO=1,ABO=1,STM=0*/
   CANMDER=0x4C; /*使能邮箱2,3,邮箱2配置成接收,3发送*/   
   CANIMR=0xF7FF;  /*中断MBX3不使能,*/
   CANIFR=0xFFFF; /*清全部中断标志*/  
}
 
 
void SYSINIT(void)
{
         asm("  SETC INTM  ");      /*关总中断*/
        asm("  CLRC SXM  ");       /*抑制符号扩展*/
        asm("  CLRC OVM  ");       /*累加器中结果正常溢出*/
        asm("  CLRC CNF  ");       /*B0区被配置为数据空间*/
        SCSR1=0x83FE;              /*时钟2倍频,CLKIN=15M,CLKOUT=30M*/
        WDCR=0x00E8;               /*不使能WDT*/
        IMR=0x0000;                /*屏蔽所有CPU中断*/
        IFR=0xFFFF;                /*清全部中断标志*/
        MCRA=0xC5FB;               /*p116配置IOPA2-SONAR,IOPB1-PWM4,IOPB3-PWM6,IOPB4-DIR1,IOPB5-DIR2*/
        MCRB=0xFEC3;               /*配置IOPC2,3-码盘,IOPC4,5-灯,IOPD0*/
        MCRC=0xF383;               /*配置IOPE2-PWM8,IOPE3-6:BRAKE1-4,IOPF2-DIR3,IOPF3-DIR4*/
      
        /*MCRA=0xCFFF;配置IOPB4,IOPB5,XINT1*/
        /*MCRB=0xFE03;配置IOPC2-IOPC7,IOPD0*/
        /*MCRC=0xF387;配置IOPF2,IOPF3,IOPE3-6*/  
        
        PBDATDIR=0xFF00;           /*设置IOPB输出低电平*/
        PCDATDIR=0x3000;           /*设置IOPC4,5输出低,其余输入*/
        PDDATDIR=0xFFFF;           /*设置IOPD0输出为高电平*/
        PEDATDIR=0xFFFF;           /*设置IOPE输出高电平*/
        PFDATDIR=0xFF00;           /*设置IOPF输出为低电平*/ 
        
        /*PBDATDIR=0xFF00;设置IOPB4,5输出低电平*/
        /*PCDATDIR=0x0000;设置IOPC2-7输入*/
        /*PDDATDIR=0xFFFF;设置IOPD0输出为高电平*/
        /*PEDATDIR=0x0000;设置IOPE3-6输入*/
        /*PFDATDIR=0xFF00;设置IOPF2,3输出为低电平*/ 
        
        ACTRA=0x0666;              /*PWM6,4,2低有效,PWM5,3,1高有效*/
        ACTRB=0x0666;              /*PWM8低有效,PWM7高有效*/
        DBTCONA=0x02E7;            /*使能死区定时器3,2,1,死区周期为3,9分频*/
        DBTCONB=0x02E7;            /*使能死区定时器6,5,4,死区周期为3,9分频*/          
        CMPR1=48;  
        CMPR2=48;
        CMPR3=48;
        CMPR4=48;
        
        T1PR=TxPR;
        T3PR=TxPR;
        /*T1PR=95;
        T3PR=95; */
        T2PR=0xFFFF;
        T4PR=0xFFFF;
        T1CNT=0;
        T2CNT=1000;
        T3CNT=0;
        T4CNT=1000;
        GPTCONA=0x0006;
        GPTCONB=0x0006;            /*禁止定时器比较输出,T4低有效,T3高有效*/
        EVAIMRA=0x0000;            /*禁止定时器1的中断,禁止比较单元1-3的中断,禁止功率驱动保护中断*/
        EVAIMRB=0x0000;            /*禁止定时器2的中断*/
        EVAIMRC=0x0004;            /*使能CAP3中断,禁止CAP1,CAP2中断*/
        EVBIMRA=0x0080;            /*使能定时器3的周期中断,禁止比较单元4-6的中断,禁止功率驱动保护中断*/
        EVBIMRB=0x0000;            /*禁止定时器4的中断*/
        EVBIMRC=0x0004;            /*使能CAP6中断,禁止CAP4,CAP5中断*/
        EVAIFRA=0xFFFF;
        EVAIFRB=0xFFFF;
        EVAIFRC=0xFFFF;
        EVBIFRA=0xFFFF;
        EVBIFRB=0xFFFF;
        EVBIFRC=0xFFFF;
        COMCONA=0xA600;            /*使能比较操作,使能比较输出,下溢或周期匹配时重装载比较和方式控制寄存器*/
        COMCONB=0xA600;            /*禁止比较操作,禁止比较输出,下溢或周期匹配时重装载比较和方式控制寄存器*/
        T1CON=0x1442;              /*连续增计数模式,预分频为16,定时器计数使能,使用内部时钟*/
        T3CON=0x1442;
        T2CON=0x1872;              /*定向增减计数模式,使能定时器操作,使用正交编码脉冲电路作为时钟输入*/
        T4CON=0x1872;
        CAPCONA=0x7404;            /*使能QEP1,2,CAP3(T1,检测上升沿)*/
        CAPCONB=0x7404;            /*使能QEP3,4,CAP6(T3,检测上升沿),禁止CAP6*/
        /*PBDATDIR=0xFF00;设置IOPB4,5输出高电平*/
        /*PFDATDIR=0xFF04;设置IOPF2输出高电平,IOPF3输出低电平IOPF6输出低电平*/
        /*PDDATDIR=0xFFFF;设置IOPD0输出为高电平*/ 
        
         /********以下是串口初始化***********/ 
   
  SCICCR=0x0007;             /*空闲线多处理器模式,8位数据,1位停止位,无奇偶校验*/
  SCICTL1=0x0013;            /*接收使能,SLEEP=0,SW RESET=0*/
  SCICTL2=0x0002;            /*接收中断使能*/
  /*SCIHBAUD=0x0001;
  SCILBAUD=0x0086;           波特率为9600,systemclk=30M*/ 
  SCIHBAUD=0x0001;
  SCILBAUD=0x0038;           /*波特率为9600systemclk=24M*/
  SCICTL1=0x0033;            /*串口初始化完成,SW RESET=1*/
  SCIPRI=0x0060;             /*一旦仿真挂起,在完成当前的接收/发送操作后停止*/
  
     /**********************************/  
        IMR=0x001a;                /*开CPU中断INT2,开INT4,开int5*/
       /*IMR=0x000A;开CPU中断INT2,开INT4*/
        asm("  CLRC INTM  ");      /*开总中断*/
}
void UpdatePosition(PID*pid)         /*获取码盘数值*/
{
        pid->count=T2CNT;
        if((EVAIFRB&0x0001)==1)
        {
        	EVAIFRB=0x0001;
    	        (pid->overflow)++;
        }
        
        
        pid->mposition=(pid->count+65536*(pid->overflow)-1000);
        
}
void UpdateTrajectory(PID*pid)
{
        if(pid->saturated==0)
        {
        	if(pid->phase==1)
                {
                        if(pid->v<pid->vlimit)
                              {pid->v+=accel;}
                        else
                              {(pid->even_cnt)++;}
                        pid->pdist-=pid->v;
                        pid->position+=pid->v;
                        if(pid->pdist<0)
                              {pid->phase=0;}
                }
                else 
                {
                	if(pid->even_cnt>0)
                              {(pid->even_cnt)--;}
                        else if(pid->v>0)
                              {pid->v-=accel;}
    	                else
    	                      {pid->move=0;
    	                       PBDATDIR=0xFF00;
    	                      } 
    	                pid->position+=pid->v;
    	        }
        }
}

void calcPID(PID*pid,int k)
{
        /*asm("  SETC SXM  ");*/
        unsigned int Kp=pid->Kp;
        unsigned int Ki=pid->Ki;
        unsigned int Kd=pid->Kd;
        UpdatePosition(&control[k]);
        UpdateTrajectory(&control[k]);
        n++;
        if((n%30)==0)
        { n=30;
          if(t<150)
          {
        	fb[t]=pid->mposition;
        	t++;
          }             
        }
        pid->e0=(pid->mposition-pid->position);
        /*pid->PID_OUT=Kp*(pid->e0);
        if(pid->saturated==0)
        {
        	pid->e_sum+=pid->e0;
        }
        pid->PID_OUT+=(Ki*(pid->e_sum));*/
        pid->de=(pid->e0-pid->e1);
        /*pid->PID_OUT+=(Kd*(pid->de));
        pid->PID_OUT=(pid->PID_OUT)/10;*/
        j=(pid->e0)/6;
        if(j>7)
        {
        	j=7;
        }
        else if(j<-7)
        {
        	j=-7;
        }
        m=fabs(j);
        pid->PID_OUT=a[m]*(pid->e0)+(100-a[m])*(pid->de);
        
        if(pid->PID_OUT>3375)
        {
                pid->PID_OUT=3375;
        } 
    
        else if(pid->PID_OUT<-3375)
        {
    	        pid->PID_OUT=-3375;
        }
        
        pid->DUTYCYCLE=(pid->PID_OUT)/2/(pid->PID_MAX)+50;
        pid->e1=pid->e0;
        pid->saturated=0;
        
        if(pid->DUTYCYCLE<6)
        {	
  	        pid->DUTYCYCLE=6;
                pid->saturated=1;
        }
        else if(pid->DUTYCYCLE>94)
        {
  	        pid->DUTYCYCLE=94;
                pid->saturated=1;
        }

        CMPR1=(pid->DUTYCYCLE)*PERIOD/100;
        /*CMPR2=(pid->DUTYCYCLE)*PERIOD/100;*/
  
}
   
void main(void)
{ 
        int h=1;
        varinit();
        initPID();
        SYSINIT(); 
        caninit();
        Tdata((char*)c_prompt); 
        if(h==0)
        {
           CANTCR=0x20;/*TRS3=1邮箱3请求发送*/  
           while(CANTCR&0x2000==0) continue; /*等待发送应答TA3=1则发送成功 */   
           CANTCR=0x2000;      /*清TA3\MIF3标志位*/
           while(CAN_FLAG==0) continue;
           CAN_FLAG=0;
           CANMDER=0x0000;
           CANMCR=0x0100; /*cDr=1改变数据请求*/           
           cantemp=CANMBX2A;
           Tfdata((float)cantemp,0); 
           cantemp=CANMBX2B;
           Tfdata((float)cantemp,0);
           cantemp=CANMBX2C;
           Tfdata((float)cantemp,0);
           cantemp=CANMBX2D;
           Tfdata((float)cantemp,0);  
           
           CANMBX3A=CANMBX2A+1; 
           CANMBX3B=CANMBX2B+1; 
           CANMBX3C=CANMBX2C+1; 
           CANMBX3D=CANMBX2D+1;          
           CANMCR=0x0480;/*DBO=1,ABO=1,STM=1*/
           CANMDER=0x04C; /*使能邮箱2,3,邮箱2配置成接收,3发送*/          
        }
        while(1)
        {
                if(SAMPLE==1)                         /*采样周期1ms到*/
                {
                	    ledcount++;
                	    if(ledcount>1000)
                	    {PCDATDIR=0x3000;}
                	    else
                	    {     PCDATDIR=0x30FF;}
                	    if(ledcount==2000) ledcount=0;  /*灯闪烁*/
                	    
                	    FLAG=0;
                        SAMPLE=0;                        
                        if(i==0)
                        {
                        	calcPID(&control[i],i);
                        }                 
                }
                if(uartflag)
                {
                   uartflag=0;
                   uartchuli(data_rx);
                } 
                if(CAN_FLAG==1)
                {
                    CAN_FLAG=0;
                    cantemp=CANMBX2A;
                    Tfdata((float)cantemp,1); 
                    cantemp=CANMBX2B;
                    Tfdata((float)cantemp,1);
                    cantemp=CANMBX2C;
                    Tfdata((float)cantemp,1);
                    cantemp=CANMBX2D;
                    Tfdata((float)cantemp,1);   
                    CANMCR=0x0480;/*DBO=1,ABO=1,STM=1*/
                    CANMDER=0x04C; /*使能邮箱2,3,邮箱2配置成接收,3发送*/ 
                }
                 
        }
        
}

⌨️ 快捷键说明

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