Estoy utilizando el módulo MSSP de un PIC 18F25K22 ( hoja de datos ) para SPI. Esto funciona correctamente, excepto cuando trato de usar la velocidad de reloj SPI máxima de 16Mhz.
El dispositivo de destino es una tarjeta SD y los síntomas que se describen a continuación ocurren con una selección de diferentes tarjetas, probadas con 6 tarjetas de diferentes fabricantes.
El reloj del microcontrolador es el oscilador interno de 16 MHz con 4x PLL, configurado como se muestra a continuación.
// Internal 64Mhz oscillator
IRCF2 = 1;
IRCF1 = 1;
IRCF0 = 1;
PLLEN = 1;
Diagrama de circuito
La parte relevante del circuito se muestra a continuación, las conexiones van directamente al PIC (tenga en cuenta que usé resistencias de 47 k al montar el PCB).
HayalgunosángulosrectosenlaPCBdonderompílospinesSPIparaladepuración.Enlacapasuperior,losrastrosvanalencabezadodedepuración,enlaparteinferiordelPIC.Incluyoestoencasodequelaintegridaddelaseñalsearelevante.
Loquefunciona
Cualquiervelocidadpordebajodelmáximoteóricofuncionaconéxito.
LasiguienteconfiguracióndebeproducirunrelojSPIde8MHzapartirdelafórmula64000000/(4*2).
//SPIclock=Fosc/(4*(SSPADD+1))SSPCON1bits.SSPM=0b1010;SSP1ADD=1;SSPSTATbits.CKE=1;//Workaroundknownsiliconbug,seeerrataSSPCON1bits.SSPEN=1;
Losdatosseescribenutilizandoelmétodomásbásico,noseutilizaninterrupciones:
unsignedcharspi_byte(uint8_tdata){SSPBUF=data;//Waitforthebuffertofillwithincomingdatawhile(!SSPSTATbits.BF);data=SSPBUF;returndata;}
Cuandosepruebaconunanalizadorlógico,hayunrelojde8Mhzdecenteymicódigofuncionabien:
Loquenofunciona
Megustaríausarelrelojmásrápidoposible,lahojadedatosmuestradosformasdehaceresto:
Deberíapoder:
- Establezcalafrecuenciaderelojdirectamenteen
Fosc/4
- Establezca
SSPxADD=0
paraelmismoefecto-Fosc/(4*(SSPxADD+1))
=Fosc/4*1
Conmirelojde64Mhz,estodeberíaproporcionarunavelocidadderelojSPIteóricade16MhzdesdeelmóduloMSSP.
LainicializacióndeSDrequiereunavelocidadlenta,debajodeestosepuedevermarcadoconel"1" rojo.
Estafaseesexitosa.Porlotanto,deberíapoderacelerar,asíqueprobéconSSP1ADD
puestoacero(estosucedealrededordelmarcador"A1"). El reloj más rápido debe estar presente en el período marcado con un "2" rojo.
SSPCON1bits.SSPEN = 0;
SSP1ADD = 0; // BUG: Set to 1 to make this work, 0 gives unstable clock?
SSPCON1bits.SSPEN = 1;
Sin embargo, esto no funciona y produce un reloj muy inestable de aproximadamente 82Khz, que se muestra a continuación (es un zoom del período marcado como "2" arriba).
Lostresprimerosbytesaquítienenunrelojunpocomásrápido,perotodavíaesdeunos400KHz(muypordebajode16MHz)yelciclodetrabajonoseacercaal50%.Luego,lavelocidaddelrelojcambiamisteriosamentea~82Khzduranteelcuartobyteyesmáscomounaseriedepulsosqueunreloj.
El18F25K22tienecontroldevelocidaddegiro,quetieneunimpacto.Lostrazadosanterioressetomaronconlaconfiguraciónpredeterminada,controldevelocidaddegirohabilitado.Cuandoestádeshabilitada,laconfiguraciónanteriorproporcionaunrelojSPIde400Khz(queesmásestableyfunciona),peroesmuchomáslentodeloquedeberíaser.
Notas
- Nohaynadarelevanteenla
Microchip errata (Tengo un chip de revisión 5) - Trabajo alrededor del único error de MSSP que todavía afecta a la revisión 5 al configurar
CKE = 1
, aunque esto no es relevante para el problema aquí. - Puedo tomar rastreos de alcance si es necesario, pero no lo tengo conmigo ahora mismo.
- Encontré esta pregunta sin respuesta que es similar, pero no puedo ' t cambiar a MSSP2.
Pregunta
¿Alguien sabe si debería poder usar un reloj SPI de 16Mhz o me falta algo en la hoja de datos?