TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: ALE1973 en 18 de Abril de 2008, 10:02:03
-
Buenas a todos, tengo implementada una comunicacion SPI en CCS con un 16F873, todo bien y funcionando, pero despues de pasar el circuito del protoboard a una placa de fenolico, aparecen ciertas cosas raras, la placa esta bien, ya la revise y la volvi a revisar, le cuento el problema, el SPI esta hecho por hardware, lo curioso es que si pongo la lectura o escritura del esclavo en el main() de la aplicacion, el pic genera el clock y los datos para el esclavo, ahora bien, si esa escritura o lectura la hago desde una funcion que llamo desde el main(), no genera ni el clock ni el dato, la rutina estoy seguro que se ejecuta, debido a que en el osciloscopio veo que baja y sube la pata del chip select, que esta antes antes y despues de la instruccion read_spi() respectivamente.
El programa espera una cadena de comandos desde la pc, en funcion de lo que envia la pc, se puede leer o escribir al esclavo SPI, esa evaluacion del comando enviado por la pc se hace en una funcion que se llama desde el main() despues que se completo la recepcion desde la PC.
En el archivo adjunto esta el codigo completo, tal como esta asi, el pic no genera el clock ni el dato para el esclavo SPI, ahora si lo coloco como lo pego a continuacion, el pic genera bien el codigo.
Probe a compilarlo con el CCS 4.0038, el 0057, y en ambos hace lo mismo.
Desde ya gracias.
Alejandro.
void main(){
int i=0;
//++++++++++++++++++Configura puertos analogicos++++++++++++++++++++++++++++++
setup_adc( ADC_CLOCK_INTERNAL );
setup_adc_ports( ALL_ANALOG ); // Ver que puertos van a ser analogicos
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_tris_a(0b11111111);
set_tris_b(0b00000000);
set_tris_c(0b10010010);
setup_spi(spi_master|spi_l_to_h|spi_clk_div_64);
//// seteo como deben estar cada uno de los pines del pic para empezar la comunicacion
output_high(pin_B1);
////seteo la transmision
delay_ms(500);
inicbuffRX(); // Borra buffer al inicio
inicbuffTX(); // Borra buffer al inicio
enable_interrupts(int_rda); // Habilita Interrupción RDA
// enable_interrupts(int_ext); // Habilita Interrupción RB0, PASO DE ALTO A BAJO
ext_int_edge(H_TO_L);
enable_interrupts(global); // Habilita interrupciones
//// mando dato al pote por spi para R=71.5K
//// mando primero el command byte y despues el dato
while(true){
spi_write(5);
}
}
-
El problema esta en el compilador, es decir la version...
Si te fijas en el listado de versiones, veras que en las ultimas esta resuelto...
4.071 A debugger problem is resolved
4.070 Some IDE issues including hidden debugger screens have been fixed
4.070 I2C slave algorithms have been updated for some chips
4.069 Compiler R/W files are now kept in the windows APPDATA directory
4.069 An interrupt bug on many PCD devices is fixed
4.069 A PCD optimization error is fixed
4.068 RS232 software timing improved a little
4.068 A math error (since 4.067) when mixing ints and floats is fixed
4.067 An addressmod bug has been fixed
4.067 A problem with LCD_SYMBOL when using more than 8 segments per symbol is fixed
4.067 An undeserved syntax error some users got in #bit is fixed
4.067 A number of PCD problems have been fixed
4.066 New PCD built in functions have been added
4.066 A problem with Vista access violations is fixed
4.065 Issues using the ICD with chips that do not report a device ID are solved
4.065 A number of PCD problems have been fixed including problems with bit fields in structures
4.064 Support for Real-ICE and ICD2 has been added
4.063 A number of bug fixes made for the PCD (24 bit) compiler
4.062 An error concerning extra data on a #device line has been corrected
4.061 A problem with #USE SPI and the hardware SPI pins is fixed
4.061 A problem linking for ICD debugging is fixed
4.061 24 Bit Wizard added to the IDE
4.060 Support has been added to allow multiple ICD units connected to the same PC
4.059 An optimization problem involving getc() in an expresion is fixed
4.059 A problem managing breakpoints in the IDE is fixed
4.058 Chip specific PCD interrupt problems are now fixed
Fue resuelto a partir de la version 4.061..
-
Gracias MGLSOFT, pero hace 3 dias atras funcionaba, y la version mas alta que tengo es la que te indique, como puede ser???, en fin voy a ver si consigo una version mas nueva y pruebo, gracias.
Alejandro
-
Hola Ale.
Yo tambien estoy trabajando con el Ade y me gustaria intercambiar impresiones y experiencia. Ya tengo armada la placa con todo y los TC estoy tambien trabajando con la comunicacion SPI. Voy a cargar tu programa y probar a ver si te puedo ayudar.
Te comento que el proyecto que tengo es incluir comunicacion ethernet y una memoria SD para almacenamiento de datos.
La parte del ethernet ya la tengo terminada, otro ingeniero esta trabajando en el software.
Asi que aqui estoy para hecharlo a volar mas rapido.
-
Hola de nuevo, confirmado, la version del compilador no es, hoy compile el codigo con una version mayor y sigue haciendo lo mismo.
Saludos.
-
En estos casos tan raros creo que lo ideal es ir probando cosas que, aunque parezcan absurdas, pueden ir dando pistas hasta encontrar el error.
En el ejemplo que te funciona has puesto:
while(true){
spi_write(5);
}
mientras que no te funciona donde haces:
spi_write(dir);
...
spi_write(temp);
...
spi_write(0x7e);
¿Porqué no pruebas a poner el bucle infinito que sí funciona dentro de la función Lee_ade() ?
Si sigue sin funcionar, habrá que seguir investigando, puesto que la razón será que no funciona desde una función (cosa rara). Pero sin embargo si funciona bien, descartarás ese motivo y tendrás que averiguar qué haces mal en tu función...
-
Manolo, gracias por responder, te comento que lo que esta probado en el main(), funciona, probe a colocar una write_spi y read_spi, y ambas funcionan, cosa rara, ya que puesta asi dentro de una funcion, tambien funcionaba...
El proximo paso es arrancar desde cero probando funcion por funcion, primero desde el main y luego llamarla desde una funcion, estoy seguro que es una pavada, pero no puedo encontrarla, ya les contare los resultados...
Gracias.
Saludos.
Alejandro.
-
Buenas, despues de mucho renegar, he notado en el archivo list, que el compilado es el que no hace la llamda, por ejemplo:
En este codigo que les copio a continuacion, es la funcion que llamo desde el main, si miran la linea 144, veran que carga el parametro de la funcion leer_ADE, pero no hay ninguna goto..., probe a compilar en la version 3.249 el mismo codigo, y obtengo exactamente lo mismo.
.................... void procesa_comando(void){
.................... int i=0;
*
0133: CLRF 3F
*
022A: SLEEP
.................... int1 a=0;
*
0134: BCF 40.0
.................... flagcommand=0; // Desactivo flag de comando pendiente.
0135: BCF 3C.0
.................... if(rxbuff[0]=='\\'&& rxbuff[1]=='r'){
0136: MOVF 36,W
0137: SUBLW 5C
0138: BTFSS 03.2
0139: GOTO 18E
013A: MOVF 37,W
013B: SUBLW 72
013C: BTFSS 03.2
013D: GOTO 18E
.................... i=rxbuff[2];
013E: MOVF 38,W
013F: MOVWF 3F
.................... txlen= lenade[i]+1;
0140: MOVF 3F,W
0141: CALL 053
0142: ADDLW 01
0143: MOVWF 3D
.................... leer_ADE(i);
0144: MOVF 3F,W
0145: MOVWF 41
.................... txBuff [0]=i;
*
018C: MOVF 3F,W
018D: MOVWF 31
.................... }
En cambio, si llamo desde el main a la funcion leer_ADE, como esta en el codigo que pego a continuacion, veran que llama a la funcion en la linea 1CC.
.................... while(true){
.................... if(flagcommand)leer_ADE(0x24);
01C8: BTFSS 3C.0
01C9: GOTO 1CD
01CA: MOVLW 24
01CB: MOVWF 3F
01CC: GOTO 12F
.................... }
Cosa rara si la hay... sigo investigando...
Saludos.
Alejandro
-
Prueba hacer un solo cambio.
Poner la variable i declarada en Main(), como global.
declarala fuera de la funcion Main(), de modo que sea global, a ver si va, creo que tu problema es de alcance de la variable, y el equivoco viene porque usas varias variables i en las funciones, pero ellas mueren dentro de la funcion... :mrgreen:
-
Hola a todos, antes de nada muchas gracias por el tiempo que le puedan dedicar.
Estoy haciendo un programa con un 16f873A escribiendo como slave por SPI.
La cuestión es que necesito la librería #use spi de ccs para enviar datos de mas de 8bits pero no hay forma de encontrarla por ningun lado. Lo mas cerca que he estado es de una explicación (http://www.ccsinfo.com/content.php?page=spi) en la pagina de ccs pero no he visto nada más.
agradecería muchisimo que me dijerais donde puedo conseguirla pues estoy con el proyecto de final de carrera y el tiempo se me hecha encima :?
1000 gracias nuevamente!
-
Perdon, Usuari0, pero interpretaste mal.... :lol: :lol:
#Use_SPI() no es una libreria, es una declaracion que haces en el programa para comenzar a utilizar el SPI por hardware o por software, segun que pines declares...
El codigo que genera esta funcion interna del CCS no es accesible para ti, solo puedes mirar lo que genera en assembler en la ventana de assembler, pero nada mas...
Si quieres y el dispositivo lo soporta (no se de que se trata) puedes hacer SPI por software, un ejemplo claro es la libreria del conversor A/D MCP3204 o MCP3208, donde se lee y escribe por SPI por software, y estan legibles los codigos de todas las funciones...
Espero haber ayudado. :mrgreen: :mrgreen:
-
hey muchas gracias por la rapidez!!
estoy con un pic16f873A, ¿es el pic el dispositivo que tiene que soportar el spi por software?¿como lo puedo saber?
cuando pongo en el mplab:#use spi() el compilador ccs me contesta: Error 101 (...)Library in USE not found "SPI"
Mi intención es usar la instruccion spi_xfer() pero antes debo añadir el #use spi. Quiero comunicarme con una dsp que tiene un buffer de recepcion de 16 bits, justo la cantidad que deseo enviar.
a lo mejor mi error es que no estoy declarando nada de entradas ni salidas referentes al spi por software. solo pongo:
(...)
setup_spi (SPI_SLAVE | SPI_H_TO_L | SPI_XMIT_L_TO_H);
(...)
set_tris_a(0b100011); //pongo el (RA1)SS como entrada
set_tris_b(0b00000000);
set_tris_c(0b00011000);
//configurolas I/O del SPI:RC3=SCK y RC4=SDI --> Entradas
//considerando 0=salida 1=entrada
Como seguro que te falta información explicare un poco mejor cual es la situación:
el pic como slave tiene que enviar un dato de 16b. pero el sspbuf (buffer rx) es de 8b. Si envio 8bits no hay problema porque la DSP (master) lo recibe bien.
y aqui viene el problema:
no puedo enviar 16bits con la instrucción spi_xfer() sin declarar #use spi.
gracias!! :-)
-
Puedes subir una imagen del esquematico??
Aunque sea un escaneo de un dibujo a mano alzada estara bien, asi vemos como conectas todo...
-
No sé si sea importante pero igual lo voy acotar, creo que te falta un guión subrayado, fijate bien usuario0 como te dice MGLSOFT que lo declares y como nos escribes que lo estas declarando, (guión sub_rayado :wink:)
#Use_SPI() no es una libreria, es una declaracion que haces en el programa para comenzar a utilizar el SPI por hardware o por software, segun que pines declares...
...
cuando pongo en el mplab:#use spi() el compilador ccs me contesta: Error 101 (...)Library in USE not found "SPI"
Saludos.
-
siento haber tardado tanto, a nadie le interesa esto mas que a mi. Me fuí a comer :)
aqui está el esquematico y el resultado de la placa. el puerto en blanco que ves es por donde sale el SPI a full-duplex a otra placa mucho mas grande con una dsp de Texas que no he diseñado yo.
gracias!
-
gracias guillermo por tu aportación.
Teneis razon al respecto. lo he escrito erróneamente. sin embargo y muy a mi pesar me sigue dando error.
me pone: (...)Invalid Pre-Processor directive
por cierto, en teoría son opciones que ya estan "build-in" no? como por ejemplo
#use delay(clock=4000000)
es decir, el compilador debería dejar que se usase este tipo de instrucciones sin añadir nada especial no? fijaos en este link (http://www.ccsinfo.com/content.php?page=compspecific). aqui aparece #use spi separado en el apartado de built in libraries y la funcion spi_xfer() en built in functions.
gracias por el esmero!
-
Necesita parametros declarados, hay algunos que son optativos, pero otros no, mira bien la ayuda del CCS.
Igual creo que si declaras con Setup_SPI() no necesitas el use_spi()...
-
creo que entiendo lo que me sugieres MGLSOFT, pero ¿crees que puedo usar el spi_xfer() sin #use spi?
Con setup_spi() (config del spi por hardware) puedo hacerlo perfectamente siempre y cuando no envíe mas de 8 bits.
Muchas gracias por tu atención.
voy a mirar de nuevo en profundidad la ayuda del CCS.
saludos a todo el foro!
es la primera vez que participo en uno y me ha sorprendido la rapidez...