센서 > MPU6050 레지스터 PC에서 엑세스 하기

TODAY265 TOTAL2,276,487
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 센서 | 자이로센서 | MPU6050 레지스터 PC에서 엑세스 하기

페이지 정보

작성자 키트 작성일2017-08-21 16:23 조회1,497회 댓글0건

첨부파일

본문

//
#include <mega128.h>
#include <delay.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//

#define TWINT 0x80
#define TWEA  0x40
#define TWSTA 0x20
#define TWSTO 0x10
#define TWWC  0x08
#define TWEN  0x04
#define TWIE  0x01
//
// TW_MT_xxx - master transmitter
// TW_MR_xxx - master receiver
// TW_ST_xxx - slave transmitter
// TW_SR_xxx - slave receiver
//
#define  TW_START                 0x08
#define  TW_REP_START             0x10
#define  TW_MT_SLA_ACK            0x18
#define  TW_MT_SLA_NACK           0x20
#define  TW_MT_DATA_ACK           0x28
#define  TW_MT_DATA_NACK          0x30
#define  TW_MT_ARB_LOST           0x38
#define  TW_MR_ARB_LOST           0x38
#define  TW_MR_SLA_ACK            0x40
#define  TW_MR_SLA_NACK           0x48
#define  TW_MR_DATA_ACK           0x50
#define  TW_MR_DATA_NACK          0x58
#define  TW_ST_SLA_ACK            0xA8
#define  TW_ST_ARB_LOST_SLA_ACK   0xB0
#define  TW_ST_DATA_ACK           0xB8
#define  TW_ST_DATA_NACK          0xC0
#define  TW_ST_LAST_DATA          0xC8
#define  TW_SR_SLA_ACK            0x60
#define  TW_SR_ARB_LOST_SLA_ACK   0x68
#define  TW_SR_GCALL_ACK          0x70
#define  TW_SR_ARB_LOST_GCALL_ACK 0x78
#define  TW_SR_DATA_ACK           0x80
#define  TW_SR_DATA_NACK          0x88
#define  TW_SR_GCALL_DATA_ACK     0x90
#define  TW_SR_GCALL_DATA_NACK    0x98
#define  TW_SR_STOP               0xA0
#define  TW_NO_INFO               0xF8
#define  TW_BUS_ERROR             0x00
//
#define MPU6050_RD_ADD   0xD1
#define MPU6050_WR_ADD   0xD0
//
void TWI_WRITE(char add,char d){
    TWCR=TWINT|TWSTA|TWEN;       while(!((TWCR&TWINT)&&(TWSR&TW_START)));     //START Complete ?
    TWDR=0xD0;  TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_SLA_ACK)));//Slave Address Write Mode Complete?
    TWDR=add;   TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK)));//Address Complete?    
    TWDR=d;     TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK)));//Data Write Complete?  
    TWCR=TWINT|TWSTO|TWEN;    //stop
    //delay_ms(5);
}
//
/*
char TWI_READ(char add){
    char d;
    TWCR=TWINT|TWSTA|TWEN;       while(!((TWCR&TWINT)&&(TWSR&TW_START)));      //START Complete ?
    TWDR=0xD0;  TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_SLA_ACK))); //Slave Address Write Mode Complete?
    TWDR=add;   TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK)));//Address Complete?    
    TWCR=TWINT|TWSTA|TWEN;       while(!((TWCR&TWINT)&&(TWSR&TW_REP_START)));  //START Complete ?
    TWDR=0xD1;  TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_SLA_ACK))); //Slave Address read Mode Complete?
    TWCR=TWINT|TWEN;             while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_NACK)));//Data Read Complete?
    d=TWDR;
    TWCR=TWINT|TWSTO|TWEN;    //stop
    return d;
}

//
void TWI_Page_WRITE(char add){
    unsigned int i;
    TWCR=TWINT|TWSTA|TWEN;      while(!((TWCR&TWINT)&&(TWSR&TW_START)));      //START Complete ?
    TWDR=0xD0; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_SLA_ACK))); //Slave Address Write Mode Complete?
    TWDR=add;  TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK)));//Address Complete?    
    for(i=0;i<64;i++){ TWDR=wr_buf[i]; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); }
    TWCR=TWINT|TWSTO|TWEN;    //stop
    delay_ms(5);
}
*/
//
char rd_buf[128];
//
void TWI_Seq_READ(void){
    char i;
    TWCR=TWINT|TWSTA|TWEN;       while(!((TWCR&TWINT)&&(TWSR&TW_START)));      //START Complete ?
    TWDR=0xD0;  TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_SLA_ACK))); //Slave Address Write Mode Complete?
    TWDR=0;     TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK)));//Address Complete?
    TWCR=TWINT|TWSTA|TWEN;       while(!((TWCR&TWINT)&&(TWSR&TW_REP_START)));  //START Complete ?
    TWDR=0xD1;  TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_SLA_ACK))); //Slave Address read Mode Complete?
    for(i=0;i<117;i++){
        TWCR=TWINT|TWEA|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_ACK))); //Data Read Complete?
        rd_buf[i]=TWDR;
    }
    TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_NACK))); //Data Read Complete?
    rd_buf[i]=TWDR;
    TWCR=TWINT|TWSTO|TWEN;    //stop
}
//
void TX1_CH(char ch){ while(!(UCSR1A&0x20)); UDR1=ch; } // 송신 1바이트
//void TX1_STR(char *str){ while(*str)TX1_CH(*str++);   } // 송신 문자열
//
char tx_add,tx_data,rx_cnt=0,rx_buf[20];
bit  rd_flag=0,wr_flag=0;
//
interrupt [USART1_RXC] void usart1_rx_isr(void){                  // 수신 인터럽트
    char ch;
    ch=UDR1;
    if(ch==2){ rx_cnt=0; rx_buf[0]=0; }
    else if(ch==3){
        if     ((rx_cnt==1)&&(rx_buf[0]=='R'))rd_flag=1;
        else if((rx_cnt==5)&&(rx_buf[0]=='W')){
            tx_add =((rx_buf[1]&0x0F)<<4)|(rx_buf[2]&0x0F);
            tx_data=((rx_buf[3]&0x0F)<<4)|(rx_buf[4]&0x0F);
            wr_flag=1;
        }
        rx_cnt=0;
    }
    else{
        if(rx_cnt<10)rx_buf[rx_cnt++]=ch;
    }
}
//
void main(void){
    char i;
    //
    UCSR1B=0x98; UBRR1L=8; //115200 @16MHz
    TWBR=18; TWSR=0;       //400 kHz i2c_init();
    SREG=0x80;
    while(1){
        if(wr_flag){ wr_flag=0; TWI_WRITE(tx_add,tx_data); }
        //
        if(rd_flag){ rd_flag=0;
            TWI_Seq_READ();
            TX1_CH(2);
            for(i=0;i<118;i++){ TX1_CH((rd_buf[i]>>4)|0x30); TX1_CH((rd_buf[i]&0x0F)|0x30); }
            TX1_CH(3);
        }
    }
}

//


24C256 I2C 강좌중 뒷부분 TWI 예제로 MPU6050을 엑세스 해봤습니다.

PC에서 값을 보기 편하도록 한 것이라서 AVR 소스코드는 간단합니다.

PC에서 시키는대로 read, write만 한 것이죠

(PC 프로그램도 232통신 부분은 AVR처럼 간단합니다.)

 

PC프로그램은 첨부 파일에 올려둡니다.^^

//

MPU6050_-_33.PNG?type=w740

사용방법은 포트번호를 선택한 후에 Open 버튼을 클릭해서 포트를 열면 됩니다.

//

MPU6050_-_34.PNG?type=w740

 

포트가 정상적으로 열리면 상단의 판넬 칼라가 하늘색으로 바뀝니다.

수동읽기 버튼을 클릭하면 MPU6050의 레지스터를 모두 읽어옵니다.

//

4.34 Register 117 – Who Am I ( Type: Read Only )

0x75번지의 WHO_AM_I 레지스터는 부팅 초기에는 0x68이 들어있는 것을 볼 수 있습니다.

동작중에는 값이 변합니다.

//

4.30 Register 107 – Power Management 1 (Type: Read/Write)

0x6B번지의 PWR_MGMT_1 비트6이 1로 되어 있어서 슬립모드 상태입니다.

Write버튼을 클릭하면 적색 글씨의 01(16진수임) 데이터가 레지스터에 써지고, 이후로는 슬립모드가 해제되어서 동작을 합니다.
//

자동읽기를 설정하거나 혹은 수동읽기 버튼을 클릭하면

118(0~117)개의 레지스터 데이터를 상위 하위로 나누어서 전송하므로 236개의 데이터가 전송되고

(적색글씨는 232통신의 기초 게시글을 읽어본 분이라면 이해 할 것입니다.)

Stx,Etx 두개가 더해져서 모두 238개가 PC로 전달 됩니다.

115200 보레이트라고 해도 데이터량이 많아서 21.4ms 정도가 걸립니다.

MPU6050에서 118개의 레지스터를 읽는 시간은 4ms 조금 더 걸리는 정도입니다.

//

MPU6050_-_35.PNG?type=w740

자동읽기는 최소 100ms에서 100ms 단위로 1000ms까지 변경 할 수 있습니다.

댓글 0

조회수 1,497

등록된 댓글이 없습니다.

센서HOME > 센서 > 자이로센서 목록

게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기