Autor Tema: Problema interrupción Rx con PIC18F46k22  (Leído 1856 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Danicap

  • PIC10
  • *
  • Mensajes: 3
Problema interrupción Rx con PIC18F46k22
« en: 01 de Marzo de 2017, 06:34:06 »
Hola a todos,

Estoy intentando diseñar un control MODBUS sobre unos ventiladores electrónicos. La comunicación MODBUS la estoy realizando con LT1481 basado en la UART1 del PIC18F46k22.
Cuando le envío la trama de datos correspondiente a la actuación sobre el ventilador, este comienza a funcionar correctamente a las rpm que le estipule. El problema viene dado al mandarle la trama de datos que le indica que ha de enviarme la información de la que dispone el ventiladro por MODBUS (V,A,rpm,W, Alarmas....), puesto que no entra en la rutina de interrupción.
La comunicación ha de ser a 9600 baudios y 8 bits.

Estoy trabajando con MPLAB 8.92 y el compilador C18, no había trabajado antes con ellos por lo que igual estoy configurando algo erróneamente en las interrupciones. Os dejo el código por si podéis echarme una mano:

Código: C
  1. #include <p18f46k22.h>
  2. //#include <usart.h>
  3.  
  4. /*  PIC Configuratings */
  5.  
  6. #pragma romdata config
  7.         #pragma config  FOSC = INTIO67, PLLCFG = OFF, PRICLKEN = ON, FCMEN = OFF, IESO = OFF
  8.         #pragma config  PWRTEN = OFF, BOREN = OFF, BORV = 285   //Normal
  9.         #pragma config  WDTEN = ON, WDTPS = 32768
  10.         #pragma config  PBADEN = OFF, HFOFST = OFF, MCLRE = EXTMCLR
  11.         #pragma config  STVREN = ON, LVP = OFF, XINST = OFF, DEBUG = OFF
  12.         #pragma config  CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF
  13.         #pragma config  CPB = OFF, CPD = OFF
  14.         #pragma config  WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
  15.         #pragma config  WRTC = OFF, WRTB = OFF, WRTD = OFF
  16.         #pragma config  EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
  17.         #pragma config  EBTRB = OFF
  18. #pragma romdata
  19.  
  20. /* INITIALIZE VARIABLES */
  21.  
  22. unsigned int CRC;
  23. unsigned char Buffer_Tx[8] = {0x01,0x04,0x00,0x00,0x00,0x22,0x70,0x13};                 //Data frame to get info from the fan
  24. //unsigned char Buffer_Tx[8] = {0x01,0x06,0x00,0x42,0x02,0xBC,0x69,0xFB};               //Data frame to actuate on the fan
  25. unsigned char Buffer_Rx[128];
  26. unsigned char Buffer_Rx_Aux[100];
  27. unsigned int RxBuffer = 0;
  28. unsigned int Alarma1_H, Alarma1_L, Alarma2_H, Alarma2_L;
  29. unsigned int Alarma1, Alarma2;
  30. void USART_initialize(void);
  31. unsigned int CRC16 (unsigned char *dirBuffer, unsigned char BytesBuffer);
  32. void RX_Buffer_initialize(void);
  33. void sendData(void);
  34. void VectorInterrupcionAlta     (void);
  35. void RutinaInterrupcionAlta     (void);
  36. int i;
  37.  
  38. void main() {
  39.         TRISC = 0b11000000;
  40.         USART_initialize();                             //Initialize USART module
  41.         RX_Buffer_initialize();
  42.         OSCCONbits.IRCF = 0b111;                        //Configure Clock Speed to 16 Mhz
  43.         //Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE &
  44.         //                USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 27);
  45.        
  46.        
  47.        
  48.         CRC = CRC16(&Buffer_Tx[0],6);           //Obtains CheckSUM
  49.         Buffer_Tx[6] = (unsigned char)(CRC & 0x00FF);
  50.         Buffer_Tx[7] = (unsigned char)((CRC >> 8) & 0x00FF);
  51.  
  52.         while(1)
  53.         {
  54.        
  55.                 sendData();             //Send Data frame by MODBUS
  56.        
  57.                 Alarma1_H = Buffer_Rx[23];
  58.                 Alarma1_L = Buffer_Rx[24];
  59.                 Alarma1 = ((Alarma1_H<<8)&0xFF00) + Alarma1_L;  //Gets Alarma1 code
  60.                 Alarma2_H = Buffer_Rx[37];
  61.                 Alarma2_L = Buffer_Rx[38];
  62.                 Alarma2 = ((Alarma2_H<<8) & 0xFF00) + Alarma2_L;        //Gets Alarma2 code
  63.                  
  64.                 if(Alarma1 != 0 | Alarma2 !=0)
  65.                 {
  66.                         PORTCbits.RC2 = 1;  //Activate Relay if alarm detected
  67.                 }
  68.                 RxBuffer = 0;
  69.           }
  70. }
  71. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  72. //+INTERRUPT SERVICE ROUTINE
  73. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  74.  
  75. //-----------------------------------------------------------------------------
  76. //- HIGH INTERRUPT Addressing                                                   -
  77. //-----------------------------------------------------------------------------
  78. #pragma code VectorInterrupcionAlta = 0x08
  79. void VectorInterrupcionAlta (void)
  80. {
  81.   _asm                 
  82.     goto RutinaInterrupcionAlta
  83.   _endasm
  84. }
  85. //-----------------------------------------------------------------------------
  86. //- HIGH INTERRUPT Function                                                             -
  87. //-----------------------------------------------------------------------------
  88. #pragma code
  89. #pragma interrupt RutinaInterrupcionAlta
  90.  
  91. void    RutinaInterrupcionAlta  (void)
  92. {
  93.         if (PIR1bits.RC1IF)
  94.         {       //UART1-BUCLE
  95.                 if (RCSTA1bits.FERR)
  96.                 {       //Detect an error in the received byte
  97.                
  98.                 }
  99.                 PIE1bits.RC1IE  = 0;                    //Disable interrupts
  100.                 //Read USART data
  101.                 Buffer_Rx[RxBuffer] = RCREG;    //Read RX register
  102.                 //Buffer_Rx[RxBuffer] = Read1USART();
  103.                 RxBuffer++;
  104.                 PIR1bits.RC1IF = 0;                     //Clear rx flag
  105.                 PIE1bits.RC1IE  = 1;                    //Enable interrupts again
  106.         }
  107. }
  108. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  109. //+USART INICIALIZATION
  110. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  111.  
  112. void USART_initialize(void){
  113.  
  114. //Configuration TX and RX pins
  115. TRISCbits.RC6 = 1;              //TX intput
  116. TRISCbits.RC7 = 1;              //RX input
  117.  
  118. //TXSTA: Transmit Status and Control Register
  119. TXSTA1bits.SYNC = 0;    //Asynchronous mode
  120. TXSTA1bits.TX9 = 0;     //8bit transmission
  121. TXSTA1bits.BRGH = 0;    //Set LOW Baud rate
  122. TXSTA1bits.TXEN = 1;    //Enable transmitter
  123. TXSTA1bits.SENDB = 0;   //Disable break
  124.  
  125. //RCSTA: Receive Status and Control Register
  126. RCSTA1bits.SPEN = 1;    //Serial Port enabled
  127. RCSTA1bits.RX9 = 0;     //8bit reception
  128. RCSTA1bits.CREN = 1;    //Enables Receiver
  129.  
  130. //Test bits
  131. //RCSTAbits.FERR = 0;   //No framing error, cleared by reading
  132. //RCSTAbits.OERR = 0;   //No Overrun error, cleared by clearing CREN
  133.                         //Disable receiver CREN 0
  134.  
  135. //BAUDCON Control register
  136. BAUDCONbits.BRG16 =0;   //8bit baud rate generator
  137. //OSCCON = 0x66;
  138. //SPBRG = 0xCF;
  139. OSCCONbits.IRCF = 0b111;//Configure Clock Speed to 16 Mhz
  140. SPBRG = 25;             // Set to 9600 baud rate, 16Mhz, High Speed, BRG16
  141. //Test bits
  142. //BAUDCONbits.RCIDL = 0;//Receive in progress
  143.  
  144. // USART interrupts configuration
  145. RCONbits.IPEN   = 1;    // ENABLE interrupt priority
  146. INTCONbits.GIE  = 1;    // ENABLE interrupts
  147. INTCONbits.PEIE = 1;    // ENABLE peripheral interrupts.
  148. PIE1bits.RC1IE  = 1;    // ENABLE USART receive interrupt
  149. PIE1bits.TX1IE  = 0;    // DISABLE USART TX interrupt
  150. IPR1 = 0b00110000;              // SET RC1 Interrupt as HIGH PROPRITY
  151. }
  152.  
  153. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  154. //+CHECKSUM CALCULATE
  155. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  156. unsigned int    CRC16                                           (unsigned char *dirBuffer, unsigned char BytesBuffer)
  157. {
  158.         //------------------------------
  159.         unsigned char   crc16tmp;
  160.         unsigned int    crc16;
  161.         //------------------------------
  162.         for(crc16=0xFFFF; BytesBuffer!=0; BytesBuffer--)
  163.         {
  164.       crc16 ^= *dirBuffer++;
  165.       for(crc16tmp =0; crc16tmp <8; crc16tmp++)
  166.       {
  167.          if(crc16 & 0x0001)
  168.             crc16 =(crc16>>1)^0xA001;
  169.          else
  170.             crc16 >>=1;
  171.       }
  172.    }
  173.    return(crc16);
  174.  
  175. }
  176.  
  177. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  178. //+BUFFER INICIALIZATION
  179. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  180.  
  181. void RX_Buffer_initialize(void){
  182.  
  183. for (i=0;i<128;i++)
  184. {
  185.         Buffer_Rx[i] = 0x00;
  186. }
  187. }
  188.  
  189. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  190. //+SEND DATA
  191. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  192.  
  193. void sendData(void)
  194. {
  195.         //RS485 in SEND MODE
  196.         PORTCbits.RC0 = 1;              //Bit C0 set to 5V
  197.         PORTCbits.RC1 = 1;              //Bit C1 set to 5V
  198.         //TXSTA1bits.TXEN = 1;  //Start the transmitter
  199.         for(i=0;i<8;i++)
  200.         {
  201.                 TXREG1 = Buffer_Tx[i];
  202.                 Buffer_Rx_Aux[i] = Buffer_Tx[i];
  203.                 while (TXSTA1bits.TRMT == 0){};
  204.                 //Write1USART(Buffer_Tx[i]);
  205.         }      
  206.         //TXSTA1bits.TXEN = 0;  //Stop the transmitter
  207.         //RS485 in RECEIVE MODE
  208.         PORTCbits.RC0 = 0;              //Bit C0 set to 0V
  209.         PORTCbits.RC1 = 0;              //Bit C1 set to 0V
  210. }

Muchas gracias!!!

Saludos!!

Desconectado Danicap

  • PIC10
  • *
  • Mensajes: 3
Re:Problema interrupción Rx con PIC18F46k22
« Respuesta #1 en: 02 de Marzo de 2017, 04:28:17 »
Hola de nuevo,

tras un largo día de estrujarme los sesos y que al pasar por la almohada siempre vienen las grandes ideas he conseguido resolver el problema!!!  :-/ :-/

Revisando mas a fondo el Datasheet del micro, me he dado cuenta de que había que utilizar la sentencia ANSELC = 0x00; (con poner C6 y C7 sería suficiente) para que los pines queden configurados correctamente como Tx y Rx respectivamente.

Una vez hecho eso ya me entraba en la interrupción del puerto Serie pero debido a la rapidez con la que la trama de datos se enviaba constantemente chocaba con la recepción y se mezclaban datos, por lo que la solución ha sido implementar una interrupción del TMR0 que se ejecute cada segundo para habilitar el envío de la trama de datos de adquisición de info 1 vez por segundo y así no interfiera con la recepción de datos mediante la interrupción serie.