C STM32 SPI传输

C STM32 SPI传输,c,stm32,spi,cubemx,truestudio,C,Stm32,Spi,Cubemx,Truestudio,我一直在使用STM32F103C8,尝试获取SPI接口。一直在使用Atolic TrueStudio。我还是个新手,如果这是个愚蠢的问题,我希望你能原谅我 无论我做什么尝试,我似乎都无法在SPI接口上传输任何内容。我看了一下手册,我认为我做的每件事都是正确的,但显然不是。从我所读到的,似乎是: 在RCC APB2ENR中启用SPI时钟 配置SPI CR1寄存器 使用SPE位启用SPI 通过将数据加载到SPI->DR寄存器进行传输 通过从SPI->DR寄存器读取数据进行接收,因为有一个发送和接收

我一直在使用STM32F103C8,尝试获取SPI接口。一直在使用Atolic TrueStudio。我还是个新手,如果这是个愚蠢的问题,我希望你能原谅我

无论我做什么尝试,我似乎都无法在SPI接口上传输任何内容。我看了一下手册,我认为我做的每件事都是正确的,但显然不是。从我所读到的,似乎是:

  • 在RCC APB2ENR中启用SPI时钟
  • 配置SPI CR1寄存器
  • 使用SPE位启用SPI
  • 通过将数据加载到SPI->DR寄存器进行传输
  • 通过从SPI->DR寄存器读取数据进行接收,因为有一个发送和接收缓冲区链接到SPI->DR
我试着把MOSI别针和味噌别针连在一起,然后写了一篇文章,结果一无所获。然后我连接了一个逻辑分析仪,SPI时钟引脚甚至什么都没做。下面的相关代码,如果有人能帮忙,那就太好了:

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);
 }
}
void printstrtuart(char str[])
{
字符*pointertostr;
for(pointertostr=&str[0];*pointertostr!='\0';pointertostr++){
USART1->DR=(*pointertoster&USART\u DR\u DR);
而((USART1->SR&USART\U SR\U TXE)==0){
; 
}
}
}
void printchararrayTuart(无符号字符str[],int-arraysize){
int j;
无符号字符缓冲区[((5*arraysize)-2)];
无符号字符*位置指针=&缓冲区[0];
对于(j=0;j SR&USART\u SR\u TXE)==0){
;
}
}
printstrtuart(“]\n\r”);
}
void SelfSPIInit(void){//因为Mx-one不工作
RCC->APB2ENR |=RCC_APB2ENR_SPI1EN;//启用SPI时钟
//设置波特率预分频器
SPI1->CR1=SPI\u CR1\u BR;//我能拥有的最慢的SPI
//CPHA-CPOL
SPI1->CR1&=~(SPI_CR1_CPOL | SPI_CR1_CPHA);
//8位数据格式
SPI1->CR1&=~(SPI_CR1_DFF);
//全双工模式
SPI1->CR1&=~(SPI_CR1_BIDIMODE);
SPI1->CR1&=~(SPI_cr1xonly);
//MSB优先
SPI1->CR1&=~(SPI_CR1_LSBFIRST);
//主模式
SPI1->CR1 |=SPI_CR1_MSTR;
//软件NSS模式关闭
SPI1->CR1 |=SPI_CR1_SSM | SPI_CR1_SSI;
//使能
SPI1->CR1 |=SPI_CR1_SPE;
//启用SPI GPIO引脚
}
内部主(空)
{
int i;
HAL_Init();
/*配置系统时钟*/
SystemClock_Config();//配置以正确的速度运行
/*初始化所有配置的外围设备*/
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;//外围设备启用
SPI1->CR1 |=SPI_CR1_SPE;
无符号字符newcharray[21]={0x41};
无符号字符*pnewcharray=&newcharray[0];
无符号字符重新排列[7]={127};
无符号字符*precarray=&recarray[0];
而(1)
{
GPIOC->BSRR |=GPIO_BSRR_BR13;
GPIOA->BSRR |=GPIO_BSRR_BR6;
毫秒延迟(500);
GPIOC->BSRR |=GPIO_BSRR_BS13;
GPIOA->BSRR |=GPIO_BSRR_BS6;
毫秒延迟(500);
SPI1->DR=*PNEWCHARRAY;
而((SPI1->SR&SPI_SR_TXE)==0){
//当传输缓冲区不为空时,请等待
;
}
而((SPI1->SR&SPI_SR_RXNE)=0){
;//当接收缓冲区不为空时
}
*precarray=SPI1->DR;
打印字符库(precarray,7);
}
}
很抱歉出现了缩进,正如我所说的,我仍然是新手,但这是编译和运行的代码。感谢您的帮助,谢谢


编辑:我不确定是否应该包括USART函数,这只是为了打印到我的笔记本电脑上,以便我可以看到SPI数据寄存器有什么。但是我想如果我把它包括进来,这个程序会更有意义。

另一个是:看起来你忘记了pin多路复用。

请看一下。stm32f103有一个完整的spi示例。

USART和spi之间有很大的区别。它们是两个完全不同的协议。你想实现哪一个?