Estou tentando configurar o módulo MSSP de um PIC18F25K22 no modo mestre SPI. Estou observando o tempo e o relógio não permanece constante durante toda a transmissão. Uma imagem mostra isso melhor do que palavras.
Depois que um pouco é enviado, o relógio diminui e não na mesma quantidade a cada vez. Eu não trabalhei com SPI antes, mas os diagramas que encontrei na Wikipedia e outros recursos nunca mostram isso. Também conectei um Arduino e não vi esse comportamento. Meu código é:
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
void main(void)
{
OSCCON = 0b11100110;
spi_setup();
__delay_ms(10);
byte temp;
while (TRUE)
{
temp = spi_transfer(0x00);
temp = spi_transfer(0x01);
temp = spi_transfer(0x02);
temp = spi_transfer(0x03);
temp = spi_transfer(0x04);
temp = spi_transfer(0x05);
__delay_us(1);
}
}
void spi_setup(void)
{
SSP1STAT = 0b00000000;
SSP1STATbits.CKE = HIGH; // data transmitted on rising edge
SSP1CON1 = 0b00000000; // enable Master SPI mode
SSP1CON1bits.CKP1 = LOW; //clock idle state is low
//i2c bits, all don't matters for SPI, cleared just in case
SSP1CON3 = 0;
// baud rate generation
SSP1ADD = 0; //FCLOCK = 8Mhz /2 = 2Mhz
// configure pins for output/input as needed
SDI1 = INPUT;
SDO1 = OUTPUT;
SCK1 = OUTPUT;
SS1 = OUTPUT;
SSP1CON1bits.SSPEN1 = HIGH; // enable pins for serial mode
}
unsigned char spi_transfer(unsigned char data)
{
SS1_LAT = LOW; // select slave
PIR1bits.SSPIF = LOW;
SSP1BUF = data;
//while (!SSP1STATbits.BF); //wait for receive to complete
while( !PIR1bits.SSPIF );
SS1_LAT = HIGH; // deselect slave
PIR1bits.SSPIF = LOW; // clear interrupt
return SSP1BUF; //return data from the slave
}
(também https://gist.github.com/stumpylog/5095250 )
Alguém já encontrou isso ou tem sugestões sobre a causa?
O que eu fiz
No final, não consegui colocar o módulo MSSP1 em funcionamento. No entanto, alterá-lo para o módulo MSSP2, exatamente o mesmo código, não exibiu esse comportamento. Não sei explicar, mas isso resolveu o problema.