Autor Tema: Dudas básicas con dsPIC33EP512MU810  (Leído 4077 veces)

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

Desconectado altofalantes

  • PIC10
  • *
  • Mensajes: 3
Dudas básicas con dsPIC33EP512MU810
« en: 13 de Mayo de 2016, 17:11:26 »
Primero decir que soy nuevo en este foro, y si lo que pido ya se ha respondido antes pido disculpas de antemano.
El caso es que estoy trabajando con SnadPIC (una board con un dsPIC33EP512MU810, de un fabricante independiente, bastante sencillita) y hasta ahora había trabajado con PIC18F45K20 en ensamblador y en C, empecé a hacer el proyecto fin de carrera hace una semanas y en lugar del F45K20 me dieron uno más potente y el caso es que todo es distinto, no hay ejemplos o los que hay (por ejemplo en la página de microchip) son tan complejos que se me escapan, no consigo que me sirvan de ayuda, así que cualquier ejemplo sencillo de programa que tengáis que pueda migrar (estoy trabajando con xc16 e ICD3), sobre todo para trabajar con los registros y SFR que son todos distintos y me vuelvo loco con el manual del PIC, para trabajar con interrupciones, que por cierto tiene 8 niveles de interrupción, como puedo saber a que lineas corresponden los saltos de cada nivel de interrupcion...etc cualquier cosa que tengáis con este PIC, cuanto más sencillas mejor, por favor enviarmelas, me sería de mucha ayuda

Desconectado altofalantes

  • PIC10
  • *
  • Mensajes: 3
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #1 en: 13 de Mayo de 2016, 20:25:07 »
Por si a alguno le interesa el proyecto consiste en:
Tomar medidas con un sensor laser rotandolo con un motor paso a paso
Como pensé hacerlo es, mover el paso a paso 45 o 90 grados hacia delante y hacia atrás y con un encóder de 100 pulsos por vuelta y unidad de captura para saber el tiempo que transcurre entre pulsos del encoder, haciendo media con los tres ultimos datos, y dividiendo el valor entre 100 por ejemplo, tomar 100 medidas por pulso con el laser.
Pasar esa información de polar a cartesiana, y programar el pic como un esclavo I2C. Por I2C recibe la orden de arrancar y parar, el rango que recorre el paso a paso (45, 90, 180 grados) y envía (permite leer) el array de valores obtenido del laser pasado a coordenadas cartesianas.
Para cronometrar el tiempo entre pulsos del encoder, unidad de captura, usando la interrupción de la captura hago la media con los tres valores anteriores, la divido entre 100 y programo un timer.
Con la interrupción de ese timer, ordeno tomar un valor del sensor. El sensor genera un valor analógico así que en el timer ordeno una conversión al CAD, y con la interrupción del CAD, opero con el valor y lo guardo en memoria para su posterior lectura a través de I2C.
El objetivo es diseñar un módulo, que convinado con otros y un máster conectado directamente a una pantalla, o al ordenador de abordo, sirvan como sensor de aparcamiento preciso para el coche, o también como módulo para un robot móvil, para autoguiado y esas cosas.
Por supuesto tengo que limarlo y lo iré descubriendo según trabaje en él pero el punto es que todo sería muy fácil si trabajara con F45K20 pero con el dsPIC33 me estoy volviendo loco para arrancar.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #2 en: 13 de Mayo de 2016, 23:31:15 »
Hola altofalantes, solo decirte que no conteste antes por que realmente pienso que necesitaria explicarte desde 0 dsPIC y eso implica que sean hojas y hojas sobre algo que podrias conocer leyendo de donde ya esta escrito.

Los dsPIC y PIC24 son realmente un MUNDO aparte, ni siquiera el ASM es parecido, ya que se parece mucho mas a lo que es GCC en ASM que lo que tenias en 8 bits con MPASM.
Por otra parte sus modulos dejan de ser "sencillos" con 2 registros como maximo, pasan a ser mucho mas complejos esto lleva a que cada modulo posea un PDF explicandolo en detalle, lo bueno es que es un PDF que vale para todos los PIC24/dsPIC.

Estos se encuentra abajo en donde dice Documentacion (Reference Manual):
http://www.microchip.com/wwwproducts/en/dsPIC33EP512MU810

Un lugar donde podes llegar a buscar codigos es tambien aca, vo ya suponer que es directo con XC16:
Sub-Foro dsPIC:
http://www.todopic.com.ar/foros/index.php?board=6.0

En si la estructura del programa es identica a como estabas acosutmbrado en XC8, por ejemplo este codigo sobre el Timer1:

Código: C
  1. #include "xc.h"
  2.  
  3.  
  4. int main(void) {
  5.    
  6.     TRISB = 0x0000;     // Bit B13 como salida.
  7.     T1CONbits.TON =0;
  8.     T1CONbits.TCS =0;
  9.     T1CONbits.TGATE =0;
  10.     T1CONbits.TCKPS =0b11;      // Pre escaler 1:256
  11.     TMR1=0x00;
  12.     PR1=781;                   // Valor en el registro ( Retardo 20ms)
  13.    
  14.     IPC0bits.T1IP =0x01;
  15.     IFS0bits.T1IF=0;            // Borra el Flag de Interrup Timer1
  16.     IEC0bits.T1IE =1;           // Habilita interrupcion Timer1  
  17.     T1CONbits.TON =1;           // Start Timer
  18.    
  19.     while(1);
  20.    
  21.     return 0;
  22. }
  23.  
  24.  
  25. void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void)
  26. {
  27.  
  28.     IFS0bits.T1IF = 0;
  29.     _LATB13 = ~_LATB13;
  30. }

Unas cuantas cosas a notar aca, observaras que use _LATB13 y no LATBbits.LATB13, esto es por que aveces el MPLAB X a pesar de estar definidos no te los toma y luego te tira error, necesitando agregar el .h del dsPIC, lo cual deberia agregarse por si solo con el xc.h como lo haces en XC8.

Otra es como se definen las interrupciones, algo mas parecido a lo que se hace con GCC es decir usando el __atribute__ , el nombre de la funcion (_T1Interrupt) no es al azar, sino como cada modulo posee un vector especifico el nombre debe cumplirse, no recuerdo si esto esta en la seccion de interrupciones o en el manual de usuario de XC16.

Tambien podes usar las plib ( libreria de perifericos )

Otro ejemplo, con cambio de reloj tambien
Código: C
  1. #include "xc.h"
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <uart.h>
  5.  
  6. #define FCY 16000000UL
  7.  
  8. void Configuracion_Oscilador(void);
  9. void Configuracion_Pines(void);
  10. void Configuracion_UARTs(void);
  11. char * utoa(char * buf, unsigned val, int base);
  12.  
  13. uint32_t contador1 = 0;
  14. uint32_t contador2 = 0;
  15. extern uint8_t algo;
  16. char resultado[10];
  17.  
  18. int main(void)
  19. {
  20.    
  21.     Configuracion_Pines();
  22.     Configuracion_Oscilador();
  23.     Configuracion_UARTs();
  24.    
  25.     // Deshabilito las interrupcion nesteadas
  26.    
  27.     _NSTDIS = 1;
  28.  
  29.     // 4 escrituras. Ya que la interrupcion se realiza cuando 3/4 lleno el buffer
  30.    
  31.     WriteUART1(++contador1);
  32.     WriteUART2(++contador2);
  33.     WriteUART1(++contador1);
  34.     WriteUART2(++contador2);
  35.     WriteUART1(++contador1);
  36.     WriteUART2(++contador2);
  37.     WriteUART1(++contador1);
  38.     WriteUART2(++contador2);    
  39.    
  40.     while(1)
  41.     {
  42.         _LATB0 = ~ _LATB0;
  43.         __delay32(8000000);
  44.         if(algo != 0)
  45.         {
  46.             if(contador1>contador2)
  47.             {
  48.                 utoa(resultado,(contador1-contador2),10);
  49.             }
  50.             else
  51.             {
  52.                 utoa(resultado,(contador2-contador1),10);
  53.             }
  54.             putsUART1((unsigned int *)"Diferencia contadores:");
  55.             putsUART1((unsigned int *)resultado);
  56.             putsUART1((unsigned int *)"\n\r");
  57.         }
  58.     }
  59.    
  60.     return 0;
  61. }
  62.  
  63. void Configuracion_Oscilador(void)
  64. {
  65.     /*
  66.      *  8Mhz cristal externo , entrada de frecuencia se cumple 0.8Mhz 8.0Mhz
  67.      *  Fin * M/N1 = Fvco = 128Mhz tambien se cumple , 120 a 340 Mhz
  68.      *  Fosc = Fvco / N2 = 32Mhz  cumple con lo establecido, 15 a 120Mhz
  69.      *  Fp = Fosc / 2 = 16Mhz
  70.      */
  71.    
  72.     PLLFBD = 30;    // M = 32
  73.     _PLLPOST = 0;   // N1 = 2 (default)
  74.     _PLLPRE = 1;    // N2 = 4 (default)
  75.    
  76.     __builtin_write_OSCCONH(0x03);              // Nuevo oscilador en Oscilador Principal con PLL
  77.     __builtin_write_OSCCONL(OSCCON | 0x01);     // Activo el bit para el cambio de oscilador
  78.    
  79.     // Esperamos el cambio de clock, es decir cuando el oscilador actual pase a ser PRIOSC + PLL
  80.     while (_COSC != 0b011);
  81.    
  82.     // Esperamos al PLL que se enganche
  83.     while (_LOCK != 1);
  84.    
  85.     // No se si es necesario para hacer que la CPU realmente funcione a 1:1 con Fp
  86.     _ROI = 1;
  87. }
  88.  
  89. void Configuracion_Pines(void)
  90. {
  91.     _TRISB0 = 0;
  92.     _LATB0 = 0;
  93. }
  94.  
  95. void Configuracion_UARTs(void)
  96. {
  97.    
  98.     uint16_t baudvalue;  
  99.     uint16_t UMODEvalue;
  100.     uint16_t USTAvalue;
  101.    
  102.     CloseUART1();       // Solo por si acaso fue un reset
  103.     CloseUART2();
  104.    
  105.     /*
  106.      * Configuracion de las interrupciones, habilitadas/deshabilitadas
  107.      * y prioridades de las mismas
  108.      */
  109.    
  110.     ConfigIntUART1(UART_RX_INT_EN & UART_RX_INT_PR6 &
  111.                    UART_TX_INT_DIS);
  112.     ConfigIntUART2(UART_RX_INT_EN & UART_RX_INT_PR6 &
  113.                    UART_TX_INT_DIS);
  114.    
  115.     /*
  116.      * Configuracion de la UART,
  117.      *
  118.      * UxMODE Register:
  119.      * UART_EN : UART habilitada
  120.      * UART_IDLE_CON : Modo de operacion continua en Idle
  121.      * UART_DIS_WAKE : Deshabilitado el Wake-Up por medio de la UART
  122.      * UART_EN_LOOPBACK: habilito el Loopback
  123.      * UART_DIS_ABAUD : Deshabilitado el Auto-Baud
  124.      * UART_NO_PAR_8bit : Sin paridad y 8 bits
  125.      * UART_1STOPBIT : 1 bit de stop
  126.      * UART_IrDA_DISABLE: Desativa la codificacion IrDA
  127.      * UART_UEN_00 : Pines RX y TX usados por el modulo, los demas ( CTS,RTS por el usuario )
  128.      * UART_BRGH_SIXTEEN : High Baud Rate Generator desactivado
  129.      * UART_MODE_SIMPLEX : Modo Simple sin control de Flujo
  130.      *
  131.      * UxSTA Register:
  132.      * UART_INT_TX_BUF_EMPTY : Interrupcion generado cuando se vacia el buffer
  133.      * UART_IrDA_POL_INV_ZERO : Idle state la salida esta en 0 (al no estar habilitado IrDA se refiere a UxTX )
  134.      * UART_TX_ENABLE : Activamos el Transmisor
  135.      * UART_INT_RX_3_4_FULL : Definimos que el flag se ponga a 1 a los 3/4 del buffer
  136.      * UART_ADR_DETECT_DIS: Deshabilitamos la deteccion de direccion ( aunque con 8 bits no funciona )
  137.      * UART_RX_OVERRUN_CLEAR : Limpiamos el bit de Overrun por si las dudas
  138.      */
  139.    
  140.     UMODEvalue =  UART_EN & UART_IDLE_CON &
  141.                   UART_DIS_WAKE & UART_EN_LOOPBACK  &
  142.                   UART_DIS_ABAUD & UART_NO_PAR_8BIT  &
  143.                   UART_1STOPBIT & UART_IrDA_DISABLE &
  144.                   UART_UEN_00 & UART_BRGH_SIXTEEN &
  145.                   UART_MODE_SIMPLEX;
  146.    
  147.     USTAvalue  =  UART_INT_TX_BUF_EMPTY  & UART_IrDA_POL_INV_ZERO &
  148.                   UART_TX_ENABLE & UART_INT_RX_3_4_FUL &
  149.                   UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR;
  150.    
  151.     /*
  152.      *  Baud = 16Mhz / ( 16 * (baudvalue + 1) ) = 58523
  153.      *  Error % = (58523 - 57600) / 57600 = 0.2124 %
  154.      */
  155.    
  156.     baudvalue = 16;
  157.    
  158.     OpenUART1(UMODEvalue,USTAvalue,baudvalue);
  159.     OpenUART2(UMODEvalue,USTAvalue,baudvalue);
  160. }
  161.  
  162. char * utoa(char * buf, unsigned val, int base)
  163. {
  164.         unsigned        v;
  165.         char            c;
  166.  
  167.         v = val;
  168.         do {
  169.                 v /= base;
  170.                 buf++;
  171.         } while(v != 0);
  172.         *buf-- = 0;
  173.         do {
  174.                 c = val % base;
  175.                 val /= base;
  176.                 if(c >= 10)
  177.                         c += 'A'-'0'-10;
  178.                 c += '0';
  179.                 *buf-- = c;
  180.         } while(val != 0);
  181.         return ++buf;
  182. }

Aca las interrupciones y Traps:

Código: C
  1. #include "xc.h"
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <uart.h>
  5.  
  6.  
  7. uint8_t basura;
  8. extern uint32_t contador1;
  9. extern uint32_t contador2;
  10. uint8_t algo = 0;
  11.  
  12.  
  13. void __attribute__((interrupt,auto_psv)) _U1RXInterrupt(void)
  14. {
  15.     IFS0bits.U1RXIF = 0;
  16. /* Read the receive buffer till atleast one or more character can be read */
  17.     while( DataRdyUART1())
  18.     {
  19.         basura = ReadUART1();
  20.     }
  21.    
  22.     if(contador1>30000)
  23.     {
  24.         // Detenemos laSSSS UARTs y revisamos los contadores
  25.         DisableIntU1RX;
  26.         DisableIntU2RX;
  27.         algo = 1;
  28.     }
  29.     else
  30.     {
  31.         WriteUART1(++contador1);
  32.         WriteUART1(++contador1);
  33.         WriteUART1(++contador1);
  34.     }
  35. }
  36.  
  37. void __attribute__((interrupt,auto_psv)) _U2RXInterrupt(void)
  38. {
  39.     IFS1bits.U2RXIF = 0;
  40. /* Read the receive buffer till atleast one or more character can be read */
  41.     while( DataRdyUART2())
  42.     {
  43.         basura = ReadUART2();
  44.     }
  45.    
  46.     if(contador2>30000)
  47.     {
  48.         // Detenemos laSSSS UARTs y revisamos los contadores
  49.         DisableIntU1RX;
  50.         DisableIntU2RX;
  51.         algo = 1;        
  52.     }
  53.     else
  54.     {
  55.         WriteUART2(++contador2);
  56.         WriteUART2(++contador2);
  57.         WriteUART2(++contador2);    
  58.     }
  59. }
  60.  
  61. /*
  62.  * Defaul de algunos traps del micro, por si las dudas
  63.  */
  64.  
  65. void __attribute__((interrupt,auto_psv)) _OscillatorFail(void)
  66. {
  67.     while(1);
  68. }
  69.  
  70. void __attribute__((interrupt,auto_psv)) _AddressError(void)
  71. {
  72.     while(1);
  73. }
  74.  
  75. void __attribute__((interrupt,auto_psv)) _StackError(void)
  76. {
  77.     while(1);
  78. }
  79.  
  80. void __attribute__((interrupt,auto_psv)) _MathError(void)
  81. {
  82.     while(1);
  83. }
  84.  
  85. void __attribute__((interrupt,auto_psv)) _DMACError(void)
  86. {
  87.     while(1);
  88. }

En resumen hay bastante, pero aca tenes las plibs que deberian facilitarte el codigo, sino podes ir registro por registro como hacias antes.

Citar
me estoy volviendo loco para arrancar.

Tal ves la estas SOBRE pensando, comenza por lo mas basico, comenza con oscilador interno, con un programa que solo configure el TRIS de algun puerto e intenta encender un LED,

Solo necesitas:

Fuses y

Código: C
  1. #include "xc.h"
  2. #define FCY 7370000UL
  3.  
  4.  
  5. int main(void) {
  6.    
  7.         TRISB = 0x0000;     // Bit B13 como salida.
  8.    
  9.         while(1)
  10.         {
  11.                 __delay32(4000000);
  12.                 _LATB0 = ~_LATB0;
  13.         }
  14.    
  15.         return 0;
  16. }

Listo tu primer programa. Es volver a aprender sobre cada modulo.
Una cosa mas, en los PIC24 / dsPIC el reloj se divide por 2 , y no por 4, eso lo vas a ver en el PDF del oscilador.

PD: No es facil, ahora no son mas 2 hojas por cada modulo, sino que son VARIAS por cada uno. Lo bueno es que te podes centrar en una cosa por ves.
« Última modificación: 13 de Mayo de 2016, 23:33:25 por KILLERJC »

Desconectado Pinolillo16

  • PIC18
  • ****
  • Mensajes: 324
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #3 en: 14 de Mayo de 2016, 02:40:29 »
Killer muy buena información, sabes donde existe un tema en el foro que contenga ejemplos en xc16? Como estos que planteas, de a poco creo que sería bueno.

Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #4 en: 14 de Mayo de 2016, 08:29:53 »
No, lo unico que quedo es sobre C30 en su mayoria incluso con las "explicaciones", y normalmente las personas que vienen ya es con algo de experiencia o que ya poseen algun problema que no encuentran solucion y codigo realizado.

Pero pienso que algo como vos estas pidiendo ( comenzar de 0 ) no hay en el foro. En principal por que es muy extenso el tema, como veras con todos los PDF de todos los modulos ( que podes evitar muchos )

Ademas solo tenes que leer esos PDF, comenzando por Oscilador, Interrupciones, Puertos, I2C ( MSSP ), lo demas es C como tenias antes. Hay un par de cambios por supuesto.

Si quisieras saber mas sobre XC16, te recomendaria leer la Guia de usuario de XC16
http://ww1.microchip.com/downloads/en/DeviceDoc/50002071E.pdf


Desconectado altofalantes

  • PIC10
  • *
  • Mensajes: 3
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #5 en: 14 de Mayo de 2016, 09:54:23 »
Muchísimas gracias Killer, era exactamente lo que estaba buscando, un poco de luz para arrancar, algún programa que funcione para ir reescrbiendo cosas sobre él e ir viendo donde empiezo a fallar, y con paciencia y más paciencia a ver si consigo sacarlo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #6 en: 14 de Mayo de 2016, 10:09:12 »
Muchísimas gracias Killer, era exactamente lo que estaba buscando, un poco de luz para arrancar, algún programa que funcione para ir reescrbiendo cosas sobre él e ir viendo donde empiezo a fallar, y con paciencia y más paciencia a ver si consigo sacarlo.

El ultimo que te pase deberia funcionar, aunque no lo probe. Te paso un ZIP con un proyecto que enciende un led cada medio segundo aproximadamente (creo no lo calcule).


Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #7 en: 15 de Mayo de 2016, 05:09:36 »
Tambien le podria venir bien echarle un vistazo a este hilo tuyo KILERJC ¿No?, ya que dice que programa en C y asm, aunque yo creo que para estos PICs va mejor C pero...

http://www.todopic.com.ar/foros/index.php?topic=45240.0

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Dudas básicas con dsPIC33EP512MU810
« Respuesta #8 en: 15 de Mayo de 2016, 14:13:20 »
Ese hilo a pesar que posee algo sobre lo que es "programacion" en general, y como se maneja un poco XC16 por dentro. Es todo de ASM.

Lo unico que hice fue usar puro ASM pero usando el compilador XC16