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

📄 mainboard_can_ricardo.c

📁 microcontroller pid implementation
💻 C
字号:
#include <p18f4580.h>
#include <stdlib.h>
#include <stdio.h>
#include <delays.h>
#include <pwm.h>
#include <timers.h>
#include <usart.h>
#include <adc.h>
#include <spi.h>

#pragma config OSC=HSPLL
#pragma config PWRT = OFF
#pragma config WDT = OFF
#pragma config MCLRE = ON

#define sentido PORTAbits.RA3    //=0
#define FRENTE 0
#define TRAS 1

#define CAN_FULL 0x01
#define CAN_EMPTY 0x00

#define BUF0_FULL 0x03
#define BUF0_EMPTY 0x04

void config(void);
void comando(void);
void WriteDac(void);
void read_encoder(void);
void int_rx(void);      //FUN钦ES DAS
void desempate(void);   //   INTERRUP钦ES
void pid(void);

//Interrup玢o TIMER 0
#pragma code HighVector=0x08
void interrupt_high(void)
{
   _asm 
   goto desempate
   _endasm
}

//Interrup玢o recep玢o USART
#pragma code low_vector=0x18
void interrupt_low(void)
{
   _asm goto 
      int_rx 
   _endasm
}
#pragma code

unsigned char trama[20];
unsigned char indice=0,nt=0;
unsigned int vel_to_dac=0;
unsigned char Print_enc_vel=0;
unsigned long contador=0;      //guarda o valor actual lido do encoder
unsigned long ult_contador=0;   //guarda o ultimo valor lido do encoder
unsigned char vel_to_print = 0;
unsigned char i=0;
unsigned int velref=0;
unsigned int aux=0; 
//---vari醰eis relacionadas com o controlador PID---//
unsigned int velocidade_ant=0;
signed int erro=0;
signed int erro_ant=0;
signed int erro_ant_ant=0;
signed int P=0;
signed long  P_grande=0;
signed int I=0;
signed long I_grande=0;
signed int D=0;
signed long D_grande=0;
//---Valores de KP,KI e KD
//--Kp=Kp*100 devido a erros de c醠culo multiplica-se por 100 e no fim dos c醠culos divide-se 
signed long Kp=230;
//signed long Kp=20;
//signed long Kp=50;
//--Ki=Ki*100*0.2 devido a erros de c醠culo multiplica-se por 100 e por 0.2(amostragem).No final das
//divide-se tudo por 100
//signed long Ki=10;
//--Ki=Ki*100*0.04
signed long Ki=13;
//--Kd=(Kd/0.2)*100
//signed long Kd=420; 
//signed long Kd=30;
//------------------------------------------------//

unsigned char CAN_RECEIVE;
unsigned char BUFFER;
unsigned char vel_from_can=0;
unsigned char last_vel_from_can=0;

//vari醰eis usadas com mensagens de CAN recebidas
unsigned long idR;         //ID da mensagem recebida
unsigned char dataR[8];      //Dados da mensagem recebida
unsigned char datalenR;      //Tamanho da mensagem recebida
      
unsigned char std_ext;      //vari醰el que verifica o id da mensagem (STANDARD ou EXTENDED)
unsigned int idO;         //vari醰el que guarda o id de ORIGEM
unsigned int idD;         //vari醰el que guarda o id de DESTINO
unsigned int idF;         //vari醰el que guarda o id de FUN敲O

//signed long velocidade=0;         //vari醰el que guarda valor da velocidade
unsigned int velocidade=0;

unsigned char encoder1=0;
unsigned char encoder2=0;
unsigned char encoder3=0;
unsigned char encoder4=0;

//vari醰el que limpa os contadores e a velocidade antes de iniciar
unsigned int sinal_inicio=1;

unsigned char envia_dados_sinaletica=0;


#pragma interrupt desempate
void desempate(void){


    //-----Interrup玢o do timer 0 para ver a velocidade actual e actualiza-la-----//
   if (INTCONbits.TMR0IF == 1)
   {
      
     //valor a por os valores no High byte e Low byte do timer 0 para uma temporiza玢o de 200ms
     TMR0H = 194;
     TMR0L = 246;

     //TMR0H = 243;
     //TMR0L = 202;

      //Leitura do valor do encoder para determinar a velocidade actual 
      ult_contador = contador;
      read_encoder();
      envia_dados_sinaletica = 1;
      vel_to_print = 1;

     //C醠culo da velocidade actual->multiplica玢o para obter a velocidade em mm/s
     velocidade = (unsigned int)(46 * (contador - ult_contador)/50);

        //printf(">velocidade=%u\n\r",velocidade);

  		if(velocidade>velref-150 && velocidade<=velref+150)
  		{
         printf(">velocidade porreira!!!\n\r");

         aux=velref-velocidade;

         velocidade=velocidade+aux;           
           
   		 vel_to_dac=((((unsigned int)velocidade)*28)/100);

   		 WriteDac();

   		 return 0;
  		}	
 
      //Actualiza玢o da velocidade ao chamar o controlador PID
     pid();
     
          //C醠culo da velocidade para enviar para o DAC
     vel_to_dac=((((unsigned int)velocidade)*28)/100);

  
    //Escrita do valor de velocidade no DAC 
      WriteDac();
      
     INTCONbits.TMR0IF = 0;   //clear interrupt flag
      
   }
      //----Recebimento dos valores de velocidade por can----//
   if(PIR3bits.RXB0IF == 1)
   {
      PIR3bits.RXB0IF = 0;

      // Check if buffer is ready.
      if ( RXB0CONbits.RXFUL )
      {
            if ( COMSTATbits.RXB0OVFL )   COMSTATbits.RXB0OVFL = 0; // Forget any previous overflow
         
            std_ext = RXB0SIDLbits.EXID; //1 = extended message; 0 = standard message
            datalenR = RXB0DLC;   //n鷐ero de bytes da mensagem recebida
                  
            dataR[0] = RXB0D0;   //dados recebidos
//            dataR[1] = RXB0D1;
//            dataR[2] = RXB0D2;
//            dataR[3] = RXB0D3;
//            dataR[4] = RXB0D4;
//            dataR[5] = RXB0D5;
//            dataR[6] = RXB0D6;
//            dataR[7] = RXB0D7;
      
            RXB0CONbits.RXFUL = 0;      //Clear Receive Full Status bit (Buffer 0)
      
            idO = (RXB0SIDH & 0xf);         //id da mensagem recebida
            idD = ((RXB0SIDH & 0xf0) >> 4);
            idF = (RXB0SIDL >> 5);
               
            
            if(idD == 0xF)
            {
               if(dataR[0] == 0x02)      // TIME SLOT =2? envia vel em mm/s para WebSIM
               {
                     //Check if the Tx Buffer 0 is ready to transmit
                     if(TXB0CONbits.TXREQ == 0)
                     {
                        //(0x08 = 0000 0001 000 -> Destino: PC; Fonte: Main (0x1); Fun玢o: )
                        
                        //velocidade = 0x0101;
                        TXB0SIDH = 0b00000001;   //ID da mensagem
                        TXB0SIDL = 0b00000000;   //SIDH: SID10 - SID3; SIDL: SID2 - SID0 mais o bit EXIDE = 0 -> message will transmit standard ID
                        TXB0D0 = (velocidade/256);      //DATA da mensagem
                        TXB0D1 = (velocidade % 256);
                        TXB0DLC = 0x02;         //TAMANHO da mensagem
                        TXB0CONbits.TXREQ = 1;   //Set message for transmission
                     }
               }//end if(dataR[0] == 0x02)

				if(dataR[0] == 0x03)      // TIME SLOT =3? envia vel em mm/s e pulsos encoder para sinal閠ica
                {

					if(envia_dados_sinaletica == 1)
					{
	                    //Check if the Tx Buffer 0 is ready to transmit
	                    if(TXB0CONbits.TXREQ == 0)
	                    {
	                        //(0x308 = 0110 0001 000 -> Destino: Sinal閠ica; Fonte: Main (0x1); Fun玢o: )
	                        
	                        TXB0SIDH = 0b01100001;   //ID da mensagem
	                        TXB0SIDL = 0b00000000;   //SIDH: SID10 - SID3; SIDL: SID2 - SID0 mais o bit EXIDE = 0 -> message will transmit standard ID
							TXB0D0 = 0xFF;
							TXB0D1 = 0x0F;
	                        TXB0D2 = (velocidade/256);
	                        TXB0D3 = (velocidade % 256);
							TXB0D4 = encoder1;	//8 bits MSB
							TXB0D5 = encoder2;
							TXB0D6 = encoder3;
							TXB0D7 = encoder4;	//8 bits LSB
	                        TXB0DLC = 0x08;         //TAMANHO da mensagem
	                        TXB0CONbits.TXREQ = 1;   //Set message for transmission
						}

						envia_dados_sinaletica = 0;
					}
				}//end if(dataR[0] == 0x03)
            } // fecha time slot 
   
            //Mensagem recebida do PC - Velocidade
            //(0x80 = 0001 0000 000 -> Destino: Mainboard; Fonte: PC; Fun玢o: )
            
 /*           if(idD == 0x1)
            {

            	vel_from_can= dataR[0];   
               
                if (vel_from_can != last_vel_from_can)
                {   
                     if(dataR[0] <101)
					 {
                        sentido=FRENTE;
                        velref =  dataR[0];
                        vel_to_dac=(unsigned int)((velref*28)/100);
                        WriteDac();
						      
                     }
                                 
                     if (dataR[0] >100)
                     {
                        sentido=TRAS;
                        velref =  dataR[0]-100;                        
                        vel_to_dac=(unsigned int)((velref*28)/100);
						WriteDac();
						
                     }

                     last_vel_from_can = vel_from_can;
                  }      

            }*/    // CAN de Velocidade vindo do CAN      
      }         //fecha tratamento de teste de recep玢o CAN
   }            //fecha decis鉶 CAN

}

#pragma interruptlow int_rx
void int_rx (void)
{
   unsigned char recebeu=0;
   //PIR1bits.RCIF=0; //quando a usart 

⌨️ 快捷键说明

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