| Предишната тема :: Следващата тема |
| Автор |
Съобщение |
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 байт от мастър към слайв и след това обратно. Интересува ме принципно каква е последователността (празни команди, закъснения и т.н)
Благодаря предварително!!!! |
|
| Върнете се в началото |
|
 |
|