глюки по SPI

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

узнаю свой "стиль" при переходе с Ассемблера на Си)))
Ставим плюсы: )
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

можно все.. но в данном случае оптимизация на скорость обрабатывания кода...
Вообщем суть этого кусочка:
из программы передается переменная произвольной длинны
Оцениваем по совпадению
if (cData==add_value) unsigned long int 0 to 4294967295
if (cData==volt_step) unsigned int 0 to 65535
разбиваем значение на соответствующее кол-во char
засовываем в char transfer[4] unsigned long int в 4 char
unsigned int в 2 первых char
и отправляем соответствующему контроллеру все значимые char
через SPDR по очереди
параллельно собираем принятые в char resive [4] после окончания передачи
из resive[4] собираем принятые char в значения по тем же условиям
if (cData==add_value)
if (cData==volt_step)

resive_add_value и resive_volt_step

asm вставки это как раз и есть расстасовка из unsigned long int в char и сбор обратно из char в unsigned long int
ничего удивительного я в этом не вижу, никакой эквилибристики. Для меня этот код вполне читаем,
если знать назначение вставок, этот же кусок у меня работает в другом проекте. Здесь подозреваю,
что пролетают мимо посылки...
идейный борец за ден. знаки всего мира
Контактная информация:
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

to ibiza11
тут скорее наоборот из си в асм по принуждению :))
идейный борец за ден. знаки всего мира
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

asm вставки это как раз и есть расстасовка из unsigned long int в char и сбор обратно из char в unsigned long int
а чем не устроили union из стандарта Си?
Ставим плюсы: )
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

Это один из множества вариантов реализации...
Ну не профи я, мне показалось такое решение работает быстрее, все-таки прямой asm...
Господа мы уклонились от темы, да я знаю мой код далек от совершенства и знаний у меня не вагон,
за сим и спрашиваю у знающих людей ...
А теперь внимание вопросы ПОЧЕМУ пропадают посылки?..
Нужно ли передергивать после каждой 8-ми битной посылки ногу SS (slave select), или
пачка из 4-х последовательных 8-ми битных должна пройти без потерь?
Какая задержка после/перед передачи значения в SPDR?
У меня пока передается только первый байт посылки дальше тишина....
идейный борец за ден. знаки всего мира
Контактная информация:
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

Новая песня, блин столько граблей по SPI, тут некоторые отсылают читать даташиты, так почему там не описан случай с двумя и более slave- ами, например что во время отдачи данных одним из slave, другой должен перевести ногу MISO в hi-z???
теперь по теме..
Мастер отдает все посылки норм,
слев первую во время приёма пачки не может поднять уровень на MISO до лог 1,
следующая пачка все ок..
Последний раз редактировалось kama3er Пн ноя 05, 2012 17:38:46, всего редактировалось 2 раза.
идейный борец за ден. знаки всего мира
Контактная информация:
Реклама
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Сообщение HHIMERA »

kama3er писал(а):тут некоторые отсылают читать даташиты, так почему там не описан случай с двумя и более slave- ами
www.atmel.com/Images/doc2585.pdf
"Я не даю готовых решений, я заставляю думать!"(С)
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

kama3er писал(а):слев первую во время приёма пачки не может поднять уровень на MISO до лог 1
Если мне не изменяет память, то некоторые микрухи после перевода CS в неактивное состояние ещё некоторое время тратят на "отключение" от шины. Может вы сильно быстро дёргаете CS-ами и данные шлёте?

PS: После прочтения процитированного отрывка вашего сообщения, у меня отчётливо всплыла в памяти фраза из мультфильма - "Казнить нельзя помиловать." :) Давайте, всё-таки, будем стараться писать грамотно. Ну, или, хотя бы понятно.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

Нашел причину по которой slave не получает байты, во время передачи по SPI от мастера,
у slave возникает прерывание по таймеру, поэтому пропадают посылки.
Вопрос как развести эти прерывания, без потерь информации по SPI и в цикле таймера?
Запрет прерываний не катит
идейный борец за ден. знаки всего мира
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

У прерываний таймеров приоритет больше, чем у прерывания от SPI.
Но, вероятнее, причина в том, что обработчик прерывания таймера работает довольно долго, что и приводит к пропуску данных по SPI.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

Насчет прерывания таймера таки да, там у меня много всего, как уведомить master, что могу сейчас принять данные?
Как поставить master в ожидание на отправку данных ?
идейный борец за ден. знаки всего мира
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Уведомить мастера? Никак. У SPI нет такого, как говориться, "by design" (придумано и сделано так).
Можно "кастыль" сделать. Например, прокинуть ещё один сигнальчик между контроллерами и использовать его как готовность приёма у RS-232.
Или, если приём по SPI идёт по прерыванию и в обработчике таймера нет критичных ко времени операций - разрешить вложенные прерывания.

Другой вариант - уменьшить время нахождения программы в обработчике прерывания относительно времени передачи одного байта по SPI. Увеличить частоту МК. Уменьшить скорость SPI.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

Снова с вами в эфире DJ kama3er :music:
был придуман алгоритм костылей и благополучно реализован для уведомления мастера,
благодаря подсказке DI HALT собрал простой, но очень нужный jtag ice дебагер (всем советую).
http://easyelectronics.ru/vnutrisxemnay ... g-ice.html
Вообще очень мощная челюсть у товарища DI HALT, для разжевывания материала...
Протеус выкинул.... пока недалеко.
Нашел прикол в ниже приведенном коде при значении переменной а=2 и переменной i=4
не происходит присвоение SPDR = transfer[a]; // а=2
...
Label1:
if(PINB.3==0)
{
for (a = 0; a < i; a++)
{
SPDR = transfer[a];
delay_us(10);
while(!(SPSR & (1<<SPIF)))
;
resive[a]=SPDR;

if((PINB.3!=0)&&(a!=i))
{
goto Label1;
}
};

}
else
{
goto Label1;
};
у кого какие мысли ....
поделитесь
идейный борец за ден. знаки всего мира
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

решено введением строк у принимающих устройств

// SPI interrupt service routine
interrupt [SPI_STC] void spi_isr(void)
{
array_resive[0]=SPDR;
SPDR=array_transfer[1];
#asm ("cli")
while(!(SPSR & (1<<7)))
; //Жду завершении передачи
for (a=1; a<4;)
{
while(!(SPSR & (1<<7)))
; //Жду завершении передачи
array_resive[a]=SPDR;
a++;
SPDR=array_transfer[a];
};
идейный борец за ден. знаки всего мира
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Код: Выделить всё

 while(!(SPSR & (1<<7)))
 //<<<<---зачем тут 
 for (a=1; a<4;)
 {
 while(!(SPSR & (1<<7))) //делаем то же самое, что здесь 
Просто тупо тратится два слова свободного места.
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Ср фев 15, 2012 17:30:44
Откуда: Украина Шостка

Сообщение kama3er »

Потому что это slave, и до того как наступит прерывание от мастера в регистре SPDR уже должен лежать array_transfer[0]....,
когда slave выпал сюда по прерыванию SPI в SPDR у него уже висит принятый array_resive [0],
а теперь делаем обмен array_resive [0] на array_transfer[1] в регистре SPDR, на всё это необходимо время,
у мастера поэтому, отрабатывается delay_us(2), а здесь стоит
эта строка

Код: Выделить всё

while(!(SPSR & (1<<7)))
и по моему не тупо стоит
и далее по циклу .....
такие вот получились костыли...
Можно это все внести в цикл for (...), но уж больно много у меня гемора получалось,
вышел из положения таким образом
идейный борец за ден. знаки всего мира
Контактная информация:
Ответить

Вернуться в «Периферия»