Autor Tema: Mis experiencias con el BUS CAN  (Leído 602550 veces)

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

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #645 en: 16 de Noviembre de 2009, 18:02:29 »
En realidad la estructura original es esta:

Código: C
  1. //PROTOTYPES and MACROS
  2.  
  3. struct rx_stat {
  4.    int1 err_ovfl;
  5.    int filthit:3;
  6.    int1 buffer;
  7.    int1 rtr;
  8.    int1 ext;
  9.    int1 inv;
  10. };

Esa estructura define los bits de status de la recepcion (por eso el nombre) y los filtros utilizados.
En esta operacion:

Código: C
  1. struct rx_stat rxstat;

Se clona (en realidad se llama crear una instancia) esa estructura en otra llamada rxstat, que es la que finalmente utiliza el programa....

Se entiende??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Kid_Bengala

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 409
Re: Mis experiencias con el BUS CAN
« Respuesta #646 en: 18 de Noviembre de 2009, 14:35:38 »
hola

uffff,hace que no toco pic y menos ccs jejeje.voy a implementer bus can en un dspic o pic24 (arquitectura 16bits) ¿tendria algun problema con la libreria de ccs o me toca "retocarla"? gracias.

saludos de antonio

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #647 en: 18 de Noviembre de 2009, 15:48:07 »
Desde la version 4.088 (creo) CCS trae las librerias para CAN exclusivas para DSPIC (can-dspic30.c y .h) y para los PIC24 (can-pic24.c y .h).
Si los buscas en la carpeta drivers veras lo que digo.
No los use personalmente, pero se que estan alli... :mrgreen: :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Kid_Bengala

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 409
Re: Mis experiencias con el BUS CAN
« Respuesta #648 en: 20 de Noviembre de 2009, 11:11:36 »
voy a mirar la versioue tengo y si vienen, muchas gracias.

saludos de antonio

Desconectado sergio_silva

  • PIC10
  • *
  • Mensajes: 6
Re: Mis experiencias con el BUS CAN
« Respuesta #649 en: 06 de Diciembre de 2009, 16:12:58 »
Boas a todos. Em primeiro, sou portugues logo a regra que diz para escrever em espanhol vai ser dificil para mim, mas com o tempo vou tentar começar a escrever em espanhol.

Eu estudo Electrónica e vou começar agora a programar o PIC18F4580, e tenho que ligar 2 PIC´s ( através de uma rede CAN), um para comunicar com o PC ( terminal ) e outro que está ligado a 2 Led´s e a 2 botões. Então, a partir do PC é possível ligar / desligar os Led´s e saber qual o estado dos botões. Eu já estive a ler este tópico e então já fiz o código para o PIC que está ligado aos Led´s e aos botões. Ainda estou à espera que o programador e os PIC´s cheguem, mas entretanto queria ter o código pronto.

Código do Pic: Relembro que este código liga/desliga Led´s consoante a informação que recebe do outro PIC e se os botões forem pressionados informa o PIC .
Código: [Seleccionar]
//#include <18F4580.h>

#FUSES NOWDT                 //No Watch Dog Timer   
#FUSES WDT128                 //Watch Dog Timer uses 1:128 Postscale   
#FUSES HS                     //High speed Osc (> 4mhz)   
#FUSES NOPROTECT             //Code not protected from reading   
#FUSES BROWNOUT               //Reset when brownout detected   
#FUSES BORV21                 //Brownout reset at 2.1V 
#FUSES PUT                   //Power Up Timer 
#FUSES NOCPD                 //No EE protection 
#FUSES STVREN                 //Stack full/underflow will cause reset 
#FUSES NODEBUG               //No Debug mode for ICD 
#FUSES NOLVP                 //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O 
#FUSES NOWRT                 //Program memory not write protected 
#FUSES NOWRTD                 //Data EEPROM not write protected 
#FUSES NOIESO                   //Internal External Switch Over mode enabled 
#FUSES FCMEN                 //Fail-safe clock monitor enabled 
//#FUSES PBADEN                 //PORTB pins are configured as analog input channels on RESET 
#FUSES BBSIZ1K               //1K words Boot Block size 
#FUSES NOWRTC                 //configuration not registers write protected 
#FUSES NOWRTB                 //Boot block not write protected 
#FUSES NOEBTR                 //Memory not protected from table reads 
#FUSES NOEBTRB               //Boot block not protected from table reads 
#FUSES NOCPB                 //No Boot Block code protection 
#FUSES NOLPT1OSC              //Timer1 is not configured for low-power operation 
//#FUSES MCLR                   //Master Clear pin enabled 
#FUSES NOXINST               //Extended set extension and Indexed Addressing mode disabled (Legacy mode) 

#include "can-18F4580.c"

#define PIC_ID 26//identificação deste PIC

#define PIN_LED1  PIN_A0
#define PIN_LED2  PIN_A1

#define LED1_LOW  output_low(PIN_LED1)
#define LED1_HIGH output_high(PIN_LED1)
#define LED2_LOW  output_low(PIN_LED2)
#define LED2_HIGH output_high(PIN_LED2)

#define BUTTON1 PIN_A2
#define BUTTON2 PIN_A3

#define BUTTON_PRESSED1 input(BUTTON1)
#define BUTTON_PRESSED2 input(BUTTON2)

void main()
{
    int led=9;
    int cnt1 = 0;
    int cnt2 = 0;
    int cnt3 = 0;
    int cnt4 = 0;

    //recv message
    struct rx_stat rxstat;
    int32 rx_id;
    int in_data[8];
    int rx_len;
   
    int out_data[8];
    int i = 0;
   
    //clear recv buffer
    for(i=0;i<8;i++)
    {
    in_data[i]=0;
    }

    can_init();
    //can_set_mode(CAN_OP_LISTEN);
   
    while(TRUE)
    {
   
        // mensagem recebida
        if ( can_kbhit() )
        {       
           if(can_getd(rx_id, &in_data[0], rx_len, rxstat))   //se existem dados no buffer in_data, guarda os dados recebidos nas variáveis
           {
              if(rx_id == PIC_ID)  // Se a mensagem é para este PIC
              {
                 led =~ (in_data[0]);                 
                 if(bit_test(led, 0))
                    LED1_HIGH;//turn ON Led 1
                 if(bit_test(led, 1))
                    LED1_LOW;//turn OFF Led 1
                 if(bit_test(led, 2))
                    LED2_HIGH;//tunr ON Led 2
                 if(bit_test(led, 3))
                    LED2_LOW;//turn OFF Led 2               
              }
           }
        }//fim do tratamento da mensagem recebida
   
        if( (!BUTTON_PRESSED1) && (cnt1 == 0) )   // if button 1 is OFF
        {
           out_data[0] = 4;
           can_putd(25, &out_data[0], 1, 1, 1, 0);
           cnt1 = 1;
           cnt2 = 0;
        }
        if( (BUTTON_PRESSED1) && (cnt2 == 0) )   //if button 1 is ON
        {
           out_data[0] = 5;
           can_putd(25, &out_data[0], 1, 1, 1, 0);
           cnt2 = 1;
           cnt1 = 0;
        }
        if( (!BUTTON_PRESSED2) && (cnt3 == 0) )   // if button 2 is OFF
        {
           out_data[0] = 6;
           can_putd(25, &out_data[0], 1, 1, 1, 0);
           cnt3 = 1;
           cnt4 = 0;       
        }
        if( (BUTTON_PRESSED2) && (cnt4 == 0) )   // if button 2 is ON
        {
           out_data[0] = 7;
           can_putd(25, &out_data[0], 1, 1, 1, 0);
           cnt4 = 1;
           cnt3 = 0;
        }       
   
   
    }

}

Se alguém puder analisar o código, é provável que tenha alguns erros.

Obrigado e parabéns pelo fórum que está muito bom!

Saludos, Sérgio Silva

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #650 en: 06 de Diciembre de 2009, 22:21:59 »
Hola Sergio!!
Bienvenido al foro y especialmente a este hilo.

Revisando el codigo, creo que esta bien operativo.
No entiendo lo de los cnt1 a 4.
Supongo es para saber que boton presionaste ultimo, es asi ??

Como comentario, usas la velocidad por defecto que tienen configuradas las librerias de CCS y de Microchip, que es de 125 K, en modo extendido.

Si quieres poner el codigo del otro PIC, podemos analizarlo y ayudar tambien.
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

penguin

  • Visitante
Re: Mis experiencias con el BUS CAN
« Respuesta #651 en: 07 de Diciembre de 2009, 13:14:31 »
Vereis, estoy tratando de enviar datos por can desde mi pic 18f4550 al mcp2510. Veo que se comunica ( aunque después el modulo can no envia nada al transceiver mcp2551). Para ver si mi SPI funciona correctamente, mando unos datos, y por oscilosciopio los puedo leer. De ahí deduzco que mi librería modificada de SPI por hardware es correcta( la can-mcp2510.c).  Pongo eso luego como comentario, y sin mas dilación, envio una trama al Can Controller. Por osciloscopio veo señal de SCK (cada 8 pulsos, pq se envian de 8 en 8 bits) y pretendo ver por la patilla SDO los datos enviados en can. Pues, primero, no veo una señal clara, hay una fija y otra que se va superponiendo ( una guarrada, hablando en plata :)). De ahí deduzco que podría ser acerca de la velocidad, asi que os pongo como determino la velocidad ( y os sonara muuucho a los seguidores de este foro, ya que me baso en él). Uso este circuito :


Para determinar la velocidad: como veis, el cristal es de 20 Mhz tanto en pic como en modulo can, y usando el programa de determinacion de velocidad del sistema, y de cambio en el programa, hago o siguiente ( para 125K y 48M)
Código: C
  1. #ifdef Set_125_Baud {
  2.      BRGCON1 = 0x07;
  3.      BRGCON2 = 0xBE;      //modificado 7/12/09 para usar CAN a 125 KBps
  4.      BRGCON3 = 0x07;      //con reloj a 48 MHz
  5.    }
  6.   #endif
  7.  

a continuacion pongo el main que uso, que no es mas que una modificacion del EX_CAN_CCS_A.C a mi convenencia:
Código: C
  1. #include <18F4550.h>
  2. #include <stdlib.h>
  3. #fuses HS,NOPROTECT,NOLVP,NOWDT,XTPLL,PLL5,NOWDT,NOPROTECT,USBDIV,CPUDIV2
  4. #use delay(clock=48000000)
  5. #include <spi-can-mcp2510.c>
  6. #define CAN_DO_DEBUG TRUE
  7. #define Set_125K_Baud TRUE
  8. #byte   porta = 0xf80
  9. #byte   portb = 0xf81
  10. #byte   portc = 0xf82
  11. #byte   portd = 0xf83
  12. #byte   porte = 0xf84
  13. #byte   t1con = 0xfcd
  14. #byte   latd = 0xf8c
  15. #byte   adcon0 = 0xfc2
  16. #byte   adcon1 = 0xfc1
  17. #byte   adcon2 = 0xfc0
  18. #byte   adresl = 0xfc3
  19. #byte   adresh = 0xfc4
  20.  
  21. #use fast_io (D)
  22. #byte PORTD= 0XF83
  23.  
  24. void main() {
  25.    int dato[8];
  26.    struct rx_stat rxstat;
  27.    int32 rx_id;
  28.    int buffer[8];
  29.    int i,rx_len;
  30.  
  31.    set_tris_d(0x01);
  32.    setup_spi(SPI_MASTER | SPI_H_TO_L|spi_clk_div_4);
  33.  
  34.    rx_id=0x01;
  35.    buffer[0]=0x08;
  36.  
  37.  
  38.  
  39.  
  40.    can_init();
  41.    while(TRUE)
  42.    {
  43.     //spi_write(0x25);
  44.      
  45.       if ( can_tbe()){
  46.        output_high(pin_d1);
  47.        can_putd(0x01,&buffer[0],8,3,TRUE,TRUE);
  48.       }
  49.    }
  50. }
  51.  
  52.  

Como veis esta quitada toda la parte interesante de ese archivo, simplemente para ver que es lo que envio y reconocerlo ( de momento que no reciba el trasnceiver es un mal menor, quiero saber primero lo que va a recibir éste).
Pretendo ver por osciloscopio el  extended frame como por ejemplo, un primer bit que sea 0(inicio) ver el numero de identificador, que deberia ser 0x01 ( con mas ceros por delante  ya que uso  extended), otros 3 ceros, el dato puesto y un seguido de 1's de end of frame. Pero no veo eso, envia algo distinto y lo peor, la señal de sck se ve fija y hay 8 semiciclos que se intercalan de una forma que hace que al ver la señal de SDO tambien se vea muy poco claro. Es pues acerca de una mala configuración de velocidad ?
« Última modificación: 08 de Diciembre de 2009, 10:55:13 por penguin »

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #652 en: 07 de Diciembre de 2009, 15:17:12 »
Antes de seguir con nada, pon el pin Reset del MCP2515 a VDD (5V), ya que no puede quedar al aire, porque tomara un estado indeterminado.
Eso puede ser la causa de tus males...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

penguin

  • Visitante
Re: Mis experiencias con el BUS CAN
« Respuesta #653 en: 07 de Diciembre de 2009, 15:47:06 »
uhm... vaya, tengo el esquema mal, cuando llegue a casa lo modifico.
El pin de reset lo tengo alimentado a Vcc ( con una resistencia de 3K9) y conectado a un pulsador, que al pulsarlo deriva a masa ( como el circuito del boot del pic).
Ahora estoy probando con distintas velocidades para el pic ( cambiando libreria spi can) y sigue en las mismas.

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #654 en: 07 de Diciembre de 2009, 16:54:40 »
Porque no pones aqui todo el codigo que usas y las librerias??
A ver si encontramos algo...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado sergio_silva

  • PIC10
  • *
  • Mensajes: 6
Re: Mis experiencias con el BUS CAN
« Respuesta #655 en: 07 de Diciembre de 2009, 18:46:42 »
Revisando el codigo, creo que esta bien operativo.
No entiendo lo de los cnt1 a 4.
Supongo es para saber que boton presionaste ultimo, es asi ??

Hola, eu utilizo los cnt´s para que lo PIC sólo envia una vez el estado del boton ( cuando é alterado) , de lo contrario lo PIC enviava sempre el estado del bóton.

Lo codigo del outro PIC, ainda no ha termiando, pero cuando terminar eu lo coloco aquí.

Gracias por la ajuda,

Sérgio Silva.

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #656 en: 07 de Diciembre de 2009, 19:21:48 »
OK, entiendo.
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

penguin

  • Visitante
Re: Mis experiencias con el BUS CAN
« Respuesta #657 en: 08 de Diciembre de 2009, 11:05:37 »
Hola MGLSOFT ( y compañia!) he modificado el esquematico. cuelgo el programa en si tal como me pides :

Código: C
  1.  
  2. ///// programa principal ////
  3.  
  4. #include <18F4550.h>
  5. #include <stdlib.h>
  6. #fuses HS,NOPROTECT,NOLVP,NOWDT,XTPLL,PLL5,NOPROTECT,USBDIV,CPUDIV2
  7. #use delay(clock=48000000)
  8. #include <spi-can-mcp2510.c>
  9.  
  10. #define CAN_DO_DEBUG TRUE
  11. #define Set_125K_Baud TRUE
  12.  
  13. #byte   porta = 0xf80
  14. #byte   portb = 0xf81
  15. #byte   portc = 0xf82
  16. #byte   portd = 0xf83
  17. #byte   porte = 0xf84
  18. #byte   t1con = 0xfcd
  19. #byte   latd = 0xf8c
  20. #byte   adcon0 = 0xfc2
  21. #byte   adcon1 = 0xfc1
  22. #byte   adcon2 = 0xfc0
  23. #byte   adresl = 0xfc3
  24. #byte   adresh = 0xfc4
  25. #use fast_io (D)
  26. #byte PORTD= 0XF83
  27.  
  28. void main() {
  29.    struct rx_stat rxstat;
  30.    int32 rx_id;
  31.    int buffer[8];
  32.    int i,rx_len;
  33.  
  34.    set_tris_d(0x01);
  35.    setup_spi(SPI_MASTER | SPI_H_TO_L|spi_clk_div_4);
  36.  
  37.    rx_id=0x01;
  38.  
  39.   buffer[0]=0x08;
  40.  
  41.    setup_timer_2(T2_DIV_BY_4,79,16);   //setup up timer2 to interrupt every 1ms if using 20Mhz clock
  42.    can_init();
  43.    enable_interrupts(INT_TIMER2);
  44.    enable_interrupts(GLOBAL);
  45.   // can_putd(0x01,dato,8,3,TRUE,TRUE);
  46.    while(TRUE){
  47.      //spi_write(0x25);  //sin habilitar nada de can, esta instruccion se lee correcta en osciloscopio por flanco ascendente de clk
  48.  
  49.       if ( can_tbe()){
  50.        output_high(pin_d1);// para ver si entra dentro del if, enciendo led
  51.        can_putd(0x01,&buffer[0],8,3,TRUE,TRUE);
  52.        }
  53.    }
  54. }
  55.  

la libreria que modifico para usar por spi por harware ( para el mcp2510) es esta :

Código: C
  1. /////////////////////////////////////////////////////////////////////////
  2. ////                        spi-can-mcp2510.c                            ////
  3. //// CAN Library routines for Microchip's MCP2510 (and compatable)   ////
  4. //// CAN IO expanders.                                               ////
  5. ////                                                                 ////
  6. //// This library provides the following functions:                  ////
  7. ////  (for more information on these functions see the comment       ////
  8. ////   header above each function)                                   ////
  9. ////                                                                 ////
  10. ////    can_init - Configures the MCP2510 CAN peripheral             ////
  11. ////                                                                 ////
  12. ////    can_set_baud - Sets the baud rate control registers          ////
  13. ////                                                                 ////
  14. ////    can_set_mode - Sets the CAN module into a specific mode      ////
  15. ////                                                                 ////
  16. ////    can_set_id - Sets the standard and extended ID               ////
  17. ////                                                                 ////
  18. ////    can_get_id - Gets the standard and extended ID               ////
  19. ////                                                                 ////
  20. ////    can_putd - Sends a message/request with specified ID         ////
  21. ////                                                                 ////
  22. ////    can_getd - Returns specifid message/request and ID           ////
  23. ////                                                                 ////
  24. ////    can_kbhit - Returns true if there is data in one of the      ////
  25. ////                receive buffers                                  ////
  26. ////                                                                 ////
  27. ////    can_tbe - Returns true if the transmit buffer is ready to    ////
  28. ////              send more data                                     ////
  29. ////                                                                 ////
  30. ////    can_abort - Aborts all pending transmissions                 ////
  31. ////                                                                 ////
  32. //// You will need a CAN transeiver to connect CANRX and CANTX       ////
  33. //// pins to CANH and CANL bus lines.                                ////
  34. ////                                                                 ////
  35. //// CCS provides an example, ex_can_ccs_b.c, which shows how to use ////
  36. //// this library with CCS's CAN Prototype board.                    ////
  37. ////                                                                 ////
  38. /////////////////////////////////////////////////////////////////////////
  39. ////                                                                 ////
  40. //// Version History                                                 ////
  41. ////                                                                 ////
  42. ////  Jul 27 04 - can_init() uses CAN_USE_EXTENDED_ID instead of     ////
  43. ////              setting all RX filters to extended.                ////
  44. ////                                                                 ////
  45. ////  Apr 20 04 - Fixed a compling problem.                          ////
  46. ////                                                                 ////
  47. ////  Feb 24 04 - can_get_id() fixed for EID<18:20>.                 ////
  48. ////                                                                 ////
  49. /////////////////////////////////////////////////////////////////////////
  50. ////        (C) Copyright 1996,2003 Custom Computer Services         ////
  51. //// This source code may only be used by licensed users of the CCS  ////
  52. //// C compiler.  This source code may only be distributed to other  ////
  53. //// licensed users of the CCS C compiler.  No other use,            ////
  54. //// reproduction or distribution is permitted without written       ////
  55. //// permission.  Derivative programs created using this software    ////
  56. //// in object code form are not restricted in any way.              ////
  57. /////////////////////////////////////////////////////////////////////////
  58.  
  59. #include <can-mcp2510.h>
  60.  
  61.  
  62.  
  63. //IO pins connected to MCP2510
  64. #ifndef EXT_CAN_CS
  65.    //#define EXT_CAN_CS   PIN_B1 //por defecto estos
  66.    //#define EXT_CAN_SI   PIN_C1
  67.    //#define EXT_CAN_SO   PIN_C0
  68.    //#define EXT_CAN_SCK  PIN_C3
  69.    // cambio para usar en PIC18F4550 modo HW
  70.    #define EXT_CAN_CS   PIN_A5
  71.    #define EXT_CAN_SI   PIN_B0
  72.    #define EXT_CAN_SO   PIN_C7
  73.    #define EXT_CAN_SCK  PIN_B1
  74. //   #define EXT_CAN_RESET   PIN_B5 //CCS library does not use this pin by default
  75. //   #define EXT_CAN_TX0RTS  PIN_C4 //CCS library does not use this pin by default
  76. //   #define EXT_CAN_TX1RTS  PIN_B4 //CCS library does not use this pin by default
  77. //   #define EXT_CAN_TX2RTS  PIN_C2 //CCS library does not use this pin by default
  78. #endif
  79.  
  80. #if CAN_DO_DEBUG
  81.  #define can_debug printf
  82. #else
  83.  #define can_debug
  84. #endif
  85.  
  86.  
  87.  
  88.  
  89. int  prescaler;
  90. int1 clkenable;
  91.  
  92.  
  93. ////////////////////////////////////////////////////////////////////////
  94. //
  95. // can_init()
  96. //
  97. // Initializes MCP2510 CAN peripheral.  Sets the RX filter and masks so the
  98. // CAN peripheral will receive all incoming IDs.  Configures both RX buffers
  99. // to only accept valid valid messages (as opposed to all messages, or all
  100. // extended message, or all standard messages).
  101. //
  102. // The constants (CAN_USE_RX_DOUBLE_BUFFER, CAN_ENABLE_DRIVE_HIGH,
  103. // CAN_ENABLE_CAN_CAPTURE, etc) are given a default define in the can-mcp2510.h file.
  104. // These default values can be overwritten in the main code, but most
  105. // applications will be fine with these defaults.
  106. //
  107. //////////////////////////////////////////////////////////////////////////////
  108. void can_init(void) {
  109.    struct struct_RXB0CTRL b_rxb0ctrl;
  110.  
  111.    mcp2510_init();
  112.  
  113.    can_set_mode(CAN_OP_CONFIG);   //must be in config mode before params can be set
  114.    can_set_baud();
  115.  
  116.    b_rxb0ctrl=0;
  117.    b_rxb0ctrl.rxm=CAN_RX_VALID;
  118.    b_rxb0ctrl.bukt=CAN_USE_RX_DOUBLE_BUFFER;
  119.    mcp2510_write(RXB0CTRL, (int)b_rxb0ctrl);
  120.    mcp2510_write(RXB1CTRL, (int)b_rxb0ctrl);
  121.  
  122.    //if you want to configure the TXnRTS pins, do it here.  default is off
  123.  
  124.    can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 0 (RX BUFFER 0)
  125.    can_set_id(RX0FILTER0, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 0 (RX BUFFER 0)
  126.    can_set_id(RX0FILTER1, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 0 (RX BUFFER 0)
  127.  
  128.    can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 1 (RX BUFFER 1)
  129.    can_set_id(RX1FILTER2, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 1 (RX BUFFER 1)
  130.    can_set_id(RX1FILTER3, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 1 (RX BUFFER 1)
  131.    can_set_id(RX1FILTER4, 0, CAN_USE_EXTENDED_ID);  //set filter 2 of mask 1 (RX BUFFER 1)
  132.    can_set_id(RX1FILTER5, 0, CAN_USE_EXTENDED_ID);  //set filter 3 of mask 1 (RX BUFFER 1)
  133.  
  134.    can_set_mode(CAN_OP_NORMAL);
  135. }
  136.  
  137. ////////////////////////////////////////////////////////////////////////
  138. //
  139. // can_set_baud()
  140. //
  141. // Configures the baud rate control registers.  All the defines here
  142. // are defaulted in the can-mcp2510.h file.  These defaults can, and
  143. // probably should, be overwritten in the main code.
  144. //
  145. // Current defaults are set to work with CCS's CAN Prototype board and
  146. // Microchip's MCP250xxx CAN Developers Kit if this PIC is running at 20Mhz.
  147. //
  148. ////////////////////////////////////////////////////////////////////////
  149.  
  150. /* void can_set_baud(void) {   // modificada abajo
  151.    struct struct_CNF1 new_CNF1;
  152.    struct struct_CNF2 new_CNF2;
  153.    struct struct_CNF3 new_CNF3;
  154.  
  155.  
  156.    new_CNF1.brp=CAN_BRG_PRESCALAR;
  157.    new_CNF1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;
  158.  
  159.    new_CNF2.prseg=CAN_BRG_PROPAGATION_TIME;
  160.    new_CNF2.phseg1=CAN_BRG_PHASE_SEGMENT_1;
  161.    new_CNF2.sam=CAN_BRG_SAM;
  162.    new_CNF2.btlmode=CAN_BRG_SEG_2_PHASE_TS;
  163.  
  164.    new_CNF3.phseg2=CAN_BRG_PHASE_SEGMENT_2;
  165.    new_CNF3.wakfil=CAN_BRG_WAKE_FILTER;
  166.  
  167.    mcp2510_write(CNF1, (int)new_CNF1);
  168.    mcp2510_write(CNF2, (int)new_CNF2);
  169.    mcp2510_write(CNF3, (int)new_CNF3);
  170. }*/
  171.                
  172. void can_set_baud(void) {      
  173.  /* # ifdef Set_125K_Baud {
  174.      BRGCON1 = 0x01;
  175.      BRGCON2 = 0xBA;      //modificado 5/11/07 para usar CAN a 125 KBps
  176.      BRGCON3 = 0x07;      //con reloj a 10 MHz
  177.   }
  178.   #endif */
  179.  
  180.   #ifdef Set_250K_Baud {
  181.      BRGCON1 = 0x00;
  182.      BRGCON2 = 0xBA;      //modificado 5/11/07 para usar CAN a 250 KBps
  183.      BRGCON3 = 0x07;      //con reloj a 10 MHz
  184.   }
  185.   #endif
  186.   #ifdef Set_500K_Baud {
  187.      BRGCON1 = 0x00;
  188.      BRGCON2 = 0x92;      //modificado 5/11/07 para usar CAN a 500 KBps
  189.      BRGCON3 = 0x02;      //con reloj a 10 MHz
  190.   }
  191.   #endif
  192. #ifdef Set_125_Baud {
  193.      BRGCON1 = 0x07;
  194.      BRGCON2 = 0xBE;      //modificado 7/12/09 para usar CAN a 250 KBps
  195.      BRGCON3 = 0x07;      //con reloj a 48 MHz
  196.    }
  197.   #endif
  198. /*
  199. #ifdef Set_125_Baud {
  200.      BRGCON1 = 0x03;
  201.      BRGCON2 = 0xBA;      //modificado 7/12/09 para usar CAN a 125 KBps
  202.      BRGCON3 = 0x07;      //con cristal a 20 MHz
  203.    }
  204.  #endif
  205. */
  206.  
  207. }
  208.  
  209. void can_set_mode(CAN_OP_MODE mode) {
  210.    struct struct_CANCTRL old_CANCTRL;
  211.  
  212.    old_CANCTRL=mcp2510_read(CANCTRL);
  213.  
  214.    old_CANCTRL.reqop=mode;
  215.  
  216.    mcp2510_write(CANCTRL, (int)old_CANCTRL);
  217.  
  218.    do {
  219.       old_CANCTRL=mcp2510_read(CANCTRL);
  220.    } while (old_CANCTRL.reqop != mode);
  221.  
  222.  }
  223.  
  224.  
  225. ///// void can_set_clk(CAN_OP_MODE prescaler)//////////////////////////////////
  226. ////////////////////////////////////////////////////////////////////////////////
  227. //void can_set_clk(CAN_OP_MODE prescaler) {   // funcio pel presclaer del clock del MCP
  228. void can_set_clk(){     //cambio capçalera perque no vull que retorni res. Crida funcio i executa.
  229.   struct struct_CANCTRL old_CANCTRL;
  230.  
  231.    old_CANCTRL=mcp2510_read(CANCTRL);
  232.   // old_CANCTRL.clkpre=0; // modifica els 2 bits del registre CANCTRL per posar a 1 el escaler
  233.  
  234.   prescaler=0; // 0  es el valor que vull de presclaer (0b00)
  235.  
  236.    old_CANCTRL.clkpre=prescaler;     //********** falta activació del pin!!!!!!!!!!!!!!!!!!!!!!!!!!
  237.  
  238.    mcp2510_write(CANCTRL, (int)old_CANCTRL);
  239.  
  240.    do {
  241.       old_CANCTRL=mcp2510_read(CANCTRL);
  242.    } while (old_CANCTRL.clkpre != prescaler);
  243. }
  244.  
  245. ////////////////////////////////////////////////////////////////////////////////
  246. //void can_set_clken() {   // activar pin clckout del mcp2510 , pero al final no uso esta funcion. de todos modos ahi esta hecha
  247. void can_set_clken(int1 cambiaa){     //cambio capçalera perque no vull que retorni res. Crida funcio i executa.
  248.   struct struct_CANCTRL old_CANCTRL;
  249.  
  250.    old_CANCTRL=mcp2510_read(CANCTRL);
  251.  
  252.   //clkenable=0; // 0  es el valor que vull de presclaer (0b00)
  253.  
  254.    //old_CANCTRL.clken=clkenable;     //********** falta activación del pin!!!!!!!!!!!!!!!!!!!!!!!!!!
  255.      old_CANCTRL.clken=cambiaa;
  256.  
  257.    mcp2510_write(CANCTRL, (int)old_CANCTRL);
  258.  
  259.    do {
  260.       old_CANCTRL=mcp2510_read(CANCTRL);
  261.    } while (old_CANCTRL.clkpre != prescaler);
  262. }
  263.  
  264. ////////////////////////////////////////////////////////////////////////
  265. //
  266. // can_set_id()
  267. //
  268. // Configures the xxxxEIDL, xxxxEIDH, xxxxSIDL and xxxxSIDH registers to
  269. // configure the defined buffer to use the specified ID
  270. //
  271. //   Paramaters:
  272. //     addr - pointer to first byte of ID register, starting with xxxxEIDL.
  273. //            For example, a pointer to RXM1EIDL
  274. //     id - ID to set buffer to
  275. //     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
  276. //
  277. ////////////////////////////////////////////////////////////////////////
  278. void can_set_id(int addr, int32 id, int1 ext) {
  279.    int converted_id[4];
  280.    int *ptr;
  281.  
  282.    ptr=&converted_id[3];   //3=eidl, 2=eidh, 1=sidl, 0=sidh
  283.  
  284.    if (ext) {  //extended
  285.       //eidl
  286.       *ptr=make8(id,0); //0:7
  287.  
  288.       //eidh
  289.       ptr--;
  290.       *ptr=make8(id,1); //8:15
  291.  
  292.       //sidl
  293.       ptr--;
  294.       *ptr=make8(id,2) & 0x03;   //16:17
  295.       *ptr|=(make8(id,2) << 3) & 0xE0; //18:20
  296.       *ptr|=0x08;
  297.  
  298.  
  299.       //sidh
  300.       ptr--;
  301.       *ptr=((make8(id,2) >> 5) & 0x07 ); //21:23
  302.       *ptr|=((make8(id,3) << 3) & 0xF8);//24:28
  303.    }
  304.    else {   //standard
  305.       //eidl
  306.       *ptr=0;
  307.  
  308.       //eidh
  309.       ptr--;
  310.       *ptr=0;
  311.  
  312.       //sidl
  313.       ptr--;
  314.       *ptr=(make8(id,0) << 5) & 0xE0;
  315.  
  316.       //sidh
  317.       ptr--;
  318.       *ptr=(make8(id,0) >> 3) & 0x1F;
  319.       *ptr|=(make8(id,1) << 5) & 0xE0;
  320.    }
  321.  
  322.    //0=eidl, 1=eidh, 2=sidl, 3=sidh
  323.    mcp2510_write(addr--, converted_id[3]);
  324.    mcp2510_write(addr--, converted_id[2]);
  325.    mcp2510_write(addr--, converted_id[1]);
  326.    mcp2510_write(addr, converted_id[0]);
  327. }
  328.  
  329. ////////////////////////////////////////////////////////////////////////
  330. //
  331. // can_get_id()
  332. //
  333. // Returns the ID of the specified buffer.  (The opposite of can_set_id())
  334. // This is used after receiving a message, to see which ID sent the message.
  335. //
  336. //   Paramaters:
  337. //     addr - pointer to first byte of ID register, starting with xxxxEIDL.
  338. //            For example, a pointer to RXM1EIDL
  339. //     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
  340. //
  341. //   Returns:
  342. //     The ID of the buffer
  343. //
  344. ////////////////////////////////////////////////////////////////////////
  345. int32 can_get_id(int addr, int1 ext) {
  346.    int32 ret;
  347.    int * ptr;
  348.    int converted_id[4];
  349.  
  350.    ptr=&converted_id[3];   //3=eidl, 2=eidh, 1=sidl, 0=sidh
  351.  
  352.    converted_id[3]=mcp2510_read(addr--);
  353.    converted_id[2]=mcp2510_read(addr--);
  354.    converted_id[1]=mcp2510_read(addr--);
  355.    converted_id[0]=mcp2510_read(addr);
  356.  
  357.    ret=0;
  358.  
  359.  
  360.    if (ext) {
  361.       ret=*ptr;  //eidl
  362.  
  363.       ptr--;     //eidh
  364.       ret|=((int32)*ptr << 8);
  365.  
  366.       ptr--;     //sidl
  367.       ret|=((int32)*ptr & 0x03) << 16;
  368.       ret|=((int32)*ptr & 0xE0) << 13;
  369.  
  370.       ptr--;     //sidh
  371.       ret|=((int32)*ptr << 21);
  372.    }
  373.    else {
  374.       ptr-=2;    //sidl
  375.       ret=((int32)*ptr & 0xE0) >> 5;
  376.  
  377.       ptr--;     //sidh
  378.       ret|=((int32)*ptr << 3);
  379.    }
  380.  
  381.    return(ret);
  382. }
  383.  
  384. ////////////////////////////////////////////////////////////////////////
  385. //
  386. // can_putd()
  387. //
  388. // Puts data on a transmit buffer, at which time the CAN peripheral will
  389. // send when the CAN bus becomes available.
  390. //
  391. //    Paramaters:
  392. //       id - ID to transmit data as
  393. //       data - pointer to data to send
  394. //       len - length of data to send
  395. //       priority - priority of message.  The higher the number, the
  396. //                  sooner the CAN peripheral will send the message.
  397. //                  Numbers 0 through 3 are valid.
  398. //       ext - TRUE to use an extended ID, FALSE if not
  399. //       rtr - TRUE to set the RTR (request) bit in the ID, false if NOT
  400. //
  401. //    Returns:
  402. //       If successful, it will return TRUE
  403. //       If un-successful, will return FALSE
  404. //
  405. ////////////////////////////////////////////////////////////////////////
  406. int1 can_putd(int32 id, int * data, int len, int priority, int1 ext, int1 rtr) {
  407.    int i;
  408.    int port;
  409.  
  410.    int TXRXBaD0;
  411.    int TXBaCTRL;
  412.    int TXRXBaEIDL;
  413.    int TXBaDLC;
  414.  
  415.    struct txbNctrl_struct b_TXBaCTRL;
  416.    struct rxbNdlc_struct b_TXBaDLC;
  417.    struct txbNctrl_struct b_TXB0CTRL, b_TXB1CTRL, b_TXB2CTRL;
  418.  
  419.    b_TXB0CTRL=mcp2510_read(TXB0CTRL);
  420.    b_TXB1CTRL=mcp2510_read(TXB1CTRL);
  421.    b_TXB2CTRL=mcp2510_read(TXB2CTRL);
  422.  
  423.     // find emtpy transmitter
  424.     //map access bank addresses to empty transmitter
  425.    if (!b_TXB0CTRL.txreq) {
  426.       TXRXBaD0=TXB0D0;
  427.       TXBaCTRL=TXB0CTRL;
  428.       TXRXBaEIDL=TXB0EIDL;
  429.       TXBaDLC=TXB0DLC;
  430.       port=0;
  431.    }
  432.    else if (!b_TXB1CTRL.txreq) {
  433.       TXRXBaD0=TXB1D0;
  434.       TXBaCTRL=TXB1CTRL;
  435.       TXRXBaEIDL=TXB1EIDL;
  436.       TXBaDLC=TXB1DLC;
  437.       port=1;
  438.    }
  439.    else if (!b_TXB2CTRL.txreq) {
  440.       TXRXBaD0=TXB2D0;
  441.       TXBaCTRL=TXB2CTRL;
  442.       TXRXBaEIDL=TXB2EIDL;
  443.       TXBaDLC=TXB2DLC;
  444.       port=2;
  445.    }
  446.    else {
  447.       #if CAN_DO_DEBUG
  448.          can_debug("\r\nCAN_PUTD() FAIL: NO OPEN TX BUFFERS\r\n");
  449.       #endif
  450.       return(0);
  451.    }
  452.  
  453.    //set priority.
  454.    b_TXBaCTRL=mcp2510_read(TXBaCTRL);
  455.    b_TXBaCTRL.txpri=priority;
  456.    mcp2510_write(TXBaCTRL, (int)b_TXBaCTRL);
  457.  
  458.    //set tx mask
  459.    can_set_id(TXRXBaEIDL, id, ext);
  460.  
  461.    //set tx data count
  462.    b_TXBaDLC=len;
  463.    b_TXBaDLC.rtr=rtr;
  464.    mcp2510_write(TXBaDLC, (int)b_TXBaDLC);
  465.  
  466.    //write to buffer
  467.     for (i=TXRXBaD0; i<(TXRXBaD0 + len); i++) {
  468.       mcp2510_write(i,*data);
  469.       data++;
  470.     }
  471.  
  472.    //enable transmission
  473.    b_TXBaCTRL=mcp2510_read(TXBaCTRL);
  474.    b_TXBaCTRL.txreq=1;
  475.    mcp2510_write(TXBaCTRL, (int)b_TXBaCTRL);
  476.  
  477.    #if CAN_DO_DEBUG
  478.             can_debug("\r\nCAN_PUTD(): BUFF=%U ID=%LX LEN=%U PRI=%U EXT=%U RTR=%U\r\n", port, id, len, priority, ext, rtr);
  479.             if ((len)&&(!rtr)) {
  480.                data-=len;
  481.                can_debug("  DATA = ");
  482.                for (i=0;i<len;i++) {
  483.                   can_debug("%X ",*data);
  484.                   data++;
  485.                }
  486.                can_debug("\r\n");
  487.             }
  488.    #endif
  489.  
  490.    return(1);
  491. }
  492.  
  493. ////////////////////////////////////////////////////////////////////////
  494. //
  495. // can_getd()
  496. //
  497. // Gets data from a receive buffer, if the data exists
  498. //
  499. //    Returns:
  500. //      id - ID who sent message
  501. //      data - pointer to array of data
  502. //      len - length of received data
  503. //      stat - structure holding some information (such as which buffer
  504. //             recieved it, ext or standard, etc)
  505. //
  506. //    Returns:
  507. //      Function call returns a TRUE if there was data in a RX buffer, FALSE
  508. //      if there was none.
  509. //
  510. ////////////////////////////////////////////////////////////////////////
  511. int1 can_getd(int32 & id, int * data, int & len, struct rx_stat & stat)
  512. {
  513.     int i;
  514.  
  515.    struct struct_RXB0CTRL b_RXB0CTRL;
  516.    struct struct_RXB1CTRL b_RXB1CTRL;
  517.    struct struct_EFLG b_EFLG;
  518.  
  519.    int RXBaDLC;
  520.    struct rxbNdlc_struct b_RXBaDLC;
  521.  
  522.    int TXRXBaSIDL;
  523.    struct struct_TXRXBaSIDL b_TXRXBaSIDL;
  524.  
  525.  
  526.    int RXBaD0;
  527.    struct struct_CANINTF b_CANINTF;
  528.  
  529.    b_CANINTF=mcp2510_read(CANINTF);
  530.  
  531.    b_RXB0CTRL=mcp2510_read(RXB0CTRL);
  532.    b_RXB1CTRL=mcp2510_read(RXB1CTRL);
  533.    b_EFLG=mcp2510_read(EFLG);
  534.  
  535.     if (b_CANINTF.rx0if) {
  536.         stat.buffer=0;
  537.  
  538.         stat.err_ovfl=b_EFLG.rx0ovr;
  539.         b_EFLG.rx0ovr=0;
  540.         mcp2510_write(EFLG, (int)b_EFLG);
  541.  
  542.         if (b_RXB0CTRL.bukt) {
  543.          stat.filthit=b_RXB0CTRL.filhit0;
  544.         }
  545.  
  546.         RXBaDLC=RXB0DLC;
  547.         TXRXBaSIDL=RXB0SIDL;
  548.         RXBaD0=RXB0D0;
  549.     }
  550.     else if (b_CANINTF.rx1if)
  551.     {
  552.         stat.buffer=1;
  553.  
  554.         stat.err_ovfl=b_EFLG.rx1ovr;
  555.         b_EFLG.rx1ovr=0;
  556.         mcp2510_write(EFLG, (int)b_EFLG);
  557.  
  558.  
  559.         stat.filthit=b_RXB1CTRL.filhit0;
  560.         RXBaDLC=RXB1DLC;
  561.         TXRXBaSIDL=RXB1SIDL;
  562.         RXBaD0=RXB1D0;
  563.     }
  564.     else {
  565.       #if CAN_DO_DEBUG
  566.          can_debug("\r\nFAIL ON CAN_GETD(): NO MESSAGE IN BUFFER\r\n");
  567.       #endif
  568.       return (0);
  569.     }
  570.  
  571.    //get count
  572.     b_RXBaDLC=mcp2510_read(RXBaDLC);
  573.     len = b_RXBaDLC.dlc;
  574.     stat.rtr=b_RXBaDLC.rtr;
  575.  
  576.    //was it extended or standard?
  577.     b_TXRXBaSIDL=mcp2510_read(TXRXBaSIDL);
  578.     stat.ext=b_TXRXBaSIDL.ext;
  579.     id=can_get_id(TXRXBaSIDL + 2,stat.ext);
  580.  
  581.    //get data
  582.     for ( i = RXBaD0; i < (RXBaD0 + len); i++ ) {
  583.          *data=mcp2510_read(i);
  584.         data++;
  585.     }
  586.  
  587.     stat.inv=b_CANINTF.merrf;
  588.     if (b_CANINTF.merrf) {
  589.       b_CANINTF.merrf=0;
  590.     }
  591.  
  592.     if (stat.buffer) {
  593.       b_CANINTF.rx1if=0;
  594.     }
  595.     else {
  596.       b_CANINTF.rx0if=0;
  597.     }
  598.     mcp2510_write(CANINTF, (int)b_CANINTF);
  599.  
  600.     #if CAN_DO_DEBUG
  601.        can_debug("\r\nCAN_GETD(): BUFF=%U ID=%LX LEN=%U OVF=%U ", stat.buffer, id, len, stat.err_ovfl);
  602.        can_debug("FILT=%U RTR=%U EXT=%U INV=%U", stat.filthit, stat.rtr, stat.ext, stat.inv);
  603.        if ((len)&&(!stat.rtr)) {
  604.           data-=len;
  605.           can_debug("\r\n    DATA = ");
  606.           for (i=0;i<len;i++) {
  607.             can_debug("%X ",*data);
  608.             data++;
  609.           }
  610.        }
  611.        can_debug("\r\n");
  612.     #endif
  613.  
  614.     return(1);
  615. }
  616.  
  617. ////////////////////////////////////////////////////////////////////////
  618. //
  619. // can_kbhit()
  620. //
  621. // Returns TRUE if there is data in the receive buffers
  622. //
  623. //////////////////////////////////////////////////////////////////////////////
  624. int1 can_kbhit(void) {
  625.    struct struct_CANINTF b_CANINTF;
  626.  
  627.    b_CANINTF=mcp2510_read(CANINTF);
  628.    if (b_CANINTF.rx0if || b_CANINTF.rx1if)
  629.       {return(1);}
  630.  
  631.    return(0);
  632. }
  633.  
  634. ////////////////////////////////////////////////////////////////////////
  635. //
  636. // can_tbe()
  637. //
  638. // Returns TRUE if the transmit buffers are empty and ready to transmit data
  639. //
  640. //////////////////////////////////////////////////////////////////////////////
  641. int1 can_tbe(void) {
  642.    struct txbNctrl_struct b_TXB0CTRL, b_TXB1CTRL, b_TXB2CTRL;
  643.  
  644.    b_TXB0CTRL=mcp2510_read(TXB0CTRL);
  645.    b_TXB1CTRL=mcp2510_read(TXB1CTRL);
  646.    b_TXB2CTRL=mcp2510_read(TXB2CTRL);
  647.  
  648.    if (!b_TXB0CTRL.txreq || !b_TXB1CTRL.txreq || !b_TXB2CTRL.txreq)
  649.       {return(1);}
  650.  
  651.    return(0);
  652. }
  653.  
  654. ////////////////////////////////////////////////////////////////////////
  655. //
  656. // can_abort()
  657. //
  658. // Aborts all pending tranmissions.
  659. //
  660. //////////////////////////////////////////////////////////////////////////////
  661. void can_abort(void) {
  662.    struct struct_CANCTRL b_CANCTRL;
  663.  
  664.    b_CANCTRL=mcp2510_read(CANCTRL);
  665.    b_CANCTRL.abat=1;
  666.    mcp2510_write(CANCTRL, (int)b_CANCTRL);
  667.  
  668.    delay_ms(5);
  669.    b_CANCTRL.abat=0;
  670.    mcp2510_write(CANCTRL, (int)b_CANCTRL);
  671. }
  672.  
  673.  
  674.  
  675.  
  676. ///////////////////
  677. ///
  678. //
  679. // SPI CODE. Antes por sofware, cambiando funciones para usar SPI por HW.
  680. //
  681. ///
  682. //////////////////
  683.  
  684. //data clocked in on rising edge
  685. //data driven out on falling edge
  686.  
  687. /*int mcp2510_read(int address) /////////  Esta es por software ////////
  688.   {
  689.    int command[2];
  690.    int i;
  691.    int data;
  692.  
  693.    command[1]=0x03;
  694.    command[0]=address;
  695.  
  696.  
  697.    output_low(EXT_CAN_CS);
  698.  
  699.    for (i=0;i<16;i++) {
  700.  
  701.     output_bit(EXT_CAN_SI, shift_left(&command[0],2,0));
  702.         output_high(EXT_CAN_SCK);
  703.         output_low(EXT_CAN_SCK);
  704.         }
  705.  
  706.        for (i=0;i<8;i++) {
  707.        shift_left(&data,1,input(EXT_CAN_SO));
  708.        output_high(EXT_CAN_SCK);
  709.        output_low(EXT_CAN_SCK);
  710.        }
  711.  
  712.  
  713.    output_high(EXT_CAN_CS);
  714.  
  715.    return(data);
  716. }*/
  717.  
  718.    /////////////////////////////////////////////////
  719.  
  720. ////////////////////////////////////  Esta es por hardware //////////////////////////////////
  721. int mcp2510_read(int address)
  722. {
  723. //enviar ( o sea escribir) al MCP desde el PIC que se quiere hacer.PIC contesta a la peticion de
  724. //lectura ( y el que hemos dicho) sobre data. Devuelve data
  725.  
  726.  int data;
  727.  
  728.       output_low(EXT_CAN_CS); // pic espera intsrucción. Primero mira cual es:
  729.       spi_write(0x03);    // escribir instrucción 0x03 es instruccion leer.Va a instruccion leer->
  730.       spi_write(address); //escribir dirección de donde se quiere leer
  731.       spi_read(data);     // escribir dato enviado por el pic
  732.       output_high(EXT_CAN_CS);
  733.       return(data);       //devuelbe lo que queremos leer
  734. }
  735.  
  736.    ////////////////////////////////////////////////
  737.  
  738.  
  739.  
  740.  
  741. /*
  742. int mcp2510_status(void) { //////////////////// por software////////////////////////////
  743.    int command;
  744.    int data;
  745.    int i;
  746.  
  747.    command=0xA0;
  748.  
  749.    output_low(EXT_CAN_CS);
  750.  
  751.    for (i=0;i<8;i++) {
  752.       output_bit(EXT_CAN_SI, shift_left(&command,1,0));
  753.       output_high(EXT_CAN_SCK);
  754.       output_low(EXT_CAN_SCK);
  755.    }
  756.    for (i=0;i<8;i++) {
  757.       shift_left(&data,1,input(EXT_CAN_SO));
  758.       output_high(EXT_CAN_SCK);
  759.       output_low(EXT_CAN_SCK);
  760.    }
  761.    for (i=0;i<8;i++) {
  762.       output_high(EXT_CAN_SCK);
  763.       output_low(EXT_CAN_SCK);
  764.    }
  765.  
  766.    output_high(EXT_CAN_CS);
  767.  
  768.    return(data);
  769. }*/
  770.  
  771. /////////////////////////////////////////////////////
  772. ////////////////////////////////////  Esta es por hardware //////////////////////////////////
  773. int mcp2510_status(void) {
  774.    int data;
  775.  
  776.    
  777.    output_low(EXT_CAN_CS);   //podriamos hacer algo par comrpbar error, si la 2a lectura!=1a lectura
  778.    spi_write(0xA0);
  779.    spi_read(data);
  780.    spi_read();
  781.    output_high(EXT_CAN_CS);
  782.  
  783. }
  784.  
  785.  
  786. ////////////////////////////////////////////////////
  787.  
  788. /*
  789. void mcp2510_write(int address, int data) { //////////////////// por software////////////////////////////
  790.    int command[3];
  791.    int i;
  792.  
  793.    command[2]=0x02;
  794.    command[1]=address;
  795.    command[0]=data;
  796.  
  797.    output_low(EXT_CAN_CS);
  798.  
  799.    for (i=0;i<24;i++) {
  800.       output_bit(EXT_CAN_SI, shift_left(&command[0],3,0));
  801.       output_high(EXT_CAN_SCK);
  802.       output_low(EXT_CAN_SCK);
  803.    }
  804.  
  805.    output_high(EXT_CAN_CS);
  806. } */
  807.  
  808. ///////////////////////////////////////////////////////////////////////
  809.  
  810. ////////////////////////////////////  Esta es por hardware //////////////////////////////////
  811. void mcp2510_write(int address, int data) {
  812.  
  813.  
  814.  
  815.    output_low(EXT_CAN_CS);
  816.    spi_write(0x02);           //
  817.    spi_write(address);        //estas 2 siempre es spi_write ya que se ha de decir desde el pic la fun.
  818.    spi_write(data);
  819.    output_high(EXT_CAN_CS);
  820.  
  821. }
  822.    
  823.  
  824.  
  825.  
  826. ////////////////////////////////////////////////////////////////////////
  827.  /*
  828.  
  829. void mcp2510_command(int command) {    /////////// por software  //////////////////////////
  830.    int i;
  831.  
  832.    output_low(EXT_CAN_CS);
  833.  
  834.    for (i=0;i<8;i++) {
  835.       output_bit(EXT_CAN_SI, shift_left(&command,1,0));
  836.       output_high(EXT_CAN_SCK);
  837.       output_low(EXT_CAN_SCK);
  838.    }
  839.  
  840.    output_high(EXT_CAN_CS);
  841. }*/
  842.  
  843. ////////////////////////////////////////////// /por Hardware //////////////////////////////
  844. void mcp2510_command(int command){
  845.  
  846. output_low(EXT_CAN_CS);
  847. spi_write(command);
  848. output_high(EXT_CAN_CS);
  849. }
  850.  
  851.  
  852. ////////////////////////////////////////
  853.  
  854.  
  855.  
  856.  
  857. /*
  858. void mcp2510_init(void) {    /////////////   por software  //////////////////////////
  859.    output_high(EXT_CAN_CS);
  860.    output_low(EXT_CAN_SCK);
  861.  
  862.    #ifdef EXT_CAN_TX0RTS
  863.     output_high(EXT_CAN_TX0RTS);
  864.    #endif
  865.    #ifdef EXT_CAN_TX1RTS
  866.     output_high(EXT_CAN_TX1RTS);
  867.    #endif
  868.    #ifdef EXT_CAN_TX2RTS
  869.     output_high(EXT_CAN_TX2RTS);
  870.    #endif
  871.  
  872.   #ifdef EXT_CAN_TX0RTS
  873.    output_high(EXT_CAN_RESET);
  874.    output_low(EXT_CAN_RESET);
  875.    output_high(EXT_CAN_RESET);
  876.    delay_ms(5);
  877.   #endif
  878.  
  879.    mcp2510_command(0xC0);   //reset
  880.    delay_ms(5);
  881. }   */
  882.  
  883.  
  884. /////////////////////////////////////////////////////////////////
  885.  
  886. /////////////////////////////// por harware  ////////////////////////////////////
  887. void mcp2510_init(void) {
  888.    output_high(EXT_CAN_CS);
  889.  
  890.  
  891.    #ifdef EXT_CAN_TX0RTS
  892.    // output_high(EXT_CAN_TX0RTS);
  893.    spi_write(); orden de escribir
  894.    #endif
  895.    #ifdef EXT_CAN_TX1RTS
  896.     output_high(EXT_CAN_TX1RTS);
  897.    #endif
  898.    #ifdef EXT_CAN_TX2RTS
  899.     output_high(EXT_CAN_TX2RTS);
  900.    #endif
  901.  
  902.   #ifdef EXT_CAN_TX0RTS
  903.    output_high(EXT_CAN_RESET);
  904.    output_low(EXT_CAN_RESET);
  905.    output_high(EXT_CAN_RESET);
  906.    delay_ms(5);
  907.   #endif
  908.  
  909.    mcp2510_command(0xC0);   //reset
  910.    delay_ms(5);
  911. }
  912. /////////////////////////////////////////////////////////////////
  913.  
  914.  

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #658 en: 08 de Diciembre de 2009, 16:42:13 »
Me parece que tu proble surge de usar Use_Fast_IO ()

en lugar de Standard_IO ().

Sugiero que hagas ese cambio primero y es posible que no tengas problemas despues.

No encuentro donde configuras los puertos para usar Fast_IO, y esa puede ser la causa de tus problemas.

Standard_IO () configura en forma automatica los puertos, y eso te saca problemas...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7841
Re: Mis experiencias con el BUS CAN
« Respuesta #659 en: 08 de Diciembre de 2009, 16:58:55 »
Definitivamente ese es tu problema...
En esta linea:
Código: C
  1. #define CAN_DO_DEBUG TRUE
Estas declarando que utilizaras el port serie del micro para hacer debug del programa a traves del puerto serie.
Eso configura la velocidad y otros datos y entre ellos, usa el pin C7 como pin de recepcion RX del puerto serie, definido para la USART.

Ese pin a su vez es SDO del bus SPI.
Como la declaracion del puerto serie es posterior a la del bus SPI, prevalece esta ultima.

Eso te anula el SPI y no transmite un solo bit porque el pin es de entrada ahora!!!

Entre las opciones tienes:
  • Hacerle entender a tu profesor que todos estos problemas que tienes son por su capricho...
  • Hacer que la muerte del profesor parezca un accidente o suicidio (en cualquiera de los casos, no apuñalarlo por la espalda, porque no seria creible)
  • Comentar todas las instrucciones #define CAN_DO_DEBUG TRUE o eliminarlas y usar standard_IO()
  • Usar el SPI por software en caso de tener exito con el primer o segundo punto!!!
:mrgreen: :D
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.