Форум за електроника Форуми Форум за електроника
Български форум за електроника, ремонти, схеми, документация
 
 Въпроси/ОтговориВъпроси/Отговори   ТърсенеТърсене   ПотребителиПотребители   ГрупиГрупи   Регистрирайте сеРегистрирайте се 
 ПрофилПрофил   Влезте, за да видите съобщенията сиВлезте, за да видите съобщенията си   ВходВход 

Грешка при SPI трансфер

 
Създайте нова тема   Напишете отговор    Форум за електроника Форуми -> Обща електроника - General Electronics



Предишната тема :: Следващата тема  
Автор Съобщение
p_stoyanoff
Опитен потребител
Опитен потребител


Регистриран на: 14 Окт 2008
Мнения: 537

МнениеПуснато на: Сря Юни 29, 2011 20:24    Заглавие: Грешка при SPI трансфер Отговорете с цитат

Направих си проста схемичка с 2 ПИК-а. Към единият (мастър) съм свързал 2 светодиода и бутон, а към втория (слейв) 1 ЛЕД.
Ето програмките:
ГЛАВЕН:
#include "18F4620.h"
#fuses HS
#use delay(clock=12000000)
#use spi(MASTER)
void data()
{
int datain=0;
if(input(PIN_B0))
{
output_high(PIN_D0);
while(datain!=100)
{
datain=0;
spi_write(200);
delay_ms(50);
if(spi_data_is_in())
{
datain=spi_read();
}
}
output_high(PIN_D2);
}
delay_ms(50);
}
void clean()
{
output_d(0);
delay_ms(50);
}
void main()
{
delay_ms(5000);
output_a(255);
output_e(0);
setup_spi(SPI_MASTER);
while(1)
{
data();
delay_ms(1000);
clean();
}
}


ПОДЧИНЕН:
#include <18F4520.h>
#fuses HS
#use delay(clock=20000000)
#use spi(SLAVE)

void main()
{
int data=0;
delay_ms(5000);

setup_spi(spi_slave);
while(1)
{
if(spi_data_is_in())
{
data=spi_read();
if(data==200)
{
spi_write(100);
output_high(PIN_A0);
delay_ms(1000);
output_low(PIN_A0);

}
}
data=0;
}
}

По принцип програмата трябва да работи така: при натискане на бутона светва първия светодиод, след което се изпраща код 100 към подчинения и се изчаква потвърждение. При пристигане на потвърждението светва втория светодиод, изчаква се 1 секунда и се изчистват портовете.
Само че при част от заявките светва първо първия диод за натиснат бутон, светва почти веднага и втория лед(аз го разбирам като приета заявка), но подчиненият чип не реагира. Това го прави при първа заявка след рестарт или случайно по време на работа.
Някакви идеи защо се получава така???
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла
p_stoyanoff
Опитен потребител
Опитен потребител


Регистриран на: 14 Окт 2008
Мнения: 537

МнениеПуснато на: Чет Юни 30, 2011 9:19    Заглавие: Отговорете с цитат

Направих следното - закачих още няколко светодиода на подчинения чип. След това му зададох да ги включва последователно, а когато получи информация от главния, да включва точно определен ЛЕД за 1 секунда. След това продължава.
Случва се следното- слейв чипа работи без проблем до момента, в който получава информация от втория. След това зацикля. Все едно започва да изпълнява инструкциите си 1 по 1, а тактовия сигнал не идва от неговия осцилатор, а от информацията по SPI.
Двата кварца са с различна стойност(такива имах). Възможно ли е от това да идва проблема???
За мен лично няма логика в това, понеже мастъра определя скоростта на трансфер, а неговия осцилатор е по-бавен - съответно подчинения не би трябвало да има проблем със скоростта....
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла
emil74
Опитен потребител
Опитен потребител


Регистриран на: 16 Мар 2007
Мнения: 1111

МнениеПуснато на: Чет Юни 30, 2011 11:32    Заглавие: Отговорете с цитат

Не съм вкарвал кода в компилатора, за да видя ясно циклите, но ми се струва, че това:
while(datain!=100)
{
datain=0;
...
ще предизвика зацикляне, защото очакваш нещо да достигне стойност 100, а всеки път го нулираш.

По-логично е да е така:

datain=0;
while(datain!=100)
{
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла Посетете сайта на потребителя
p_stoyanoff
Опитен потребител
Опитен потребител


Регистриран на: 14 Окт 2008
Мнения: 537

МнениеПуснато на: Чет Юни 30, 2011 17:02    Заглавие: Отговорете с цитат

Кода си е наред. Подходът ми е грешен!
SPI не работи така. Главният чип инициира обмена на инфо, за това подчиненият увисва докато чака да извърши транфер. За това се получава това накъсване на програмата.
Някой разполага ли с някакви примерни програми за SPI ???
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла
emil74
Опитен потребител
Опитен потребител


Регистриран на: 16 Мар 2007
Мнения: 1111

МнениеПуснато на: Чет Юни 30, 2011 17:15    Заглавие: Отговорете с цитат

Имам, но за друг "C" компилатор. Но е малко по-трудно да се намери SPI код за подчинен контролер. Защо не си направиш библиотека или да дефинираш поведението на подчинения в подпрограма?
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла Посетете сайта на потребителя
p_stoyanoff
Опитен потребител
Опитен потребител


Регистриран на: 14 Окт 2008
Мнения: 537

МнениеПуснато на: Чет Юни 30, 2011 18:59    Заглавие: Отговорете с цитат

Не е проблема в примерите. Имало чалъм работата е тоя интерфейс.
Оправих нещата. Вече работи на 6.
Благодаря все пак!!!
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла
p_stoyanoff
Опитен потребител
Опитен потребител


Регистриран на: 14 Окт 2008
Мнения: 537

МнениеПуснато на: Вто Юли 19, 2011 13:43    Заглавие: Отговорете с цитат

Отново стигнах до задънена улица с този интерфейс. Когато предавам данни само в една посока (от мастър към слейв или обратно) използвам следният код:
MASTER:
spi_write(0x00);
delay_ms(1);
spi_write(data);

SLAVE:
while(1){
if(spi_data_is_in())
{
data=spi_read();
}
}
Първият пакет "събужда" слейва и после се извършва трансфера.
При прости програми това работи, но имам съмнения, че имам някаква кардинална грешка свързана с принципа на действие на функциите.
До колкото разбрах главният инциира трансфера. Когато той изпълнява spi_write се раменя информацията в 2-та буфера. интересува ме при прочитане(spi_read) буферът изпразва ли се или трябва да напиша в него 0х00, за се нулира. От другата страна подчиненият изчаква spi_write , за да започне да пише или чете(поне така разбрах). Ако може някой да обясни и как работи функцията spi_data_is_in(). До колкото рабрах от няколко западни форуми, тази функция "изяжда" първия байт. Това вярно ли е???
Може ли някой да публикува прост пример за транфер на 1 байт от мастър към слайв и след това обратно. Интересува ме принципно каква е последователността (празни команди, закъснения и т.н)
Благодаря предварително!!!!
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла
Покажи мнения от преди:   
Създайте нова тема   Напишете отговор    Форум за електроника Форуми -> Обща електроника - General Electronics Часовете са според зоната GMT + 2 Часа
Страница 1 от 1

 
Към:  
Не Можете да пускате нови теми
Не Можете да отговаряте на темите
Не Можете да променяте съобщенията си
Не Можете да изтривате съобщенията си
Не Можете да гласувате в анкети


Powered by phpBB © 2001, 2005 phpBB Group
Translation by: Boby Dimitrov
Where to Find Free Service Manuals