реклама на сайте
подробности

 
 
> avr155, Вопрос
alux
сообщение Jul 19 2007, 11:07
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Разбираюсь с этим апнотом. Не понятно, каким образом в функции Get_byte() происходит обнаружение приема последнего байта? Ведь переменная j, которая передается в качестве второго аргумента этой функции, и которая сравнивается с нулем, инкрементируется data_pack.size раз и по идее не станет равной нулю ни при каких условиях. Ну, разве что размер получаемых данных превысит 255. Или я чего-то не доганяю?
На всякий случай прилагаю апнот.

Может быть правильней было бы сделать так:
for(j=data_pack.size;((j)&&(state == SUCCESS));j--)
state = Get_byte(data_pack.data_ptr++,j);
Прикрепленные файлы
Прикрепленный файл  AVR155.zip ( 10.02 килобайт ) Кол-во скачиваний: 50
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
WHALE
сообщение Jul 20 2007, 08:33
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



я уже года 2 работаю с AVR315,глюков не замечал(кроме собственных :-))


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
alux
сообщение Jul 20 2007, 11:53
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Если использовать avr315, как просто получить и/или принять один байт без применения буфера?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 20 2007, 12:10
Сообщение #4


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(alux @ Jul 20 2007, 14:53) *
Если использовать avr315, как просто получить и/или принять один байт без применения буфера?

Никак - буфер должен быть обязательно. И упр. структура.
Но это не должно Вас пугать. Это есть правильный подход.

Цитата(alux @ Jul 20 2007, 09:03) *
Правильно ли будет с моей поправкой?

Думаю что нет.
условие (j) равносильно (j > 0), вы используете пост декремент, а это значит, что 0 в теле цикла никогда не появится.

Я бы сделал функцию чтения блока, т.к. все равно побайтовый I2C обмен практически не нужен:
Код
U8 Get_Block( <Тип записи> *pDataPkt )
{
     U8 size = pDataPkt->size;
     U8 state = ACK;
     while( size-- &&  state == ACK)
     {
          state = Get_byte(pDataPkt->data_ptr++, size);
     }
     return state;
}
Go to the top of the page
 
+Quote Post
alux
сообщение Jul 20 2007, 15:13
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(defunct @ Jul 20 2007, 15:10) *
условие (j) равносильно (j > 0), вы используете пост декремент, а это значит, что 0 в теле цикла никогда не появится.

Значит нужно сделать предекремент?

Цитата(defunct @ Jul 20 2007, 15:10) *
Я бы сделал функцию чтения блока...

Я бы предпочел использовать функцию Send_to_TWI , как в avr155. Только с поправкой (с предекрементом для receive data).

Как отправить по TWI (avr315) массив из 1000 байт? Не инициализировать же буфер из 1000 байт...
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 20 2007, 18:23
Сообщение #6


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(alux @ Jul 20 2007, 18:13) *
Значит нужно сделать предекремент?

нет, нужно менять либо условие (т.к. проверка условия в цикле for делается до модификации),
либо параметр функции:
Get_Byte( xx, j - 1);

либо саму функцию..

Цитата
Я бы предпочел использовать функцию Send_to_TWI , как в avr155. Только с поправкой (с предекрементом для receive data).

я предпочитаю пользоваться функцией блочной записи/чтения:

/***********************************************
* i2c_MemTransfer() *
* begin interrupt handled transfer *
* ---> I2CAddr - address of the target device *
* if even - Master to slave direction *
* if odd - Slave to Master direction *
* ---> memAddr - address of memory cell *
* ---> count - number of bytes to transfer *
* ---> pData - data to write, or pointer to *
* buffer (if receiving) *
* <--- ничего не возвращает *
***********************************************/
void i2c_MemTransfer(U8 I2CAddr, U16 memAddr, U8 count, U8 *pData)

Цитата
Как отправить по TWI (avr315) массив из 1000 байт? Не инициализировать же буфер из 1000 байт...

Блоками например по 32 байта. И буфер сделать 32 байта.
Обычно объем буфера зависит от слейва.
Вы с каким устройством собираетесь работать через i2c?
Go to the top of the page
 
+Quote Post
alux
сообщение Jul 20 2007, 18:30
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(defunct @ Jul 20 2007, 21:23) *
Вы с каким устройством собираетесь работать через i2c?

LCD(TIC154), DS1388(rtc), FOSP-01A(цифровой барометр)
Сейчас вот думаю , как отправить картинку (массив[1064] во флеше) в LCD.
Покажите, пожалуста, на примере с использованием аппаратного twi с прерываниями.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 20 2007, 19:18
Сообщение #8


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(alux @ Jul 20 2007, 21:30) *
Покажите, пожалуста, на примере с использованием аппаратного twi с прерываниями.

Рабочий пример под ARM. Надо будет поменять имена регистров на соответвующие из TWI модуля. Немного подрихтовать напильником, и можно использовать для AVR.

PS: I2C модуль ARM практически ничем (кроме имен регистров) не отличается от TWI модуля AVR
Прикрепленные файлы
Прикрепленный файл  ex21_i2c.rar ( 28.93 килобайт ) Кол-во скачиваний: 44
 
Go to the top of the page
 
+Quote Post
alux
сообщение Jul 20 2007, 20:33
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



я имел в виду пример кода, как отправить большой массив частями по 32 байта по аппаратному TWI. Ну да ладно. Наверно я изобретаю велосипед:
static const unsigned char __flash logo[]={....};
#define COUNT(logo) (sizeof(logo)/sizeof((logo)[0]))
const unsigned char __flash *pic;
unsigned int max;
unsigned char messageBuf[32];
pic = logo;
max=COUNT(logo);

for(unsigned int cnt = 0; cnt < (max/32); cnt++)
{
messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS)|(FALSE<<TWI_READ_BIT);
for(unsigned char i=1;i<32;i++)
messageBuf[i] = *pic++;
TWI_Start_Transceiver_With_Data(messageBuf,32);
}
Только не понятно как быть, если размер массива не кратный 32? Т.е. последняя отправка неполного буфера.
...пока спрашивал, пришла мысль. Можно так?
messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS)|(FALSE<<TWI_READ_BIT);
for(unsigned char i=1;i<(max%32);i++)
messageBuf[i] = *pic++;
TWI_Start_Transceiver_With_Data(messageBuf,(max%32));
...И еще. Первый элемент messageBuf всегда должен быть (TWI_targetSlaveAddress<<TWI_ADR_BITS)|(FALSE<<TWI_READ_BIT); в случае отправки.
Правильно ли я делаю?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 20 2007, 21:15
Сообщение #10


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(alux @ Jul 20 2007, 23:33) *
я имел в виду пример кода, как отправить большой массив частями по 32 байта по аппаратному TWI.

В рамках предыдущего примера - вызвать функцию I2C_TRANSFER n/32 раз с требуемыми параметрами в цикле... где n - объем данных в байтах который надо переслать..

Или Вам надо обязательно за одну транзакцию 1024 байта перегонять?

Цитата
Только не понятно как быть, если размер массива не кратный 32? Т.е. последняя отправка неполного буфера.

При отправке порции отнимайте 32 байта от суммарной длины. Когда остается меньше 32х байт, то отправляйте все что осталось и на этом собсно все.. Зачем там еще операции деления использовать?!
Go to the top of the page
 
+Quote Post
alux
сообщение Jul 20 2007, 21:53
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(defunct @ Jul 21 2007, 00:15) *
При отправке порции отнимайте 32 байта от суммарной длины. Когда остается меньше 32х байт, то отправляйте все что осталось и на этом собсно все.. Зачем там еще операции деления использовать?!

Как узнать, что остается меньше 32х байт? А в моем варианте, допустим надо переслать 1064 байт. Первый раз отправляем 1064/32=33 раз. Остаток отправляем 1064%32=8 байт. А что Вас смущает?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 20 2007, 23:54
Сообщение #12


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(alux @ Jul 21 2007, 00:53) *
Как узнать, что остается меньше 32х байт? А в моем варианте, допустим надо переслать 1064 байт. Первый раз отправляем 1064/32=33 раз. Остаток отправляем 1064%32=8 байт. А что Вас смущает?


Код
while(size)
{
   BytesToSend = (size > 32) ? 32 : size;
   i2c_transfer( devaddr, memaddr, BytesToSend, pData);
   pData += BytesToSend;
   memaddr += BytesToSend;
   size -= BytesToSend;
}
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- alux   avr155   Jul 19 2007, 11:07
- - defunct   Цитата(alux @ Jul 19 2007, 14:07) Разбира...   Jul 19 2007, 15:18
|- - alux   Цитата(defunct @ Jul 19 2007, 18:18) Это ...   Jul 20 2007, 06:03
- - alux   Вот, немного подрихтовал: Кодstatic const unsigned...   Jul 21 2007, 17:51
|- - defunct   Цитата(alux @ Jul 21 2007, 20:51) Если и...   Jul 21 2007, 18:27
||- - alux   Цитата(defunct @ Jul 21 2007, 21:27) Масс...   Jul 23 2007, 16:31
||- - Сергей Борщ   Цитата(alux @ Jul 23 2007, 19:31) Что Вы ...   Jul 23 2007, 17:18
|- - ReAl   Цитата(alux @ Jul 21 2007, 20:51) Если и...   Jul 22 2007, 18:36
- - alux   Не получается у меня загрузить картинку в индикато...   Jul 23 2007, 08:21
- - alux   Скажите, пожалуйста, стоит ли заморачиваться с апп...   Jul 23 2007, 18:44
- - defunct   Цитата(alux @ Jul 23 2007, 21:44) Если да...   Jul 23 2007, 20:43


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 19:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01519 секунд с 7
ELECTRONIX ©2004-2016