I've been using an STM32F103C8, trying for a while to get the SPI interface. Been using Atollic TrueStudio. I'm still new at this so if this is a dumb question I hope you'll forgive me.
I can't seem to transmit anything on the SPI interface no matter what I try. I looked through the manual and I thought I did everything correctly but obviously not. From what I read, it seems to be:
- Enable SPI Clock in RCC APB2ENR
- Configure the SPI CR1 Register
- Enable the SPI using the SPE bit
- Transmit by loading data into the SPI-> DR Register
- Receive by reading data from the SPI-> DR register since there is a transmit and a receive buffer linked to SPI->DR
I tried looping back the MOSI pin to the MISO pin and doing a write, and got nothing. I then connected a logic analyser and the SPI clock pin isn't even doing anything. Relevant code below, if anyone can help that'd be great:
void PrintStrToUART(char str[])
{
char *pointertostr;
for (pointertostr = &str[0]; *pointertostr != '\0'; pointertostr++){
USART1 -> DR = (*pointertostr & USART_DR_DR);
while ((USART1 -> SR & USART_SR_TXE) == 0){
;
}
}
}
void PrintCharArrayToUART(unsigned char str[], int arraysize){
int j;
unsigned char buffer[((5*arraysize)-2)];
unsigned char *positionpointer = &buffer[0];
for(j=0; j <= (arraysize-1); j++){
if(j){
positionpointer += sprintf(positionpointer, ", ");
}
positionpointer += sprintf(positionpointer, "%d", str[j]);
}
int newarrayend;
newarrayend = (positionpointer - &buffer[0]);
PrintStrToUART("[");
for(j = 0; j <= newarrayend; j++){
USART1 -> DR = (buffer[j] & USART_DR_DR);
while ((USART1 -> SR & USART_SR_TXE) == 0){
;
}
}
PrintStrToUART("]\n\r");
}
void SelfSPIInit(void){ //because the Mx one is not working
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //Enable SPI clock
//Set baud prescaler
SPI1->CR1 = SPI_CR1_BR; //Slowest SPI I can have
//CPHA CPOL
SPI1-> CR1 &= ~(SPI_CR1_CPOL | SPI_CR1_CPHA);
//8 bit data format
SPI1->CR1 &= ~(SPI_CR1_DFF);
//Full duplex mode
SPI1->CR1 &= ~(SPI_CR1_BIDIMODE);
SPI1->CR1 &= ~(SPI_CR1_RXONLY);
//MSB first
SPI1->CR1 &= ~(SPI_CR1_LSBFIRST);
//Master mode
SPI1->CR1 |= SPI_CR1_MSTR;
//Software NSS mode off
SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI;
//Enable
SPI1->CR1 |= SPI_CR1_SPE;
//Enable the SPI GPIO pins
}
int main(void)
{
int i;
HAL_Init();
/* Configure the system clock */
SystemClock_Config(); //config to run at the correct speed
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
MX_TIM1_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
MX_CRC_Init();
MX_USART2_UART_Init();
MX_ADC1_Init();
MX_TIM3_Init();
//MX_SPI1_Init();
SelfSPIInit();
TIM1 -> CR1 |= TIM_CR1_CEN;
TIM2 -> CR1 |= TIM_CR1_CEN;
I2C1 -> CR1 |= I2C_CR1_PE; //peripheral enable
SPI1 -> CR1 |= SPI_CR1_SPE;
unsigned char newchararray[21] = {0x41};
unsigned char *pnewchararray = &newchararray[0];
unsigned char recarray[7] = {127};
unsigned char *precarray = &recarray[0];
while (1)
{
GPIOC -> BSRR |= GPIO_BSRR_BR13;
GPIOA -> BSRR |= GPIO_BSRR_BR6;
MilliSecondDelay(500);
GPIOC -> BSRR |= GPIO_BSRR_BS13;
GPIOA -> BSRR |= GPIO_BSRR_BS6;
MilliSecondDelay(500);
SPI1->DR = *pnewchararray;
while((SPI1->SR & SPI_SR_TXE) == 0){
//while transmit buffer not empty, wait
;
}
while((SPI1->SR & SPI_SR_RXNE) == 0){
;//while receive buffer not empty
}
*precarray = SPI1->DR;
PrintCharArrayToUART(precarray, 7);
}
}
Sorry about the indenting, as I said I'm still new that this, but that's the code that compiles and runs. Any help appreciated, thanks!
Edit: Wasn't sure if I should include the USART functions, that is just to print to my laptop so I can see what the SPI data register has. But I thought if I included it, the program would make more sense.