zi4rox 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Всё вроде делаю правильно, а нужного результата не получаю. Попробую собрать всё в кучу, и описать что получается. Итак на данный момент код прошивки такой: #include <mega16.h> #include <io.h> #define DDR_SPI DDRB #define DD_MISO PORTB.6 void SPI_SlaveInit(void) { /* Set MISO output, all others input */ DDR_SPI = (1 << 6); /* Enable SPI */ SPCR = 0x40; } unsigned char SPI_SlaveReceive(void) { /* Wait for reception complete */ while(!(SPSR & (1 << 7))); /* Return data register */ return SPDR; } void main (void){ SPI_SlaveInit(); DDRA = 0xFF; while (1){ //SPI_SlaveReceive(); PORTA = SPDR; } } Как в реальности работает этот код: 1. МК запускается (светодиоды выключены) 2. Я посылаю байт на МК (светодиоды выключены) // Т.е - по сути ничего не происходит 3. Если я делаю RESET то на светодиодах появляется переданный в пункте 2 байт (PORTA = SPDR;) // Значит всё таки хоть и как-то криво, но байт передается 4. Если после пункта 3 (когда горят светодиоды), я посылаю ещё раз байт на МК - то всё снова гаснет, и отобразится лишь при следующем перезапуске Ещё стоит заметить, что в коде я закомментировал и не использую процедуру ожидания завершения передачи байта (из даташита): unsigned char SPI_SlaveReceive(void) { /* Wait for reception complete */ while(!(SPSR & (1 << 7))); /* Return data register */ return SPDR; } Путем отладки - выяснил, что условие while(!(SPSR & (1 << 7))) - никогда не будет пройдено => ничего не произойдет Вот такая вот загогулина Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Тем не менее у вас всё абсолютно правильно. Инициализация верна и приём символа абсолютно верен. Согласно схемы приведенной в посте 1 у вас SS вывод в обрыве. SS - слэйв селект. При 1 обязательно, и при обрыве с высокой степенью вероятности у вас SPI в режиме слэйв не будет работать. Реально этот вывод у вас заземлён? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zi4rox 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Да, я SS посадил на землю - без этого даже кривая передача байта была невозможной Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Блин просмотрел. У вас ошибка в голове. Надо так void main (void){ SPI_SlaveInit(); DDRA = 0xFF; while (1){ PORTA = SPI_SlaveReceive(); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NullPointer 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Питается от чего оно у вас? Фильтры по питанию стоят? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zi4rox 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Блин просмотрел. У вас ошибка в голове. Надо так void main (void){ SPI_SlaveInit(); DDRA = 0xFF; while (1){ PORTA = SPI_SlaveReceive(); } } Так я уже пробывал =( Попробывал ещё раз - результат тотже плачевный. Никакой реакции. Мне кажется что загвоздка в самой функции ожидания окончания приёма - SPI_SlaveReceive() - на ней программа стопориться и не выполняется Питается от чего оно у вас? Фильтры по питанию стоят? От блока питания, что сам собирал там фильтрация есть - всё нормально, думаю затык не в этом. Что самое интересное, как всегда вылезет, что причина в чем то очень простом и возможно банальном =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrik.kiev.ua 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба попробуйте использовать 4094 (8–STAGE SHIFT-AND-STORE BUS REGISTER). для Ваших задач, как нарисовано на схеме, самое оно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Да не может быть никаких затыков. Это не медицина. Здесь всё чётко до безобразия. Включил - хомуты устранил - работает. Итак если у вас так как вы писали, а именно: #include <mega16.h> #include <io.h> #define DDR_SPI DDRB #define DD_MISO PORTB.6 void SPI_SlaveInit(void) { /* Set MISO output, all others input */ DDR_SPI = (1 << 6); /* Enable SPI */ SPCR = 0x40; } unsigned char SPI_SlaveReceive(void) { /* Wait for reception complete */ while(!(SPSR & (1 << 7))); /* Return data register */ return SPDR; } void main (void){ SPI_SlaveInit(); DDRA = 0xFF; while (1){ PORTA = SPI_SlaveReceive(); } } То всё будет работать. Для того, чтобы исключить ошибки связи предлагаю подать на MOSI единицу (если светодиоды зажигаются единицей или 0 - если нулём) и "поискрить" SCK. Предварительно подперев её 0 (поискрить на 1). Я уверен, что ваши светодиоды - загорятся. PS: Кстати о порте А. Надеюсь питание на AVCC вы подали? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться