AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
17.04.2012, 10:25
|
|
Почётный гражданин KAZUS.RU
Регистрация: 28.02.2010
Сообщений: 2,297
Сказал спасибо: 53
Сказали Спасибо 461 раз(а) в 392 сообщении(ях)
|
Re: I2C + atmega32
Сообщение от kruftin
|
Ну судя по коду у нас всегда true.
|
Вы код посмотрите - вызов со значением TRUE выставляет бит TWEA
void i2cReceiveByte(unsigned char ackFlag)
{
// begin receive over i2c
if( ackFlag )
{
// ackFlag = TRUE: ACK the recevied data
TWCR = (((TWCR)&TWCR_CMD_MASK)|1‹‹TWINT|1‹‹TWEA);
}
else
{
// ackFlag = FALSE: NACK the recevied data
TWCR = (((TWCR)&TWCR_CMD_MASK)|1‹‹TWINT);
}
}
• Bit 6 – TWEA: TWI Enable Acknowledge Bit
"...The TWEA bit controls the generation of the acknowledge pulse. If the TWEA bit is written
to one, the ACK pulse is generated on the TWI bus if the following conditions are
met:
1. The device’s own Slave address has been received.
2. A general call has been received, while the TWGCE bit in the TWAR is set.
3. A data byte has been received in Master Receiver or Slave Receiver mode.
By writing the TWEA bit to zero, the device can be virtually disconnected from the Twowire
Serial Bus temporarily. Address recognition can then be resumed by writing the
TWEA bit to one again...
PS. Поймите, смысл в Таких конструкциях не всегда очевиден .Нужно знать тонкости каждого регистра (а они бывают и 16-ти разрядные - там важен порядок заполнения) , плюс замена кристалла-бывает в разных местах биты раскиданы,иногда бит в одном регистре разрешает доступ к другому.Вот поэтому и делаются такие функции,что-бы сильно не задумываться,как всё происходит,разработчики рекомендуют,значит следуется воспользоваться советами.Это универсальная конструкция,хотя можно было-бы втупую TWCR |= 0xC0.
Последний раз редактировалось OlegNZH; 17.04.2012 в 10:58.
|
|
|
|
18.04.2012, 09:55
|
|
Частый гость
Регистрация: 26.08.2008
Сообщений: 23
Сказал спасибо: 10
Сказали Спасибо 8 раз(а) в 5 сообщении(ях)
|
Re: I2C + atmega32
Бит TWEA следует выставлять на все принятые байты, кроме последнего, и действует установка этого бита на следующий байт, который еще будет принят. Поэтому, во время обработки предпоследнего байта, не выставляйте этот бит, тогда следующий (последний) принятый байт не будет сопровожден флагом ACK - что послужит указанием передатчику завершить передачу пакета.
__________________
Пенсионер
|
|
|
|
18.04.2012, 10:43
|
|
Частый гость
Регистрация: 26.08.2008
Сообщений: 23
Сказал спасибо: 10
Сказали Спасибо 8 раз(а) в 5 сообщении(ях)
|
Re: I2C + atmega32
И еще. Мк ATMEGA после приема последнего бита текущего байта и выдачи флага ACK (или /ACK) удерживает линию SCL в низком состоянии до тех пор, пока в регистр TWCR не будет чего-нибудь записано, после чего эта линия отпускается и передача будет продолжена. Также сия ATMEGA в режиме мастер (передатчик или приемник) формирует слишком короткий сигнал STOP на I2C. После приема последнего байта транзакции или перед началом новой, на всякий случай, сделайте задержку на TWI_BITRATE тактов процессора, где TWI_BITRATE это значение, которое вы записали в TWBR умноженное на значение константы, записанной в регистр TWSR + 1, чтобы состояние STOP на линиях интерфейса устаканилось до необходимой кондиции.
__________________
Пенсионер
|
|
|
|
18.04.2012, 20:35
|
|
Прописка
Регистрация: 17.02.2012
Сообщений: 109
Сказал спасибо: 10
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: I2C + atmega32
А еще если у меня компас вот на такой плате http://www.seeedstudio.com/wiki/inde..._Compass_v1.0b
То питание на SDA и SDL мне подавать не нужно(что-то я не совсем это понял)?
|
|
|
|
26.04.2012, 22:27
|
|
Прописка
Регистрация: 17.02.2012
Сообщений: 109
Сказал спасибо: 10
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: I2C + atmega32
Ну спаял я этот компас к своей плате, все как надо сделал.
Код который мне давали я переделал под свой HMC5883, хотя там все регистры, да практически все совпадает.
Но в результате получаю по uart в ответе от компаса в качестве старшего байта "3D" и в качестве младшего байта тоже "3D". Что-то покрутил я его и тоже самое он выдает.
Вот участок кода, переменные xh, xl я определил глобально в самом верху:
Код:
|
void HMC5843(void)
{
//unsigned char xh, xl, yh, yl, zh, zl;
long xo, yo, zo;
i2cSendStart();
i2cWaitForComplete();
i2cSendByte(0x3C); //write to HMC
i2cWaitForComplete();
i2cSendByte(0x02); //mode register
i2cWaitForComplete();
i2cSendByte(0x00); //continuous measurement mode
i2cWaitForComplete();
i2cSendStop();
//must read all six registers plus one to move the pointer back to 0x03
i2cSendStart();
i2cWaitForComplete();
i2cSendByte(0x3D); //read from HMC
i2cWaitForComplete();
i2cReceiveByte(TRUE);
i2cWaitForComplete();
xh = i2cGetReceivedByte(); //x high byte
i2cWaitForComplete();
i2cReceiveByte(TRUE);
i2cWaitForComplete();
xl = i2cGetReceivedByte(); //x low byte
i2cWaitForComplete();
xo = xl|(xh ‹‹ 8);
i2cReceiveByte(TRUE);
i2cWaitForComplete();
yh = i2cGetReceivedByte(); //y high byte
i2cWaitForComplete();
i2cReceiveByte(TRUE);
i2cWaitForComplete();
yl = i2cGetReceivedByte(); //y low byte
i2cWaitForComplete();
yo = yl|(yh ‹‹ 8);
i2cReceiveByte(TRUE);
i2cWaitForComplete();
zh = i2cGetReceivedByte();
i2cWaitForComplete(); //z high byte
i2cReceiveByte(TRUE);
i2cWaitForComplete();
zl = i2cGetReceivedByte(); //z low byte
i2cWaitForComplete();
zo = zl|(zh ‹‹ 8);
i2cSendByte(0x3D); //must reach 0x09 to go back to 0x03
i2cWaitForComplete();
i2cSendStop();
}
void main(void)
{
i2cInit();
delay_ms(100);
USART_Init();
#asm("sei");
while(1)
{
HMC5843();
delay_ms(400); //at least 100ms interval between measurements
if (1){
USART_SendChar('p'); //отвечаем компу
USART_SendChar('r');
USART_SendChar('i');
USART_SendChar('v');
USART_SendChar('e');
USART_SendChar('t');
USART_SendChar(xl);
USART_SendChar(xh);
delay_ms(500);
}
}
} |
Во вложении весь код приведен, подскажите что не так. Т.е. получается я послал 3D два раза, а он мне их и отгрузил обратно. Хотя может функция на прием косячна:
Код:
|
void i2cReceiveByte(unsigned char ackFlag)
{
// begin receive over i2c
if( ackFlag )
{
// ackFlag = TRUE: ACK the recevied data
TWCR = (((TWCR)&TWCR_CMD_MASK)|1‹‹TWINT|1‹‹TWEA);
}
else
{
// ackFlag = FALSE: NACK the recevied data
TWCR = (((TWCR)&TWCR_CMD_MASK)|1‹‹TWINT);
}
} |
Может сюда добавить надо READ_sda()?
Код:
|
#define READ_sda() DDRC = DDRC & 0b11111101 //SDA must be input when reading - don't forget the resistor on SDA!! |
Последний раз редактировалось kruftin; 27.04.2012 в 20:25.
|
|
|
|
03.05.2012, 21:57
|
|
Прописка
Регистрация: 17.02.2012
Сообщений: 109
Сказал спасибо: 10
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: I2C + atmega32
Который день уже и никак не могу настроить компас. Получаю лишь 3D да 3D в качестве старшего и младшего байта по координате любой. Врубал порт на вход и безрезультатно. Есть может кто-то у кого работал такой компас.
|
|
|
|
11.05.2012, 22:48
|
|
Прописка
Регистрация: 17.02.2012
Сообщений: 109
Сказал спасибо: 10
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: I2C + atmega32
При проверке статуса i2c получаю код 30, который согласно даташиту на атмега32 означает DATA byte transmitted, NOT ACK received. Опрос статуса проводил на следующем участке:
Код:
|
void HMC5843(void)
{
//unsigned char xh, xl, yh, yl, zh, zl;
long xo, yo, zo;
i2cSendStart();
i2cWaitForComplete();
i2cCheckForStart(); //test for start
i2cSendByte(0x3C); //write to HMC
i2cWaitForComplete();
i2cSendByte(0x02); //mode register
i2cWaitForComplete();
i2cSendByte(0x00); //continuous measurement mode
i2cWaitForComplete();
status_er = i2cGetStatus(); //опрос статуса
//i2cCheckForMT_SLA();
i2cSendStop();
delay_ms(10); |
Т.е. компас отказывается принимать данные или он не работает?
|
|
|
|
15.05.2012, 20:29
|
|
Прописка
Регистрация: 17.02.2012
Сообщений: 109
Сказал спасибо: 10
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: I2C + atmega32
Вот два варианта проекта в CVAVR для моего компаса. К сожалению пока проходит только старт нормально, а дальше 0х20 вместо 0х18 при посылке адреса устройства. Хотя бы понять что поменять то? TWBR менял, делал больше 10, но коды статусные twi не изменились.
|
|
|
|
17.05.2012, 22:40
|
|
Прописка
Регистрация: 17.02.2012
Сообщений: 109
Сказал спасибо: 10
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: I2C + atmega32
На данный момент связь с компасом есть, все проверки проходят согласно даташиту, однако от компаса получаю по всем координатам старший байт ff, младший 00. Пока не знаю в чем дело.
|
|
|
|
22.10.2012, 22:51
|
|
Частый гость
Регистрация: 22.10.2012
Сообщений: 10
Сказал спасибо: 0
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: I2C + atmega32
Кто-нибудь разобрался с процессом калибровки HMC5883L? В даташите очень мало про это сказано, пока пробую методом тыка.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
UART + atmega32
|
kruftin |
Микроконтроллеры, АЦП, память и т.д |
35 |
06.06.2012 11:26 |
Прошивка atmega32
|
kruftin |
Микроконтроллеры, АЦП, память и т.д |
10 |
17.02.2012 17:22 |
Atmega32 и энкодер
|
Pevek80 |
Микроконтроллеры, АЦП, память и т.д |
21 |
06.03.2011 20:46 |
Atmega32 и LCD
|
DEJL1985 |
Делимся опытом |
8 |
20.06.2010 14:35 |
ATmega32
|
NCy |
Микроконтроллеры, АЦП, память и т.д |
20 |
28.04.2007 00:44 |
Часовой пояс GMT +4, время: 23:04.
|
|