簡體   English   中英

在STM32F4 Discovery上配置SPI

[英]Configure SPI on STM32F4 Discovery

用示波器上的引腳進行測量時,無法從MOSI引腳或CLK引腳中獲取任何數據。

這是我的代碼:

包括

包括“ stm32f407xx.h”

無效的delay(){

                  int i;

                  for(i = 0; i < 1000000; i++);

}

int main(){

           // Enable RCC APB2 clock for SYSCFG (for externalinterrupt)
                  RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
                  // Enable RCC APB1 clock for SPI2
                  RCC->APB1ENR |= (1 << 14);
                  // GPIOA for pushbutton
                  RCC->AHB1ENR |= (1 << 0);
                  // GPIOB for SPI
                  RCC->AHB1ENR |= (1 << 1);
                  // GPIOD for LED
                  RCC->AHB1ENR |= (1 << 3);

////////用於MOSI,MISO och CLK引腳的GPIO B初始化:

                  GPIOB->MODER |= (2 << (2*13)); //Sets pin 13 as Alternate function
                  GPIOB->MODER |= (2 << (2*14)); //Sets pin 14 as Alternate function
                  GPIOB->MODER |= (2 << (2*15)); //Sets pin 15 as Alternate function
                  GPIOB->OTYPER |= PUSH_PULL_PIN_13;
                  GPIOB->OTYPER |= PUSH_PULL_PIN_14;
                  GPIOB->OTYPER |= PUSH_PULL_PIN_15;

                  GPIOB->OSPEEDR |= OSPEEDR_MEDIUM_PIN_13;
                  GPIOB->OSPEEDR |= OSPEEDR_MEDIUM_PIN_14;
                  GPIOB->OSPEEDR |= OSPEEDR_MEDIUM_PIN_15;

                  GPIOB->PUPDR |= PUPDR_PULLDOWN_PIN_13; // Pull down for CLK
                  GPIOB->PUPDR |= PUPDR_PULLUP_PIN_14; // Pull up for MISO
                  GPIOB->PUPDR |= PUPDR_PULLUP_PIN_15; // Pull up for MOSI

                  GPIOB->AFR[1] |= ALT_FUNC_AF5_PIN_13;  // 5 för AF5 till pin 13
                  GPIOB->AFR[1] |= ALT_FUNC_AF5_PIN_14;  // 5 för AF5 till pin 14
                  GPIOB->AFR[1] |= ALT_FUNC_AF5_PIN_15;  // 5 för AF5 till pin 15

//////////按鈕的GPIO A初始化

                  GPIOA->MODER |= MODER_INPUT_PIN_0;

用於LED的GPIO D初始化

                  GPIOD->MODER |= MODER_OUTPUT_PIN_12; //Sets pin 12 as output
                  GPIOD->MODER |= MODER_OUTPUT_PIN_13; //Sets pin 13 as output
                  GPIOD->MODER |= MODER_OUTPUT_PIN_14; //Sets pin 14 as output
                  GPIOD->MODER |= MODER_OUTPUT_PIN_15; //Sets pin 15 as output

                  GPIOD->OTYPER |= PUSH_PULL_PIN_12;
                  GPIOD->OTYPER |= PUSH_PULL_PIN_13;
                  GPIOD->OTYPER |= PUSH_PULL_PIN_14;
                  GPIOD->OTYPER |= PUSH_PULL_PIN_15;

                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_12;
                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_13;
                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_14;
                  GPIOD->OSPEEDR |= OSPEEDR_MEDIUM_PIN_15;

                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_12; //Frågetecken på denna, ska det vara 0 1 eller 2??
                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_13; //Frågetecken på denna, ska det vara 0 1 eller 2??
                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_14; //Frågetecken på denna, ska det vara 0 1 eller 2??
                  GPIOD->PUPDR |= PUPDR_PULLDOWN_PIN_15; //Frågetecken på denna, ska det vara 0 1 eller 2??

                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_12;  // 0 för AF0 till pin 12
                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_13;  // 0 för AF0 till pin 13
                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_14;  // 0 för AF0 till pin 14
                  GPIOD->AFR[1] |= ALT_FUNC_AF0_PIN_15;  // 0 för AF0 till pin 15

//////// SPI初始化

                  SPI2->CR1 |= (0 << CR1_CLOCK_PHASE);       //Set clockphase in CR1 register
                  SPI2->CR1 |= (1 << CR1_CLOCK_POLARITY);    //Set polarity in CR1 register
                  SPI2->CR1 |= (4 << CR1_BAUD_RATE);         //Set baudrate
                  SPI2->CR1 |= (1 << CR1_DATA_FRAME_FORMAT); //16-bit transmission
                  SPI2->CR1 |= (1 << CR1_ENABLE_SPI);        //Enable SPI
                  SPI2->CR1 |= (1 << CR1_MASTER_SELECT);     //MASTER SELECTION
                  SPI2->CR1 |= (1 << CR1_LSB_FIRST);         //LSB FIRST
                  SPI2->CR1 |= (1 << CR1_SLAVE_SELECT);      //SSI set
                  SPI2->CR1 |= (1 << CR1_SW_SLAVE_MANAGE);   //SSM, software slave management selected, which means SSI will be used insted of I/O
                  SPI2->CR1 |= (0 << CR1_RECEIVE_ONLY);      //Transmit and Receive
                  SPI2->CR1 |= (0 << CR1_CRC_TRANSFER);      //NOT USED, CRC
                  //SPI2->CR1 |= (0 << CR1_CRC_CALCULATION); //NOT USED, CRC calculation disabled
                  //SPI2->CR1 |= (0 << CR1_BIDIOE);          //enable transmit-only if set
                  SPI2->CR1 |= (0 << CR1_BIDIMODE);          //1-line bidirectional mode if set

/////////啟用外部中斷

                  //SYSCFG->EXTICR[0] |= (0 << 0); //Enable
                  EXTI->IMR |= (1 << 0);      //Enable interrupt
                  EXTI->RTSR |= (1 << 0);    //set Risnig edge interrupt
                  EXTI->FTSR |= (0 << 0);    //falling edge interrupt (disabled)
                  NVIC_EnableIRQ(EXTI0_IRQn);
                  SPI2->CR2 |= (1 << 7);

                  while(1){
                         GPIOD->ODR |= (1 << 12); // led ON
                         delay();
                         GPIOD->ODR &= ~(1 << 12); // led OFF
                         delay();
                  }

                  return 0;

}

無效EXTI0_IRQHandler(){

         EXTI->PR |= (1 << 0); //Clears interrupt pending bit

         while(1){
                GPIOD->ODR |= (1 << 13); //Blå led ON
                delay();
                GPIOD->ODR &= ~(1 << 13); //Blå led OFF
                delay();
                // Here I want to Send Data
                SPI2->DR |= 0xFF;
         }

}

請使用來自stm32f407xx.h文件的適當的宏定義。 更好地閱讀:

TIM2->DIER |= TIM_DIER_UIE; /* interrupt enable on 1st channel */

比:

TIM2->DIER |= (1 << 1); /* interrupt enable on 1st channel */

這樣可以避免混亂,並可以指出問題出在哪里。 在當前代碼格式下,如果正確設置寄存器,則需要花費大量時間進行解碼。

編輯:好的,聞到一些氣味:

GPIOD->AFR[1] |= (0 << (30));  // 5 för AF0 till pin 15

AFR寄存器的每個引腳為4位。 您為什么要轉移價值30? 不應該是28嗎?

edit_2:您的按鈕是否觸發EXTI irq? 如果是,那就不好了。。。我不記得板上是否有提供按鈕反跳功能的硬件,即使您應該將其放入代碼中。 現在,中斷可能被觸發很多次,而不是按1 irq = 1按鈕。

edit_3:

SPI2->CR2 |= (1 << 7);

當TX緩沖區為空時啟用irq。 緩沖區為空,直到您按下按鈕。 這會導致不停地調用SPI2中斷,並且您尚未為其定義處理程序。 嘗試闡明您要實現的目標以及應該如何實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM