پروژه ژایروسکوپ CRM200 با استفاده از میکروکنترلر ATMEGA

 پروژه ژایروسکوپ CRM200 با استفاده از میکروکنترلر  ATMEGA

راهنمای راه اندازی ژایروسکوپ(سنسور سرعت زاویه ای) CRM200 با استفاده از برد آموزشی پلاریس Polaris
هدف از انجام این پروژه اندازه گیری سرعت زاویه ای با دقت بالا توسط ژایروسکوپ دقیق cRM200  می باشد.

با فراگیری این آموزش شما قادر خواهید بود سنسورهای مشابه که خروجی آنها SPI میباشد را به همبن روش راه اندازی نمایید.

ژایروسکوپ CRM200
ژایروسکوپ CRM200

مقدمه‌ای بر سنسور CRM200

حسگر تک محوره CRM200 توسط تکنولوژی MEMS ساخته شده است و قادر به اندازه‌گیری سرعت زاویه‌ای تا حداکثر نرخ 1000± درجه بر ثانیه می‌باشد. حسگر در دو حالت آنالوگ یا دیجیتال قادر به ارسال اطلاعات است. در حالت آنالوگ، سیگنال خروجی، سیگنالی خطی و متناسب با سرعت زاویه‌ای و در حالت دیجیتال خروجی طبق پروتکل SPI و داده‌های مربوط به ژایروسکوپ، 16 بیتی می‌باشند. در جدول زیر مشخصات سنسور آورده شده‌است.

Device Type Gyro No. of axes 1
Angular range [±°/s] 75, 150, 300, 900 Sensitivity 12, 6, 3, 1 mV/°/s
Measuring range 75, 150, 300, 900 °/s Bias over temperature ± 1.5 °/s
In-Band quiescent noise 0.18 °/s rms Bandwidth 160 hz
Bias instability 24 °/hr Supplier Silicon Sensing
Supply voltage [VDC] 2.7 – 3.6

راه‌اندازی CRM200 توسط برد AVR WIZZARD

راه‌اندازی CRM200 توسط برد AVR WIZZARD
راه‌اندازی CRM200 توسط برد AVR WIZZARD

 

هدف: در این پروژه سنسور ژایروسکوپ CRM200 در حالت دیجیتال توسط برد AVR WIZZARD راه‌اندازی شده و داده‌های دریافتی از سنسور هم بر روی LCD نمایش داده‌ می‌شود و هم از طریق پورت سریال ارسال می‌شود.

نیازمندی‌ها:

  • برد AVR WIZZARD
  • ماژول FTDI232 (USB to Serial)
  • ماژول CRM200
  • آداپتور تغذیه
  • سیم جامپر

برای راه‌اندازی حسگر در حالت دیجیتال، جامپر Mode  را به Vdd متصل کرده و دو جامپر SEL0 و SEL1  را قطع نمایید. طبق شکل 1 پایه‌های حسگر را به میکرو متصل نمایید.

اتصال پایه سنسور crm200به میکروکنترلر
اتصال پایه سنسور crm200به میکروکنترلر

کدنویسی:

CRM200 از طریق درگاه SPI ارتباط برقرار می‌کند. برای نوشتن کد مربوطه، ابتدا در CodeVision پروژه جدید تعریف کرده و درگاه‌های SPI و UART آن را راه اندازی می‌کنیم. همچنین تنظیمات مربوط به LCD  را انجام می‌دهیم.

ایجاد پروژه در CodeVision

برای ایجاد پروژه جدید، از شاخه File، گزینه New و سپس Project را انتخاب کنید.

پیغام مربوط به code wizard

سپس پنجره دیگری نشان داده خواهد شد؛ گزینه اول را انتخاب کرده و Ok را بزنید.

پیغام مربوط به code wizardانتخاب خانواده avr

پس از تایید این گزینه، وارد صفحه جدیدی خواهید شد. در این صفحه تنظیمات مربوط به پورت‌های ورودی و خروجی، LCD و SPI را انجام خواهیم داد. میکرو کنترلر استفاده شده ATMEGA32A می‌باشد.

تنظیمات مربوط به پورت‌های ورودی و خروجیLCD و SPI

پایه CS ماژول به PORTB.4 متصل است. در قسمت PORT، این پورت را به عنوان خروجی تعریف می کنیم.

PORTB.4 تعریف به عنوان خروجی

سپس تنظیمات مربوط به LCD را انجام می‌دهیم.

نظیمات مربوط به LCD

همانطور که روی برد مشخص شده است، خطوط داده LCD به PORTA و خطوط فرمان به PORTB متصل هستند.

در ادامه SPI را فعال سازی می‌کنیم.

SPI فعال سازی

حال تنظیمات مربوط به UART را انجام می‌دهیم

ذخیره سازی نهایی

پس از ذخیره سازی، وارد پنجره کدنویسی خواهیم شد. در این پنجره قسمت‌های مشخص شده اند که کاربر کد خود را در آن جا وارد کند.

کد برنامه

/*******************************************************
This program was created by the CodeWizardAVR V3.33 
Automatic Program Generator
© Copyright 1998-2018 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project : CRM200
Version : 1.0
Date    : 06/25/2019
Author  : 
Company : KEI_CAN
Comments: 
Chip type               : ATmega32A
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*******************************************************/
#include <mega32a.h>
// SPI functions
#include <spi.h>
// Alphanumeric LCD functions
#include <alcd.h>
// Declare your global variables here
// Standard Input/Output functions
#include <stdio.h>
#include <stdint.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void uart_print(char*);
void uart_putchar(char); 
uint8_t * spi_read(uint8_t,uint8_t) ;
uint8_t read_data[10];
void main(void)
{
// Declare your local variables here
uint8_t *address,checksum,gyro_ch[10],temp_ch[10];
int gyro,temperature;
float temp;
// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);
// Port B initialization
// Function: Bit7=Out Bit6=In Bit5=Out Bit4=Out Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(1<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0 Bit6=T Bit5=0 Bit4=0 Bit3=T Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x33;
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 500.000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (1<<SPR0);
SPSR=(0<<SPI2X);
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTA Bit 4
// D5 - PORTA Bit 5
// D6 - PORTA Bit 6
// D7 - PORTA Bit 7
// Characters/line: 8
lcd_init(16);
lcd_clear();
lcd_gotoxy(6,0); //row 0 column 6
lcd_printf("KEI");
lcd_gotoxy(6,1); //row 1 column 6
lcd_printf("CAN");

delay_ms(1500);

while (1)
      {
// Place your code here  
       delay_ms(10); 
       address=spi_read(0x38,6);//Command Byte (Byte 1)  0x38: 75°/s Rate Range
       if(*(address)==0x03)//check status data (Byte 1)
       {
                gyro=  (int)(*(address+1))<<8 |(*(address+2));// (Byte 2) & (Byte 3)
                gyro=gyro/96;//scale factor for 75°/s
                temperature=  (int)(*(address+3))<<8 |*(address+4);// (Byte 4) & (Byte 5) 
                temperature-=531;//from datasheet
                temp=(float)temperature/2.75; //scale factor
                checksum=*(address+5);//(Byte 6)  
                ltoa(gyro,gyro_ch);   
//ltoa() function in C language converts long data type to string data type
                ftoa(temp,2,temp_ch);
//convert a floating point number to a character array  to display on LCD   
                ltoa(gyro,gyro_ch); 
                lcd_clear();
                lcd_gotoxy(0,0); //row 0 column 0
                lcd_puts(gyro_ch);
                lcd_gotoxy(0,1); //row 1 column 0   
                lcd_puts("Temp: ");
                lcd_puts(temp_ch);
                lcd_puts(" OC");
                uart_print(". Gyro= ");                 
                uart_print(gyro_ch); // sending data by UART
                uart_print(". Temp=  ");                            
                uart_print(temp_ch); // sending data by UART
       }    
      }
}
void uart_putchar(char z) 
{
        UDR = z; 
        while ( !( UCSRA & (1<<UDRE)) ) ; //Wait for transmission complete
}
void uart_print(char  *st)
{
	int stl, i;
	stl = strlen(st);
	for (i=0; i<stl; i++)
	uart_putchar(*st++);
}

uint8_t * spi_read(uint8_t data,uint8_t size)
{
 uint8_t i,chsum=~data;
 uint8_t buff[]={0,0x00,0x00,0x00,0x00,0}; 
 buff[0]=data;buff[5]=chsum;//refer to datasheet
 PORTB.4=0;//chip select pin  
 for (i=0;i<80;i++);//delay (important!)
 for(i=0;i<size;++i)
 { 
 SPDR=buff[i];//status register address
 while(!(SPSR & (1<<SPIF))); //Wait for transmission complete 
 read_data[i]=SPDR; 
 }  
  for (i=0;i<20;i++);//delay
 PORTB.4=1; 
 return  read_data;
}

نتیجه عملی

نتیجه عملی راه اندازی ژایروسکوپ CRM200 توسط برد آموزشی پلاریس Polaris

نتیجه عملی راه اندازی ژایروسکوپ CRM200 توسط برد آموزشی پلاریس Polaris

نکته: خروجی ژایروسکوپ به صورت 16 بیتی است، اما بیت 15 حاوی داده‌ای نمی‌باشد و بیت 16 نیز بیت علامت می‌باشد.

zahra_ahmadi

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

شش + 12 =