راه اندازی ماژول RM3100 با استفاده از میکروکنترلرهای STM32

0

راه اندازی ماژول RM3100 با استفاده از میکروکنترلرهای STM32

ماژول RM3100 یک سنسور مغناطیسی سه محوره از محصولات شرکت PNI است. گذرگاه ارتباطی این ماژول SPI و I2C است. لذا نیازی به مبدل های آنالوگ به دیجیتال نیست. این سنسور بهترین عملکرد را در بین سنسور مشابه خود دارد بطوریکه حداقل 10 مرتبه از لحاظه رزولوشن و 20 مرتبه نویز کمتری نسبت به بهترین سنسورهای Hall Effect دارد.  این سنسور با دقت بالایی میدان مغناطیسی را اندازه گیری می کند. لذا با استفاده از این سنسور می توان با دقت بالایی زاویه و جهت حرک را تشخیص داد.

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

ماژول RM3100 در شکل زیرنشان داده شده است. همچنین برای در شکل 2 ابعاد ادواتی که بر روی این ماژول قرار دارند به تصویر کشیده شده اند.

ماژول_RM3100
ماژول_RM3100
قطعات ماژول RM3100
قطعات ماژول RM3100

سخت افزار مورد نیاز

  • در این پروژه از بورد STM32F4DISCOVERY استفاده شده است. لازم به ذکر است روال راه­اندازی در کلیه میکروکنترلرهای STM32 مشابه یکدیگر هستند و لزومی برای خرید این بورد نیست و می­توان از بوردهای ارزان قیمت موجود در بازار استفاده کرد.
  • ماژول RM3100

نرم افزار مورد نیاز

نرم افزار STM32CubeMX یک ابزار گرافیکی برای تولید برنامه برای میکروکنترلر ARM سری cortex-M است. در این پروژه از این نرم افزار برای تولید کد استفاد شده است. همچنین نرم افزار IAR Embedded work bench برای ویرایش، کامپایل و برنامه ریزی میکروکنترلر مورد استفاده قرار گرفته شده است.

در این پروژه از واحدهای GPIO، SPI و UART استفاده شده است. از GPIO برای کنترلر پایه Chip Select ماژول RM3100 و از واحد SPI برای ارتباط با ماژول RM3100 و همچنین به منظور ارسال داده به کامپیوتر از واحد UART استفاده شده است.

پایه های ماژول

  • Vcc: پایه ولتاژ ورودی ماژول است. مقدار آن باید بین 2 تا 3.6 ولت باشد.
  • GND: پایه زمین ماژول است.
  • DRDY: هنگامی­که اندازه گیری به اتمام برسد این پایه یک می­شود.
  • CLK: پایه کلاک گذرگاه SPI است. حدکثر مقدار آن یک مگاهرتز است.
  • MISO: پایه Master In Slave Out گذرگاه SPI است.
  • MOSI: پایه Master Out Slave In گذرگاه SPI است.
  • SSN: پایه chip select گذرگاه SPI است.

نحوه اتصال

در جدول 1 نحوه اتصال ماژول به میکروکنترلر نشان داده شده است. در این پروژه از SPI3 و از پایه PA4 بعنوان Chip Select استفاده شده است. لازم به ذکر است لزومی به استفاده از SPI3 و پایه PA4 نیست و می توان از واحدهای دیگر SPI نظیر SPI1 نیز استفاده کرد.

جدول 1

میکروکنترلر STM32

ماژول RM3100

3.3V

Vcc

GND

GND

DRDY

PC11

MISO

PC12

MOSI

PA4

SSN

PC10

CLK

 

نحوه انجام تنظیمات اولیه در نرم افزار STM32CubeMX

ابتدا نوبت به تنظیم کلاک میکروکنترلر است. تنظیم کلاک با توجه به سخت افزار موردنظر انجام می­شود. بعنوان مثال کلاک سیستم می تواند داخلی و یا خارجی باشد. در این پروژه از کریستال خارجی هشت مگاهرتزی استفاده شده است. در زیر چگونگی تنظیم کلاک نشان داده شده است.

نحوه تنظیم کلاک در نرم افرار STM32CubeMX
نحوه تنظیم کلاک در نرم افرار STM32CubeMX

تنظیم واحد SPI

در تنظیم واحد SPI باید نکات زیر را در نظر گرفت:

  • حداکثر فرکانس کلاک SPI یک مگاهرتز است.
  • ارسال داده بصورت MSB first باشد.
  • مد SPI باید CPOL = CPHA = 1 یا CPOL = CPHA = 0 باشد.

در شکل 4 نحوه تنظیم واحد SPI نشان داده شده است.

چگونگی تنظیم واحد SPI
چگونگی تنظیم واحد SPI

تنظیم UART

از UART برای ارسال داده به کامپیوتر استفاده شده است. در این پروژه آموزشی برای سادگی از حالت بدون DMA و وقفه استفاده شده است. مقدار Baudrate نیز 115200 تنظیم شده است. نحوه تنظیم آن در شکل 5 نشان داده شده است.

نحوه تنظیم واحد UART در نرم افزار STM32CubeMX
نحوه تنظیم واحد UART در نرم افزار STM32CubeMX

تنظیمات GPIO

همانطور که در بخش­های قبل ذکر گردید پایه Chip select گذرگاه SPI بصورت نرم افزاری تنظیم می شود. برای این منظور تنها کافیست در قسمت Pinout View بر روی پایه مورد نظر کلیک چپ کرده و گزینه GPIO _output را انتخاب کنید. در  چگونگی تنظیم پایه   نشان داده شده است.

پس از انجام تنظیمات فوق به سربرگ Project Manager رفته و نام پروژه و محل ذخیره آن را مشخص کنید و از قسمت Toolchain/IDE گزینه EWARM V8 را انتخاب کرده و در نهایت بر روی گزینه GENERATE CODE کلیک کنید. در شکل زیر چگونگی تنظیم نشان داده شده است.

نحوه ذخیره برنامه و تولید کد با استفاده از نرم افزار STM32CubeMX
نحوه ذخیره برنامه و تولید کد با استفاده از نرم افزار STM32CubeMX

در این پروژه از نرم افزار IAR استفاده شده است ولی می­توان از ابزارهایی نظیر Keil و … نیز استفاده نمود.

توسعه نرم افزار

برای خواندن داده از ماژول RM3100 دو روش وجود دارد. روش اول استفاده از مکانیزم interrupt و یا وقفه و روش دوم polling و یا سرکشی است. در روش وقفه از پایه DRDY برای ایجاد وقفه استفاده می­شود. این پایه هنگامی­که داده سنسور آماده باشد یک می­شود و بعد از خواندن داده مجددا صفر می­شود. در روش دوم داده سنسور بطور مداوم خوانده می­شود و در صورتی­که بیت DRDY در رجیستر STATUS یک باشد داده­ معتبر خواهد بود.  در این پروژه برای سادگی از روش polling استفاده شده است.

بطور خلاصه برای استفاده از ماژول باید گام­های زیر طی شود:

  • تنظیم مناسب Cycle time: Cycle time تعداد کلاک­های لازم برای اندازه گیری را مشخص می­کند که برای هر سنسور می­تواند متفاوت باشد. هر چقدر مقدار Cycle Time بزرگتر باشد رزولوشن و بهره آن بالاتر می­رود و هر چقدر کمتر باشد مدت زمان اندازه گیری کمتر خواهد بود. 
  • برای تنظیم مقدار Cycle Time باید رجیسترهای CCX، CCY و CCZ ست شوند. طول این رجیسترها 16 بیت می­باشد لذا می­تواند مقدار آن­ها می­توانند بین 0 تا 65535 باشد. در کد زیر چونگی تنظیم این نشان داده شده است:

void setCycleTime(uint16_t un16xData, uint16_t un16yData, uint8_t un16zData)
{
    uint8_t aun8TXData[10];
    aun8TXData[0] = RM_WRITE_COMMAND | RM_CCX0_REG;                 /*      send write command to address starting from CCX register      */
    aun8TXData[1] = ((uint8_t)un16xData & 0x00FF);                  /*      calculate least significant byte of X axis data               */
    aun8TXData[2] = ((uint8_t)(un16xData >> 8U) & 0x00FF);          /*      calculate most significant byte of X axis data                */
    aun8TXData[3] = ((uint8_t)un16yData & 0x00FF);                  /*      calculate least significant byte of Y axis data               */
    aun8TXData[4] = ((uint8_t)(un16yData >> 8U) & 0x00FF);          /*      calculate most significant byte of Y axis data                */
    aun8TXData[5] = ((uint8_t)un16zData & 0x00FF);                  /*      calculate least significant byte of Z axis data               */
    aun8TXData[6] = ((uint8_t)(un16zData >> 8U) & 0x00FF);          /*      calculate most significant byte of Z axis data                */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);           /*      set chip select pin LOW                                       */
    HAL_SPI_Transmit(&hspi3, aun8TXData,2, 100);                    /*      start SPI communication                                       */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);             /*      set chip select pin HIGH                                      */
}
 
  • گام بعدی خواندن داده از سنسور است. برای خواندن داده ابتدا رجیستر CMM را تنظیم نمود. فیلدهای این رجیستر در شکل 8 نشان داده شده است. با یک کردن بیت START سنسور بصورت مداوم نمونه برداری می­کند. بیت های CMX، CMY و CMZ نیز مشخص می­کنند که در کدام راستا نمونه برداری انجام شود. با یک کردن هر کدام از این بیت­ها مکانیزم نمونه برداری در راستای متناظر با آن فعال می­شود. بیت DRDM نیز رفتار پایه DRDY را مشخص می­کند. در صورتی­که این بیت یک باشد، بعد از هر بار که نمونه برداری به اتمام رسید پایه DRDY یک می­شود.
  • در صورتیکه بخواهیم از هر سه محور بخوانیم باید عدد 0x79 نوشته شود.

    بعد از تنظیم رجیستر CMM می­توان مقادیر سنسورها را خواند. بایت اول دریافتی همواره رجیستر STATUS است. بیت با ارزش این رجیستر مقدار DRDY است. در صورتیکه این بیت یک باشد مقدار خوانده شده معتبر است.

ارتباط SPI
ارتباط SPI

در کد زیر نحوه تنظیم رجیستر CMM نشان داده شده است.

void setCMMRegTOStart(void)
{
  uint8_t tempTXData[2];
  tempTXData[0] = RM_CMM_REG | RM_WRITE_COMMAND;
  tempTXData[1] = 0x79;

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi3, tempTXData, 2, 100);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
 

در کد زیر نیز نحوه خواندن داده از سنسور نشان داده شده است.

uint8_t readSensorData(uint8_t* aun8readData)
{
  int i;
  uint8_t aun8TXTempData[10];
  aun8TXTempData[0] = RM_READ_COMMAND | RM_MX0_REG;
  for (i = 1;i<10;i++)
    aun8TXTempData[i] = 0xff;   /* these are not important*/
  
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
  HAL_SPI_TransmitReceive(&hspi3, aun8TXTempData, aun8readData, 10, 100);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  return 0;
}
 

در نهایت تابع main بصورت کد زیر است.

int main(void)
{
  /* USER CODE BEGIN 1 */
  uint8_t aun8SPITXData[10];
  uint8_t aun8SPIRXData[10];
  uint32_t un32XData;
  uint32_t un32YData;
  uint32_t un32ZData;
  char strDataToPC[100];
  volatile unsigned int i=0U;
  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI3_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  
  /*    test the module connection      */
  if (testConnection() == -1)            /*  RM3100 module is not correctly connected to MCU!  */
  {
    while(1);
  }
  
  /* set cyle time of each axis. here all of them are set to 0x64 (100)  */
  setCycleTime(100, 100, 100);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /*  set CMM reg to do measurement continously  */
    setCMMRegTOStart(); 
    /*  read measured data form sensor  */
    readSensorData(aun8SPIRXData);
    /*  check the validity of measured data     */
    if (aun8SPIRXData[0] & RM_STATUS_MASK == RM_STATUS_MASK)
    {
      /* convert data to 32-bit format instead of byte array format        */
      un32XData = (uint32_t)aun8SPIRXData[3] + ((uint32_t)aun8SPIRXData[2] <<8) + ((uint32_t)aun8SPIRXData[1] << 16);
      un32YData = (uint32_t)aun8SPIRXData[6] + ((uint32_t)aun8SPIRXData[5] <<8) + ((uint32_t)aun8SPIRXData[4] << 16);
      un32ZData = (uint32_t)aun8SPIRXData[9] + ((uint32_t)aun8SPIRXData[8] <<8) + ((uint32_t)aun8SPIRXData[7] << 16);
      
      /* send data to PC        */
      sprintf(strDataToPC, "X axis = %8d\n", un32XData);
      HAL_UART_Transmit(&huart1, strDataToPC, 20, 100);
      
      sprintf(strDataToPC, "Y axis = %8d\n", un32YData);
      HAL_UART_Transmit(&huart1, strDataToPC, 20, 100);
      
      sprintf(strDataToPC, "Z axis = %8d\n", un32ZData);
      HAL_UART_Transmit(&huart1, strDataToPC, 20, 100);      
      
    }
    /*  dummy loop in order to wait     */
    for (i=0;i<1000000;i++);    
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 

لازم به ذکر است که پروژه  STM32CubeMX و IAR ضمیمه گزارش شده اند.

Choose your Reaction!
دیدگاه خود را بنویسید

آدرس ایمیل شما منتشر نخواهد شد.

redronic.com