Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы

Как считать данные с гироскопа MPU-6050?

Непрочитано 16.05.2016, 01:01  
Kopranych
Частый гость
 
Регистрация: 16.05.2016
Адрес: Москва
Сообщений: 35
Сказал спасибо: 6
Сказали Спасибо 1 раз в 1 сообщении
Kopranych на пути к лучшему
По умолчанию Как считать данные с гироскопа MPU-6050?

Здравствуйте! Имею микроконтроллер мега16 и модуль гироскоп MPU-6050. Пытаюсь с ним пообщаться по шине TWI.
Общение построил по протоколу из даташита и вроде бы модуль отсылает мне бит подтверждения ACK но как дело доходит до чтения данных из регистра TWDR там одни нули! Подскажите что неправильно.
Вот протокол общения:

unsigned char MPU_I2C_R(unsigned char w,unsigned char x, unsigned char r)
{
char a;
I2C_start();//отправляем условие СТАРТ
I2C_tranciv_byte(w);//отправляем адрес модуля на запись
I2C_tranciv_byte(x);//отправляем адрес регистра откуда будем читать данные
I2C_start();//отправляем повторный СТАРТ
I2C_tranciv_byte(r);//отправляем адрес модуля на чтение
a = I2C_receiver_last_byte();//читаем данные из регистра
I2C_stop();//отправляем условие СТОП
return a;
}
Вот функция чтения чтения данных
unsigned char I2C_receiver_last_byte()
{

TWCR = (1‹‹TWINT)|(1‹‹TWEN);// включили прием данных ‹--вот после этого в отладке регистр TWDR обнуляется
while(!(TWCR&(1‹‹TWINT))); //ждем установку бита TWIN

return TWDR;
}
Реклама:
Kopranych вне форума  
Непрочитано 16.05.2016, 19:15  
-Alan-
Прописка
 
Аватар для -Alan-
 
Регистрация: 05.12.2008
Адрес: Россия, Омск
Сообщений: 145
Сказал спасибо: 39
Сказали Спасибо 29 раз(а) в 22 сообщении(ях)
-Alan- на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Шина подтянута к питанию?
-Alan- вне форума  
Непрочитано 16.05.2016, 20:20  
Kopranych
Частый гость
 
Регистрация: 16.05.2016
Адрес: Москва
Сообщений: 35
Сказал спасибо: 6
Сказали Спасибо 1 раз в 1 сообщении
Kopranych на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Да подтянута. На самом модуле через два резистора на 4.7К
Kopranych вне форума  
Непрочитано 16.05.2016, 21:41  
Signalshik2
Вид на жительство
 
Аватар для Signalshik2
 
Регистрация: 11.08.2015
Сообщений: 409
Сказал спасибо: 17
Сказали Спасибо 37 раз(а) в 28 сообщении(ях)
Signalshik2 на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Попробуйте использовать прерывание от TWI. И уже в прерывании обрабатывать байт, который пришел от гироскопа.
Signalshik2 вне форума  
Непрочитано 16.05.2016, 22:02  
Signalshik2
Вид на жительство
 
Аватар для Signalshik2
 
Регистрация: 11.08.2015
Сообщений: 409
Сказал спасибо: 17
Сказали Спасибо 37 раз(а) в 28 сообщении(ях)
Signalshik2 на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Кстати, как вариант, может Вы подключили микроконтроллер к AUX-входу гироскопа?
Signalshik2 вне форума  
Непрочитано 20.05.2016, 12:59  
-Alan-
Прописка
 
Аватар для -Alan-
 
Регистрация: 05.12.2008
Адрес: Россия, Омск
Сообщений: 145
Сказал спасибо: 39
Сказали Спасибо 29 раз(а) в 22 сообщении(ях)
-Alan- на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Для начала - проверьте, читаются ли вообще данные, в частности, регистры калибровки.
Так же, рекомендую обратиться к документу: MPU6050 register map.
Если интересен код - вот мой, работает на ATMega1284p
Данные выводятся в консоль.
Пример:
Accel: X: -3024 Y: -1164 Z: 17076 Gyro: X: -434 Y: 123 Z: -19 Temperature: 30
Да, чип греется.
Нажмите, чтобы открыть спойлер

Код:
#define F_CPU 8000000UL

#include ‹avr/io.h›
#include ‹util/delay.h›
#include ‹avr/pgmspace.h›
#include ‹util/twi.h›
#include ‹avr/interrupt.h›
#include ‹stdlib.h›

#define TWBR_val	0x40
#define UART_BAUD_RATE		9600
#define BaudRate (F_CPU/UART_BAUD_RATE)/16-1;
// 11059200/115200 = 96|16 = 6-1 = 5.

volatile uint8_t tx_buffer[256];
volatile uint16_t txwrptr, txsendptr;

ISR (USART0_RX_vect) {
	
};
ISR (USART0_TX_vect) {
};
ISR (USART0_UDRE_vect) {
	if (txsendptr ›= sizeof(tx_buffer))
		txsendptr = 0;
	if (txsendptr != txwrptr)
	{
		UDR0 = tx_buffer[txsendptr];
		txsendptr++;
	} else {
		UCSR0B &= ~(1‹‹UDRIE0);
	};
};

void console_put(const char *s) {
	while (*s)						// Пока по указателю на ноль (нуль-терминатор)
	{
		tx_buffer[txwrptr] = *s;			// Записываем в буфер
		txwrptr++;					// Двигаем указатель
		if (txwrptr ›= sizeof(tx_buffer))		// Если дослигли конца - возвращаемся в начало
			txwrptr = 0;
		s++;						// Двигаем указатель строки.
		if (txwrptr == txsendptr)			// Если указатель записи буфера "наехал" на указатель передачи
		{
			UCSR0B|=(1‹‹UDRIE0);			// Разрешаем передачу
			_delay_us(100);				// Ждём.
		};
	};
	UCSR0B|=(1‹‹UDRIE0);					// Разрешаем передачу
};
void console_put_hex(uint8_t s) {
	char rs[3];
	if ((s ›› 4) › 9)
	{
		rs[0] = ('7' + (s ›› 4));
	} else {
		rs[0] = ('0' + (s ›› 4));
	};
	if ((s & 0x0F) › 9) {
		rs[1] = ('7' + (s & 0x0F));
	} else {
		rs[1] = ('0' + (s & 0x0F));
	};
	rs[2] = 0;
	console_put(rs);
};
void console_put_BYTE(uint8_t byte, uint8_t isSigned) {
	char t[4];
	if (isSigned)
	{
		itoa(byte, t, 10);
	} else {
		utoa(byte, t, 10);
	};
	console_put(t);
};
void console_put_WORD(uint16_t word, uint8_t isSigned) {
	char t[8];
	if (isSigned)
	{
		itoa(word, t, 10);
	} else {
		utoa(word, t, 10);
	};
	console_put(t);
};
void console_put_DWORD(uint32_t dword, uint8_t isSigned) {
	char t[14];
	if (isSigned)
	{
		ltoa(dword, t, 10);
	} else {
		ultoa(dword, t, 10);
	};
	console_put(t);
};
void console_init(void) {
	uint16_t i;
	for (i=0;i‹sizeof(tx_buffer);i++)
	{
		tx_buffer[i] = 0;
	};
// 	// Обнуляем переменные
// 	rxlen = 0;
	txwrptr = 0;
	txsendptr = 0;
	// Настраиваем переферию.
	PRR0 &= ~(1‹‹PRUSART0);			// Enables USART0
	UBRR0 = BaudRate;			// Baud rate
	UCSR0A = 0;				// USART Status and control register
	UCSR0B = (1‹‹RXCIE0)|(1‹‹RXEN0)|(1‹‹TXEN0);
	// Transmitter Enabled, Receiver Enabled, RX_Complete_Int Enabled.
	UCSR0C = (1‹‹UCSZ01)|(1‹‹UCSZ00);	// 8 bit, no parity, 1 stop bit.
};
void I2C_init(void){
	PRR0 &= ~(1‹‹PRTWI);			// Разрешаем работу интерфейса TWI
	TWBR = TWBR_val;
};
uint8_t I2C_start(uint8_t address){
	unsigned int RetryCount = 0;			// Счётчик попыток.
	TWCR = 0;					// reset TWI control register
	TWCR = (1‹‹TWINT) | (1‹‹TWSTA) | (1‹‹TWEN);	// transmit START condition
	// wait for end of transmission
	while( !(TWCR & (1‹‹TWINT)) )			// Ждём, пока переферия не сбросит бит занятости.
	{
		RetryCount++;				// Считаем таймер...
		if (RetryCount › 20000) break;		// Если ждём слишком долго - выход.
	};
	// check if the start condition was successfully transmitted
	if((TWSR & 0xF8) != TW_START){ return 1; }
	// load slave address into data register
	TWDR = address;
	// start transmission of address
	TWCR = (1‹‹TWINT) | (1‹‹TWEN);
	// wait for end of transmission
	while( !(TWCR & (1‹‹TWINT)) )
	{
		RetryCount++;
		if (RetryCount › 20000) break;
	};
	// check if the device has acknowledged the READ / WRITE mode
	uint8_t twst = TW_STATUS & 0xF8;
	if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
	return 0;
};
uint8_t I2C_write(uint8_t data){
	unsigned int RetryCount = 0;
	// load data into data register
	TWDR = data;
	// start transmission of data
	TWCR = (1‹‹TWINT) | (1‹‹TWEN);
	// wait for end of transmission
	while( !(TWCR & (1‹‹TWINT)) )
	{
		RetryCount++;
		if (RetryCount › 60000) break;
	};
	if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
	return 0;
};
uint8_t I2C_read_ack(void){
	unsigned int RetryCount = 0;
	// start TWI module and acknowledge data after reception
	TWCR = (1‹‹TWINT) | (1‹‹TWEN) | (1‹‹TWEA);
	// wait for end of transmission
	while( !(TWCR & (1‹‹TWINT)) )
	{
		RetryCount++;
		if (RetryCount › 60000) break;
	};
	// return received data from TWDR
	return TWDR;
};
uint8_t I2C_read_nack(void){
	unsigned int RetryCount = 0;
	// start receiving without acknowledging reception
	TWCR = (1‹‹TWINT) | (1‹‹TWEN);
	// wait for end of transmission
	while( !(TWCR & (1‹‹TWINT)) )
	{
		RetryCount++;
		if (RetryCount › 60000) break;
	};
	return TWDR;				// return received data from TWDR
};
void I2C_stop(void){
	// transmit STOP condition
	TWCR = (1‹‹TWINT) | (1‹‹TWEN) | (1‹‹TWSTO);
	_delay_us(5);				// Без этой паузы не получается передать STOP. И в отладке всё становится грустно.
						// Самое смешное, что в железе работает нормально.
	TWCR = 0;
};
uint8_t I2C_WriteSpecifiedByte(unsigned char addr, unsigned char data) {
	uint8_t status;				// Запоминаем статус.
	I2C_start(0xD0);			// START + SLA + WR
	status = (TWSR & 0xF8);			// Читаем статус, запоминаем.
	I2C_write(addr);			// ADDR
	I2C_write(data);			// Data
	I2C_stop();				// STOP
	if (status == 0x18)			// Если статус = (0x18 ‹‹ 3 ())
	{					// SLA + W &  ACK
		return 0;			// No ERROR
	} else {				// SLA + W & nACK
		return 1;			// ERROR
	};
};
uint8_t I2C_ReadSpecifiedByte(unsigned char addr) {
	unsigned char temp;
	I2C_start(0xD0);			// START + SLA + WR
	I2C_write(addr);			// ADDR
	//I2C_stop();				// STOP
	I2C_start(0xD1);			// START + SLA + RD
	temp = I2C_read_nack();			// READ
	I2C_stop();				// STOP
	return temp;
};

int main(void) {
	uint16_t val[6];
	int16_t temperature;
	DDRA = 0xFF;
	DDRB = 0xFF;
	DDRC = 0xFF;
	DDRD = 0xFF;
	PORTA = 0x00;
	PORTB = 0x00;
	PORTC = 0;
	PORTD = 0;
	I2C_init();
	console_init();
	console_put("Init OK\r\n");
	_delay_ms(100);
	//I2C_WriteSpecifiedByte(0x19, 0x40);
	//I2C_WriteSpecifiedByte(0x1A, 0x2A);
	//I2C_WriteSpecifiedByte(0x1B, 0);
	//I2C_WriteSpecifiedByte(0x1C, 0);
	I2C_WriteSpecifiedByte(0x6B, 0x00);
	console_put("Self test: XA=");
	console_put_BYTE(I2C_ReadSpecifiedByte(0x0D) & 0x1F, 0);
	console_put(" XB=");
	console_put_BYTE(I2C_ReadSpecifiedByte(0x0E) & 0x1F, 0);
	console_put(" XC=");
	console_put_BYTE(I2C_ReadSpecifiedByte(0x0F) & 0x1F, 0);
	console_put("\r\n");
	sei();
	while(1) {
		_delay_ms(1000);
		console_put("\rAccel: X: ");
		val[0] = ((I2C_ReadSpecifiedByte(0x3B) ‹‹ 8) | (I2C_ReadSpecifiedByte(0x3C)));
		val[1] = ((I2C_ReadSpecifiedByte(0x3D) ‹‹ 8) | (I2C_ReadSpecifiedByte(0x3E)));
		val[2] = ((I2C_ReadSpecifiedByte(0x3F) ‹‹ 8) | (I2C_ReadSpecifiedByte(0x40)));
		val[3] = ((I2C_ReadSpecifiedByte(0x43) ‹‹ 8) | (I2C_ReadSpecifiedByte(0x44)));
		val[4] = ((I2C_ReadSpecifiedByte(0x45) ‹‹ 8) | (I2C_ReadSpecifiedByte(0x46)));
		val[5] = ((I2C_ReadSpecifiedByte(0x47) ‹‹ 8) | (I2C_ReadSpecifiedByte(0x48)));
		temperature = ((I2C_ReadSpecifiedByte(0x41) ‹‹ 8) | (I2C_ReadSpecifiedByte(0x42)));
		temperature = temperature / 340 + 36;
		console_put_WORD(val[0],1);
		console_put(" Y: ");
		console_put_WORD(val[1],1);
		console_put(" Z: ");
		console_put_WORD(val[2],1);
		console_put("  Gyro: X: ");
		console_put_WORD(val[3],1);
		console_put(" Y: ");
		console_put_WORD(val[4],1);
		console_put(" Z: ");
		console_put_WORD(val[5],1);
		console_put(" Temperature: ");
		console_put_WORD(temperature, 1);
		console_put("             ");
	};
};
-Alan- вне форума  
Сказали "Спасибо" -Alan-
Kopranych (20.05.2016)
Непрочитано 20.05.2016, 22:52  
Kopranych
Частый гость
 
Регистрация: 16.05.2016
Адрес: Москва
Сообщений: 35
Сказал спасибо: 6
Сказали Спасибо 1 раз в 1 сообщении
Kopranych на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Всем спасибо за ответы особенно -Alan- у меня все заработало! -Alan-Посмотрел ваш код в начале программы вы инициализируете регистр Register 107 – Power Management 1 PWR_MGMT_1 записав в него нули! что не было у меня. Нигде кстати про этот регистр не говорится хотя он важен. Да и хотел спросить у вас про закомментированные регистры выше, что они значат?
Kopranych вне форума  
Непрочитано 20.05.2016, 22:59  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,821
Сказал спасибо: 919
Сказали Спасибо 4,289 раз(а) в 2,570 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

-Alan- вам показал, как не надо писать программу. Все в кучу, одна бестолковая длинная портянка. Не делайте так. Сами же потом увязните в ней.
Easyrider83 вне форума  
Непрочитано 21.05.2016, 08:08  
-Alan-
Прописка
 
Аватар для -Alan-
 
Регистрация: 05.12.2008
Адрес: Россия, Омск
Сообщений: 145
Сказал спасибо: 39
Сказали Спасибо 29 раз(а) в 22 сообщении(ях)
-Alan- на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Отвечу по порядку.
Kopranych:
1. Регистр управления питанием описан в инструкции но явно не указано, что после подачи питания чип находится в режиме сна. Нашёл на Ардуино-форуме пример, где этот же регистр обнуляли.
2. По закомментированным значениям - пытался настроить чип таким способом. Естественно, не вышло =)

Easyrider83, согласен, делать так не надо. Просто я собрал кусочки из своего проекта, которые минимально необходимы именно для быстрой сборки проекта:
TWI обмен данными (адрес кристалла забит жёстко)
UART на вывод в консоль
Собственно сам камушек и всё остальное. Свои проекты я так не веду, если что. А как для примера "Чтобы только собралось и запустилось" - достаточно. Кому надо - перепишет под себя и научится
-Alan- вне форума  
Непрочитано 21.05.2016, 14:28  
Someone
Гражданин KAZUS.RUN
 
Регистрация: 16.06.2005
Сообщений: 942
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
Someone на пути к лучшему
По умолчанию Re: Как считать данные с гироскопа MPU-6050?

Сообщение от Kopranych Посмотреть сообщение
Посмотрел ваш код в начале программы вы инициализируете регистр Register 107 – Power Management 1 PWR_MGMT_1 записав в него нули! что не было у меня.
Это тут не причём. Читай даташиты. У меги16 нет регистра повер менеджмент. А там где он есть, как в меге у Алана, после сброса по подаче питания сей регистр и так заполняется нулями.
Someone вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
FAQ (ЧаВО) по PROTEUS для начинающих и не только dosikus Proteus 221 07.03.2024 22:45
Помогите считать данные с датчика (PIC контроллер) Vyazikov Микроконтроллеры, АЦП, память и т.д 22 08.03.2012 00:37
ST10F269 Считать данные Zahar175 Микроконтроллеры, АЦП, память и т.д 2 25.12.2011 12:45
как в PIC 18F452 считать из такойто ячейки ОЗУ данные? DAS_WEYDER Микроконтроллеры, АЦП, память и т.д 5 22.08.2007 11:09


Часовой пояс GMT +4, время: 12:00.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.