اطلاعیه

Collapse
No announcement yet.

مشکل با دریافت اطلاعات از SPI در میکرو STM32

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    مشکل با دریافت اطلاعات از SPI در میکرو STM32

    سلام دوستان
    یه برنامه توی کیل نوشتم که اطلاعات رو از SPI1 ارسال میکنم و توی SPI2 اون رو دریافت میکنم . موقع ازسال و دریافت اطلاعات هم وقفه رو فعال کردم.
    مشکل من اینجاست که اطلاعات درستی دریافت نمیکم (ارسال درست انجام میشه و وقفه های ارسال و دریافت هم عمل میکنن ولی دیتا درست دریافت نمیشه)
    برنامه با STM32CUBEMX نوشته شده (HAL)
    کد:
    [LEFT]
    [CPP]
    #include "main.h"
    #include "stm32f4xx_hal.h"
    #include <stdio.h>
    #include <string.h>
    
    
    SPI_HandleTypeDef hspi1;
    SPI_HandleTypeDef hspi2;
    
    
    char Data_Tx2=1;
    char Data_Rx=0;
    char i=0;
    
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_SPI1_Init(void);
    static void MX_SPI2_Init(void);
    
    
    void HAL_SPI_RxCpltCallback (SPI_HandleTypeDef * hspi)
    {
    
    
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1); 
    
    
        for(i=0;i<Data_Rx;i++)
        {
           HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
          HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);   
          }
    
    
      HAL_SPI_Receive_IT(&hspi2,(uint8_t*)&Data_Rx,1);
    
    
    }
    
    
    void HAL_SPI_TxCpltCallback (SPI_HandleTypeDef * hspi)
    {
    
    
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
    
    
    }
    
    
    
    
    int main(void)
    {
    
    
      HAL_Init();
    
    
      /* Configure the system clock */
      SystemClock_Config();
    
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_SPI1_Init();
      MX_SPI2_Init();
    
    
     HAL_SPI_Receive_IT(&hspi2,(uint8_t*)&Data_Rx,1);
    
    
      while (1)
      {
      HAL_SPI_Transmit_IT(&hspi1,(uint8_t*)&Data_Tx2,1);
      while(HAL_SPI_GetState(&hspi1)!=HAL_SPI_STATE_READY);
      HAL_Delay(100); 
    
    
      Data_Tx2++;
      }
    
    
    }
    
    
    
    
    void SystemClock_Config(void)
    {
    
    
      RCC_OscInitTypeDef RCC_OscInitStruct;
      RCC_ClkInitTypeDef RCC_ClkInitStruct;
    
    
        /**Configure the main internal regulator output voltage 
        */
      __HAL_RCC_PWR_CLK_ENABLE();
    
    
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
    
        /**Initializes the CPU, AHB and APB busses clocks 
        */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.HSICalibrationValue = 16;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
    
    
        /**Initializes the CPU, AHB and APB busses clocks 
        */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
    
    
        /**Configure the Systick interrupt time 
        */
      HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
    
    
        /**Configure the Systick 
        */
      HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
    
    
      /* SysTick_IRQn interrupt configuration */
      HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
    }
    
    
    /* SPI1 init function */
    static void MX_SPI1_Init(void)
    {
    
    
      /* SPI1 parameter configuration*/
      hspi1.Instance = SPI1;
      hspi1.Init.Mode = SPI_MODE_MASTER;
      hspi1.Init.Direction = SPI_DIRECTION_2LINES;
      hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
      hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi1.Init.NSS = SPI_NSS_SOFT;
      hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
      hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi1.Init.CRCPolynomial = 10;
      if (HAL_SPI_Init(&hspi1) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
    
    
    }
    
    
    /* SPI2 init function */
    static void MX_SPI2_Init(void)
    {
    
    
      /* SPI2 parameter configuration*/
      hspi2.Instance = SPI2;
      hspi2.Init.Mode = SPI_MODE_SLAVE;
      hspi2.Init.Direction = SPI_DIRECTION_2LINES;
      hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
      hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
      hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi2.Init.CRCPolynomial = 10;
      if (HAL_SPI_Init(&hspi2) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
    
    
    }
    
    
    /** Configure pins as 
            * Analog 
            * Input 
            * Output
            * EVENT_OUT
            * EXTI
    */
    static void MX_GPIO_Init(void)
    {
    
    
      GPIO_InitTypeDef GPIO_InitStruct;
    
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);
    
    
      /*Configure GPIO pins : PB0 PB1 */
      GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_PULLDOWN;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
    
    }
    
    
    /* USER CODE BEGIN 4 */
    
    
    /* USER CODE END 4 */
    
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * [MENTION=17545]para[/MENTION]m  file: The file name as string.
      * [MENTION=17545]para[/MENTION]m  line: The line in file as a number.
      * @retval None
      */
    void _Error_Handler(char *file, int line)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
      while(1)
      {
      }
      /* USER CODE END Error_Handler_Debug */
    }
    
    
    #ifdef  USE_FULL_ASSERT
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * [MENTION=17545]para[/MENTION]m  file: pointer to the source file name
      * [MENTION=17545]para[/MENTION]m  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t* file, uint32_t line)
    { 
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
    
    
    /**
      * @}
      */
    
    
    /**
      * @}
      */
    
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/[/CPP][/LEFT]
    [CPP]
    [/CPP]
    [FONT=Yekan][/LEFT][/FONT]

    #2
    پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

    نوشته اصلی توسط ahmadelectronic نمایش پست ها
    سلام دوستان
    یه برنامه توی کیل نوشتم که اطلاعات رو از SPI1 ارسال میکنم و توی SPI2 اون رو دریافت میکنم . موقع ازسال و دریافت اطلاعات هم وقفه رو فعال کردم.
    مشکل من اینجاست که اطلاعات درستی دریافت نمیکم (ارسال درست انجام میشه و وقفه های ارسال و دریافت هم عمل میکنن ولی دیتا درست دریافت نمیشه)
    سلام،
    من فرصت نکردم برنامه ات رو نگاه کنم،
    چیزی که به ذهن من میرسه، اینه که:
    سرعت انتقالتون چقدر است؟!
    توی STM32 پریفرال SPI1 روی باس داخلی APB2 است و بقیه SPI-2-3-4-... روی باس APB1 قرار دارند!
    و از اونجایی که حداکثر سرعت مجاز APB2 دو برابر حداکثر سرعت APB1 میباشد! رعایت نکردن سرعت حداکثر APB1 میتونه مشکل ساز باشه!!
    بررسی کن ببین مربوط به این موضوع نیست؟
    جدیدترین ویرایش توسط ubub; ۰۹:۴۵ ۱۳۹۷/۰۱/۲۷.
    ◙◙◙◙◙ میخوام به دوستان یه کتاب معرفی کنم! وقت کردید، بخونید - اسمش هست قرآن، سال نشر 10، نویسنده: خدا . ◙◙◙◙◙

    دیدگاه


      #3
      پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

      دوستان برای اینکه چک کرد یک آی سی که با spi کار میکنه سالم هست یا نه چه روشی میشه بکار برد؟
      روشی بجز ارتباط مستقیم با spi منظورم هست

      دیدگاه


        #4
        پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

        نوشته اصلی توسط hosseinkomijani نمایش پست ها
        دوستان برای اینکه چک کرد یک آی سی که با spi کار میکنه سالم هست یا نه چه روشی میشه بکار برد؟
        روشی بجز ارتباط مستقیم با spi منظورم هست
        با سلام و احترام
        برای بررسی و اطمینان از صحت ارتباطاتی مثل RS-232 و I2C و SPI و ... بهترین و مناسبترین راه استفاده از لاجیک آنالایزر هست لازم هم نیست هزینه زیادی کنید لاجیک آنالایزرهای ساده مثل مورد لینک زیر نیز بخوبی برای بررسی مشکلات مرتبط با این پروتکلها جوابگوست. نرم افزار این لاجیک آنالایزر قادر به دیکد و نمایش پکتها نیز میباشد. من خودم از همین مدل قبلا گرفته ام و اگر کیفیت این سری هم مشابه قبلیها باشد آنرا به دوستانی که زیاد با میکرو سروکار دارند توصیه میکنم.



        موفق باشید.

        دیدگاه


          #5
          پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

          نوشته اصلی توسط evergreen نمایش پست ها
          با سلام و احترام
          برای بررسی و اطمینان از صحت ارتباطاتی مثل RS-232 و I2C و SPI و ... بهترین و مناسبترین راه استفاده از لاجیک آنالایزر هست لازم هم نیست هزینه زیادی کنید لاجیک آنالایزرهای ساده مثل مورد لینک زیر نیز بخوبی برای بررسی مشکلات مرتبط با این پروتکلها جوابگوست. نرم افزار این لاجیک آنالایزر قادر به دیکد و نمایش پکتها نیز میباشد. من خودم از همین مدل قبلا گرفته ام و اگر کیفیت این سری هم مشابه قبلیها باشد آنرا به دوستانی که زیاد با میکرو سروکار دارند توصیه میکنم.



          موفق باشید.
          مهندس جان این کار اسکوپ رو می*کنه؟ یا فرق داره؟ چیزی که من دیدم شبیه این اسکوپ*های پرتبل میمونه؟
          چه جوری باش باید کار کرد؟

          دیدگاه


            #6
            پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

            نوشته اصلی توسط hosseinkomijani نمایش پست ها
            مهندس جان این کار اسکوپ رو می*کنه؟ یا فرق داره؟ چیزی که من دیدم شبیه این اسکوپ*های پرتبل میمونه؟
            چه جوری باش باید کار کرد؟
            با سلام مجدد
            این کار اسیلوسکوپ را نمیکند چون ورودی های آن تنها قادر به تشخیص سطوح لاجیکی 0 و 1 میباشد و نباید ولتاژ بیشتر از 5 ولت به ورودیهای آن اعمال کنید. ولی سرعت نمونه برداری آن با توجه به قیمت مناسب میباشد. در ویدیوی زیر میتوانید با مشخصات و نحوه کارکرد آن آشنا شوید.

            موفق باشید.

            دیدگاه


              #7
              پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

              عرض سلام و احترام خدمت دوستان و استادان عزیز. بنده چند وقتی هست که درگیر ارسال اطلاعات یک شتاب سنج از طریق spi در میکرو STM32F030 هستم. کدها با توابع سطح پایین نوشته نوشته شده اند. مشکل اصلی اینجاست که اطلاعات خوانده شده پس و پیش و در بسیاری از مواقع نادرست می باشند. برای نمایش اطلاعات خوانده شده هم از /UART استفاده میکنم. مساله ای دیگه ای که خودم متوجه آن شدم و نتونستم برطرفش کنم، ست شدن فلگ overrun در هر بار استفاده از تابع spi_transmit هست . کتابخانه ای که برای spi و همچنین شتاب سنج نوشته ام رو در ادامه قرار میدهم. ممنون میشم از دوستان اهل فن کسی بتونه گیر کار رو پیدا کنه.


              /*
              * spi.c
              *
              * Created on: ۸ خرداد ۱۴۰۱
              * Author: Mohammad Golmohammadi from LEEV Instruments
              */


              #include "spi.h"


              /**
              * @brief SPI GPIO Pins Config
              */
              void spi_GPIO_config(void)
              {
              //Enable PORTA Clock
              RCC->AHBENR |= (RCC_AHBENR_GPIOAEN|RCC_AHBENR_GPIOBEN);
              //Re-mapping Alternate functions all belong to AF0 as SPI1
              //PA4:CS output , PB3:SCK , PB4:MISO , PB5:MOSI
              GPIOA->MODER &= ~(GPIO_MODER_MODER4); // Reset SPI Pins MODE
              GPIOB->MODER &= ~(GPIO_MODER_MODER3|GPIO_MODER_MODER4|GPIO_MODER_M ODER5); // Reset SPI Pins MODE
              GPIOB->MODER |= ( GPIO_MODER_MODER3_1 | GPIO_MODER_MODER4_1 | GPIO_MODER_MODER5_1); //Setting SPI pins as Alternate functions
              GPIOA->MODER |= GPIO_MODER_MODER4_0; //PA4 as general output
              GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_4);//PA4 Push pull output
              GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_3 |GPIO_OTYPER_OT_4 |GPIO_OTYPER_OT_5);//PA4 Push pull output
              GPIOB->AFR[0] &= ~(GPIO_AFRL_AFRL3 |GPIO_AFRL_AFRL4 |GPIO_AFRL_AFRL5); // Alternate function AF0 Select for PA5,6,7
              //Output max medium speed
              GPIOA->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR4);
              GPIOB->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR3 |GPIO_OSPEEDR_OSPEEDR4 |GPIO_OSPEEDR_OSPEEDR5);
              GPIOA->OSPEEDR |=(GPIO_OSPEEDR_OSPEEDR4_1);
              GPIOB->OSPEEDR |= (GPIO_OSPEEDR_OSPEEDR3_1 |GPIO_OSPEEDR_OSPEEDR4_1 |GPIO_OSPEEDR_OSPEEDR5_1);
              GPIOA->BSRR = (GPIO_BSRR_BS_4); //Set PA4 High as default
              }


              /**
              * @brief SPI Peripheral configuration
              */
              void spi_config(void)
              {
              //Enable SPI Clock
              RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
              //Setting SPI Mode to mode3(CPOL=CPHA=1)
              SPI1->CR1 &= ~(SPI_CR1_CPHA | SPI_CR1_CPOL);
              SPI1->CR1 |= (SPI_CR1_CPHA | SPI_CR1_CPOL);
              //Baud rate selection for SPI = 6MHZ
              SPI1->CR1 &= ~SPI_CR1_BR;
              SPI1->CR1 |= (SPI_CR1_BR_1);
              //MSB First
              SPI1->CR1 &= ~SPI_CR1_LSBFIRST;
              //Full Duplex mode
              SPI1->CR1 &= ~SPI_CR1_RXONLY;
              //SPI in Master mode
              SPI1->CR1 |= SPI_CR1_MSTR;
              //Setting Data length to 8bits
              // SPI1->CR2 |= (SPI_CR2_DS_0 |SPI_CR2_DS_1 |SPI_CR2_DS_2 );
              SPI1->CR2 = 0U;
              //Setting Frame format
              SPI1->CR2 &= ~ SPI_CR2_FRF;
              //software SS enable
              SPI1->CR1 |= (SPI_CR1_SSI | SPI_CR1_SSM) ;
              //SPI Enable
              //Disable SPI
              SPI1->CR1 &= ~SPI_CR1_SPE;
              SPI1->CR1 |= SPI_CR1_SPE;
              // Clear All flags
              __IO uint32_t tempRd=0x00U;
              tempRd= SPI1->SR;
              (void)tempRd;
              }


              /**
              * @brief SPI Transmit
              */
              bool spi_transmit(uint8_t *pData, uint8_t len, uint32_t timeout)
              {
              //Enable SPI,if not
              SPI1->CR1 |= SPI_CR1_SPE;
              //Timeout initial Ticks
              uint8_t dataIdx=0;
              uint32_t startTick=rcc_msGetTicks();
              //while loop, transferring data, managing timeout
              while(dataIdx<len)
              {
              //TXE flag check
              if((SPI1->SR & SPI_SR_TXE)==SPI_SR_TXE)
              {
              (*(__IO uint8_t *)&SPI1->DR) = pData[dataIdx];
              dataIdx++;
              }
              else // Timeout
              {
              if((rcc_msGetTicks()-startTick)>=timeout) return false;
              }
              }
              //wait for busy flag
              while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY);
              {
              if((rcc_msGetTicks()-startTick)>=timeout) return false;
              }
              //Clear overrun -->reading DR and then SR
              if((SPI1->SR & SPI_SR_OVR)==SPI_SR_OVR)
              {
              printf("transfer Over Run Occurred\n" );
              __IO uint32_t tempRd= 0x00U;
              tempRd= SPI1->DR ;
              tempRd= SPI1->SR;
              (void)tempRd;
              }
              return 1;


              }
              /**
              * @brief SPI Receive
              */
              bool spi_receive(uint8_t *pData, uint8_t len, uint32_t timeout)
              {
              //Enable SPI,if not
              SPI1->CR1 |= SPI_CR1_SPE;
              //Timeout initial Ticks
              uint8_t dataIdx=0;
              uint32_t startTick=rcc_msGetTicks();
              uint32_t dummyTx = 1U;
              //while loop , Transmit , Receive , Timeout
              while(dataIdx<len)
              {
              //Transmit
              if(((SPI1->SR & SPI_SR_TXE)==SPI_SR_TXE) && (dummyTx))
              {
              (*(__IO uint8_t *)&SPI1->DR) = 0xFF; //Sending Dummy data before read
              dummyTx=0U;
              }
              //Receive
              if((SPI1->SR & SPI_SR_RXNE)==SPI_SR_RXNE)
              {
              (*(uint8_t *)&pData[dataIdx]) = (*(__IO uint8_t *)&SPI1->DR);
              dataIdx++;
              dummyTx=1U;
              }
              else // Timeout management
              {
              if((rcc_msGetTicks()-startTick)>=timeout) return false;
              }
              }
              //busy flag
              while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY)
              {
              if((rcc_msGetTicks()-startTick)>=timeout) return false;
              }
              //Clear overrun -->reading DR and then SR
              if((SPI1->SR & SPI_SR_OVR)==SPI_SR_OVR)
              {
              printf("receive Over Run Occurred\n" );
              __IO uint32_t tempRd= 0x00U;
              tempRd= SPI1->DR ;
              tempRd= SPI1->SR;
              (void)tempRd;
              }
              return 1;


              }




              /**
              * @brief SPI Receive
              */
              bool spi_transmitReceive(uint8_t *dataTx, uint8_t *dataRx, uint8_t len, uint32_t timeout)
              {
              //Enable SPI if not
              SPI1->CR1 |= SPI_CR1_SPE;
              //Read to DR as RXNE flag is HIGH (Rx buffer Not Empty)
              uint8_t dataIdx = 0;
              uint32_t startTick = rcc_msGetTicks();
              uint32_t dummyTx = 1U;


              while(dataIdx<len)
              {
              //Transmit dummy and lock
              if(((SPI1->SR & SPI_SR_TXE)==SPI_SR_TXE) && (dummyTx))
              {
              (*(__IO uint8_t *)&SPI1->DR) = dataTx[dataIdx];
              dummyTx = 0U;
              }


              if((SPI1->SR & SPI_SR_RXNE)==SPI_SR_RXNE) //Rx buffer NOT empty
              {
              (*(uint8_t *)&dataRx[dataIdx]) = (*(__IO uint8_t *)&SPI1->DR);
              dataIdx++;
              dummyTx = 1U; //Next is Tx
              }
              else //Manage timeout
              {
              if((rcc_msGetTicks() - startTick)>= timeout) return 0;
              }
              }
              //Wait for busy flag
              while((SPI1->SR & SPI_SR_BSY)==SPI_SR_BSY)
              {
              if((rcc_msGetTicks() - startTick)>= timeout) return 0;
              }
              //Clear overrun -->reading DR and then SR
              if((SPI1->SR & SPI_SR_OVR)==SPI_SR_OVR)
              {
              printf("receive Over Run Occurred\n" );
              __IO uint32_t tempRd= 0x00U;
              tempRd= SPI1->DR ;
              tempRd= SPI1->SR;
              (void)tempRd;
              }
              return 1;
              }






              /**
              * @brief CS Enable
              */
              void spi_cs_enable(void)
              {
              GPIOA->BSRR = (GPIO_BSRR_BR_4); // Reset PA4
              }
              /**
              * @brief CS disable
              */
              void spi_cs_disable(void)
              {
              GPIOA->BSRR = (GPIO_BSRR_BS_4); //Set PA4
              }

              /////////////////////////////////////////////////////////////////////////////////////// توابع مربوط به شتاب سنج //////////////////////////////////
              /**
              * @brief lis3dh Write
              */
              void lis3dh_write(uint8_t address , uint8_t Data)
              {
              // uint16_t i=0, usdelay=10;
              uint8_t val[2]={(address | 0x00) , Data};
              spi_cs_enable();
              asm("NOP");
              spi_transmit(val, 2, 100);
              // while(++i<usdelay) asm("NOP");
              asm("NOP");
              spi_cs_disable();


              }




              /**
              * @brief lis3dh Read
              */
              uint8_t lis3dh_read(uint8_t address)
              {
              address|=0x80;
              uint8_t Dummydata=0xFF,dataRd=0;
              spi_cs_enable();
              spi_transmit(&address, 1, 100);
              //spi_transmitReceive(&Dummydata,&dataRd,1,100);
              spi_receive(&dataRd, 1, 100);
              spi_cs_disable();
              return dataRd;
              }

              دیدگاه


                #8
                پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

                داخل این حلقه هم وقتی رجیستر who_am_i رو میخونم اول 2 مقدار اشتباه چاپ میکنه و در سومین لوپ حلقه مقدار صحیح این رجیستر رو میخونه.


                uint8_t LIS3DH_Detected;
                while((LIS3DH_Detected)!=LIS3DH_ID)
                {
                // rcc_msDelay(100);
                LIS3DH_Detected=lis3dh_read(LIS3DH_WHO_AM_I);
                printf("LIS WHOamI: %d\n" , LIS3DH_Detected);
                }

                دیدگاه


                  #9
                  پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

                  عزیز جان اول اینکه باید اینتراپتی کار کنی ، دوم اینکه dma رو باید برای این مدل برنامه ها که دیتای دائمی رد و بدل میشه فعال کنی ( حلقه با سی پی یو نمیشه )

                  اطلاعات غلط حلقه بخاطر دیلی هست ...( توی برنامه نویسی غیر از حالت اسباب بازی و آموزشی کی از دیلی استفاده میکنه ؟! از شما بعید بود )

                  مشکل اصلیت اورران شدن بافر spi هست ( بافر این سری همون spix dr هست که خوندنش بافر rx و نوشتنش بافر tx محسوب میشه ... حجم هر کدوم ۱۶ بیته اونم بخاطر فریم فرمت ۱۶ بیتی اینقدره ... شما تک رجیستر در نظر بگیرش )
                  جدیدترین ویرایش توسط Amie.s.m; ۲۰:۲۵ ۱۴۰۱/۰۳/۲۸.

                  دیدگاه


                    #10
                    پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

                    ممنون مجددا به خاطر پاسخ شما. اول اینکه delay داخل حلقه کامنت شده است. من به هیچ عنوان از تاخیر بیجا استفاده نمیکنم در برنامه و به عواقبش هم واقفم. (صرفا جهت تست گذاشته شده بوده و بعدا کامنت شده.) . استفاده از وقفه و DMA هم قطعا بهترین روش هست ولی در پروژه اخیر به دلیل یکسری محدودیت های از پیش تحمیل شده تا الان استفاده نکردم ازشون. نکته آخری هم که فرمودید درست هست، بافر SPI اورران میشد و دلیلش هم وقفه ای بود که UART در روتین اجرای SPI ایجاد میکرد که با ماسک کردنش در طی روتین spi برطرف شد. دیتافریم هم 8 بیت در نظر گرفته شده.
                    جدیدترین ویرایش توسط mo.glmdi; ۱۳:۴۳ ۱۴۰۱/۰۳/۲۹.

                    دیدگاه


                      #11
                      پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

                      اوکی ،

                      حالا سوال پیش میاد ( مرتبط با همون یکسری محدودیت ها که نمیدونم چیه )

                      شما داری با دو پروتکل سریال آسنکرون و تفاضل دیتا ریت خیلی سنگین کار میکنی ( پریفرال اس پی آی داره با باوود ریت ۶ مگابیت بر ثانیه دیتا تحویل میگیره ، شما هم که اینتراپت rxne رو استفاده نکردی مدام داری استاتوس رجیستر rxne سمت اس پی آی رو در حلقه اصلی چک میکنی .... این رو بگذار یک طرف . حالا این فلگ ست میشه میری رجیستر spi dr رو میخونی میریزی توی یک متغیر .
                      این متغیر یا مستقیم یا با مقداری پیش پردازش میره روی tx fifo یو اس آرت رایت میشه .
                      باوود ریت این طرف سقفش ۱۱۵۲۰۰ بیت برثانیه است یعنی حداقل ۶۰ برابر کندتر از اونطرفه که داره دیتا رو جمع میکنه « به فرم ارسال دیتای هگز حساب کردم ، با فرمت ascii که شما داری دیتا ارسال میکنی نرخ ارسال عملی ات خیلی کندتره » .
                      اینجا هم که داری مدام استاتوس رجیستر usart رو چک میکنی ببینی کی txfifo empty میشه .
                      کاراکتر بعدی رو بریزی روی بافر پورت سریال .

                      به نظر خودت این روش صرفنظر از منابع سیستمی که داری هدر میدی ( حلقه های مداوم برای چک یک فلگ توسط سی پی یو ) سرعت پایین پریفرالها ، باس apb که خودش یک گلوگاه دیگه است ، مصرف انرژی بیهوده ( اگر سیستم هندهلده ) و اینکه کل منابع و باسها درگیر شدن که از یک پریفرال کند دیتا بخونن روی یک پریفرال باستانی ( اینو دیگه باید با ساعت شنی سرعتش رو اندازه گرفت ) بریزن .

                      ارور هندلر و بقیه مواردی که در عمل لازم داری هم فاکتور گرفتم .

                      این وسط هم با وجودیکه تئوریک میتونستی پهنای باند اسمی حدود ۱۲۰ مگابایت بر ثانیه و پردازش 60dmips داشته باشی تهش محدود شدی به چند کیلوبایت بر ثانیه ( مجددا خوش بینانه گفتم )

                      فرض کن میخواستی با همین مدل دیتا رو از یک فلش spi یا qspi بخونی باهاش فریم بافر lcd با عمق رنگ ۱۶ بیت و رزولوشن ۴۸۰ در ۸۰۰ به شکل تعاملی درست کنی .

                      اوپراتورت فرصت داشت بره یه چایی بریزه ، بذاره خنک بشه و بخوره ... انشالله فریم اول نمایش داده شده ... طرف با hmi یه کلیدی یا بخشی از صفحه رو لمس کنه ... مجددا بره یه چای دیگه بریزه تا سیستم صفحه ، منو ، عملگر یا هر چیز بعدی رو لود کنه .

                      اینکار شبیه شکستن فندق با پتک توسط لاک پشت نیست ؟ ( با یک تبصره که همیشه هم پتکه نمیتونه فندوق رو بشکنه ! خیلی وقتا بابت همین تاخیرها سه تا پتک زده یدونه فندق له شده ، دو تاش گم شده ، چند تاش شاید بشکنه شایدم نشکنه )

                      بنظر من با هر سیستمی کار میکنی از اولش اصولی کار کن که حین توسعه مجبور به اختراع دوره ای چرخ نشی .
                      جدیدترین ویرایش توسط Amie.s.m; ۰۲:۳۵ ۱۴۰۱/۰۳/۳۱.

                      دیدگاه


                        #12
                        پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

                        در حالت کلی متوجه فرمایش شما هستم. اینکه مجبور شدم از یک دیوایس spi در حالت polling استفاده کنم ، برمیگرده به محدودیت سخت افزار و برد اشتباهی که قبلا چاپ کردم و الان مونده دستم و چاره ای جز استفاده ازش ندارم( با هزینه های کمرشکن الان چاره ای جز این ندارم. ) بحث دوم شما هم که مربوط به استفاده از وقفه ها و DMA به جهت کاهش حجم پردازش هست رو هم کاملا تایید میکنم و قطعا این کار رو انجام خواهم داد ولی با توجه به اینکه ماها جنگ زده های اتمل هستیم(به دلیل ناپدید شدن سری های XMEGA ) و پناهنده های جدید STM، این فضا یکم اولش غریبه برامون و پر از پیچ و خم های ناجور و البته جذاب. مورد آخر هم که باید عرض کنم، این هست که من از UART فقط برای debugging استفاده میکنم و طرح هم تعاملی نیست یعنی دیتایی از طرف یوزر نخواهیم داشت.
                        و در همین حدش که بتونم اطلاعات برنامه رو در جاهایی از کد مانیتور کنم فعلا کفایت میکنه هر چند راضی نمیشم به این چون در آینده نزدیک مجبور خواهم شد به قول شما چرخ اختراع کنم. الان هم مساله ای که وجود داره این هست که یک تابع printf گذاشتم در یک قسمت از کد برای دیباگینگ و داخل یک حلقه ای گذاشتم که هر ثانیه یکبار دیتا رو چاپ کنه. ولی مشکلی که هست اینه که دیتا درست چاپ نمیشه. اگر یکبار عدد درست نمایش داده میشه، دو یا سه بار عدد اشتباه و پرتی چاپ میشه. از صحت دیتای ورودی به این حلقه مطمئن هستم( روی لاجیک آنالایزر دیتای spi رو دیکد میکنم و دیتا درسته) . به نظر شما اشکال کار از کجا میتونه باشه؟

                        دیدگاه


                          #13
                          پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

                          کاملا روشن شدم و بغضی وهم آلود گلوم رو گرفت .
                          اون بخش جنگ زده های اتمل و مهاجرین اس تی به قول اون دوستمون « واقعا قلبم گرفت »

                          پیغام خصوصی ادامه میدیم سریعتر از این حالات بلغمی گذر کنی و ردای مریدان طریقت st بر تن کنی ( در طالع ات بخت بلند میبینم و امید است با مجاهدت و تزکیه نفس و مراقبه به کسوت پیر و قطب و مراد این آیین درآیی که در کتب قدیمه رهروان طریقت آرمیه را تا ۷۲ برشمرده اند که فرقه اس تیه قسم ۵۴ ام باشد ! و معجزات و کرامات فراوان برایشان ذکر شده ... )

                          دیدگاه


                            #14
                            پاسخ : مشکل با دریافت اطلاعات از SPI در میکرو STM32

                            بسیار عالی و تاثیرگذار بود، مخصوصا بخش طالع بینی و غسل تعمید آرمیه

                            دیدگاه

                            لطفا صبر کنید...
                            X