ATMEGA8: подключение к другому контролеру(SPI,I2C)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Goldkiller
Родился
Сообщения: 6
Зарегистрирован: Чт апр 05, 2012 16:17:20

ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Goldkiller »

Здравствуйте уважаемые Коты. У меня проблема с подключением двух контроллеров через SPI или I2C. В инете все проверил, все статьи , форумы, но к сожалению не смог найти нужной информации. Теоретическое подключение мне понятно. Но не получается написать код в Codevision.
Скиньте пожалуйста коды SLAVE и Master под SPI и I2C.
:( :( :(

В прикрепленном файле пример использования SPI (код написан в avrasm)
Вложения
spi8.rar
Подключение 2 МК: SPI
(69.16 КБ) 382 скачивания
Реклама
Аватара пользователя
ds1307
Грызет канифоль
Сообщения: 260
Зарегистрирован: Чт янв 13, 2011 18:54:29
Откуда: Минск

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение ds1307 »

Goldkiller писал(а):Здравствуйте уважаемые Коты. У меня проблема с подключением двух контроллеров через SPI или I2C. В инете все проверил, все статьи , форумы, но к сожалению не смог найти нужной информации. Теоретическое подключение мне понятно. Но не получается написать код в Codevision.
Скиньте пожалуйста коды SLAVE и Master под SPI и I2C.
:( :( :(
Здесь нет телепатов. И теоретически не понятно что вы хотите от этого соединения. Связь должна быть в обе стороны или только в одну. По SPI я думаю будет легче. Генерите код в CV, во вкладке SPI поставте галку чтобы через прерывание. Затем сделайте сначало передачу в одну сторону, от мастера к слейву. Что-то подобное как передача по UART. А там глдядишь и дотумкаете как в обе стороны сделать.
Учиться, учиться, ...
Реклама
Goldkiller
Родился
Сообщения: 6
Зарегистрирован: Чт апр 05, 2012 16:17:20

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Goldkiller »

От этого соединения мне нужно что бы МК MASTER давал команды SLAVE.
Т.е. При замыкании кнопки на MASTERe, загорался LED на SLAVE.
Я просто еще новичок , не совсем понимаю как сделать передачу на SLAVE.
А затем на SLAVE ее принять.
Если вам не сложно, множите написать код ?


Вот сгенерированный код CV:

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

#include <mega8.h>
#include <alcd.h>

interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
data=SPDR;
}

void main(void)
{
PORTB=0x00;
DDRB=0x2C;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;

ACSR=0x80;
SFIOR=0x00;

SPCR=0xD0;
SPSR=0x00;

#asm
    in   r30,spsr
    in   r30,spdr
#endasm
lcd_init(16);
#asm("sei")

while (1){ }
}
Аватара пользователя
ds1307
Грызет канифоль
Сообщения: 260
Зарегистрирован: Чт янв 13, 2011 18:54:29
Откуда: Минск

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение ds1307 »

Так сделать на слейве
// SPI interrupt service routine
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
data=SPDR;
// Place your code here
PORTD=data;
}

А так на мастере
// SPI interrupt service routine
interrupt [SPI_STC] void spi_isr(void)
{
// unsigned char data;
// data=SPDR;
// Place your code here
}
...

while (1){
когда произойдет что-то SPDR = 0bXXXXXXXX;
вместо X поставь 0 или 1
}
Учиться, учиться, ...
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
s_black
Мучитель микросхем
Сообщения: 411
Зарегистрирован: Вс авг 10, 2008 19:35:49
Откуда: Евпатория
Контактная информация:

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение s_black »

Goldkiller писал(а): В инете все проверил, все статьи , форумы, но к сожалению не смог найти нужной информации.

Плохо искал.
Реклама
Goldkiller
Родился
Сообщения: 6
Зарегистрирован: Чт апр 05, 2012 16:17:20

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Goldkiller »

s_black писал(а):
Goldkiller писал(а): В инете все проверил, все статьи , форумы, но к сожалению не смог найти нужной информации.

Плохо искал.


Спасибо вам огромное, все получилось , смог добиться того , что Слейв получал байты с мастера.
Но тут появились некоторые проблемы.
1. Почему то в proteus'е все работает только когда подключаю библиотеку alcd.h либо lcd.h, почему без этой библиотеке мастер не передает байты слейву?
2. Хотел попробовать подключить 3 МК SLAVE, с генерировал тот же код что и на 2 МК Slave.
A) Proteus пишет ошибку: Source code build FALED with 1 error(s). и только после удаление МК с этим кодом все опять работает как и прежде.
Б) Попробовал переключить 2 МК Слейв к другому порту на мастере. Порту дал 0 сигнал. Но Байты мастер так же не передает.
В) Как в SPI работает Адресация ? :( :( :( :(
Вложения
SPI.rar
Готовое Подключение SPI
(130.29 КБ) 294 скачивания
Реклама
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Jack_A »

Goldkiller писал(а): В) Как в SPI работает Адресация ? :( :( :( :(
Если для готового устройства ( флеш, таймкипер, термометр etc. ) - то в соответствии с ДШ на них. Если для самостоятельно программируемого устройства - в соответствии с выбранным протоколом в переданном пакете содержится адрес устройства. Все слейвы слушают линию, и тот, у которого его адрес совпадает с адресом в пакете, отвечает. Адреса у слейвов могут задаваться джамперами, могут быть прошиты ( нежелательно, трудно изменять ) или раздаваться динамически по включению мастера ( мне не нравится, ненадежно, imho ) .
Аватара пользователя
s_black
Мучитель микросхем
Сообщения: 411
Зарегистрирован: Вс авг 10, 2008 19:35:49
Откуда: Евпатория
Контактная информация:

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение s_black »

To Jack_A.
Гм.. Как бы Вам, коллега, сказать помягче, что Вы ошибаетесь :) То, что Вы озвучили - это адресация для I2C. В протоколе SPI адресация устройства осуществляется подачей на SLAVE низкого уровня на вывод "выбор кристалла". Чаще всего - это вывод CS "Chip Select". В AVR, если он работает как SLAVE - это вывод SS.
To Goldkiller.
Насчёт Протеуса ничего не скажу - я в нём не работаю, предпочитаю отладку на железе. Насчёт адресации см. выше и помните, что, если выбрано более одного SLAVE, то они примут данные от MASTER, но вот, что MASTER примет у себя от нескольких SLAVE-ов - это ещё вопрос, т.к. выйдет коллизия с накладкой байтов друг на друга!
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Jack_A »

Да, малость того... Повелся на название темы, не вникнув. С UARTом пробовал, фурычет. Выходы TxD слейвов объединял по И. Но надежнее - мультиплексировать опять же с выборкой слейва, как бы CS.
Впрочем, немного поизвращавшись над линией MISO, можно этот вариант замутить и для SPI. Но, как говорил Суворов, это уже будет через Альпы.
Goldkiller
Родился
Сообщения: 6
Зарегистрирован: Чт апр 05, 2012 16:17:20

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Goldkiller »

s_black писал(а): Насчёт адресации см. выше и помните, что, если выбрано более одного SLAVE, то они примут данные от MASTER, но вот, что MASTER примет у себя от нескольких SLAVE-ов - это ещё вопрос, т.к. выйдет коллизия с накладкой байтов друг на друга!
Передачу 2 сразу слейвам я не буду делать. Только по очередности.
Я хочу что бы на одном МК (Slave1) производился расчет АЦП. например 12v.
На другом МК(Slave2) производился расчет температуры. например 20 С.
Мастер посылал запрос сначала на Slave 1 - 'volt' и в ответ приходил ответ 12, затем посылал запрос на Слейв 2 и получил ответ 20. А затем мастер чтоб все вывел на экран.
Пока что получилось осуществить отправку к слейв байтов. Сейчас пытаюсь понять как отправить обратно ответ мастеру.
Может у вас есть готовый код двух стороннего обмена данных ?
Я на одном сайте нашел как они это делают , но там все на Асемблере, а я к сожалению плохо на Асемблее ориентируюсь. в Основном в Codevision . http://avr.ru/ready/inter/spi/spi Множите помочь если вам не сложно. Просто я пишу диссертацию и это единственный форум в котором мне ответили, а до защиты диссертации остался месяц. :( :( :(
Еще вопрос: Можно ли на Слейве порт SS просто заземлить, а на Мастере SS не куда не подключать ?
Goldkiller
Родился
Сообщения: 6
Зарегистрирован: Чт апр 05, 2012 16:17:20

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Goldkiller »

Вроде бы получилось отправить мастером '0xFF' и слейвом отправить ответ '0x7F' , но в SPI-debugger вышли какие то строчки.
Можете расписать значения их ? Может это какие то ошибки при отправке ? вот скрин.
Вложения
avr_pb.rar
Готовый вариант прием-передачи по SPI
(150.29 КБ) 331 скачивание
SPI_debuger.JPG
Скрин SPI-debugger
(21.2 КБ) 917 скачиваний
Аватара пользователя
s_black
Мучитель микросхем
Сообщения: 411
Зарегистрирован: Вс авг 10, 2008 19:35:49
Откуда: Евпатория
Контактная информация:

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение s_black »

Goldkiller писал(а): Пока что получилось осуществить отправку к слейв байтов. Сейчас пытаюсь понять как отправить обратно ответ мастеру.
Может у вас есть готовый код двух стороннего обмена данных ?
Вы не до конца поняли суть SPI интерфейса. В тот момент, когда идёт передача с мастера на слейв по линии MOSI - MOSI , В ЭТО ЖЕ ВРЕМЯ идёт обратная передача со слейва на мастер по линии MISO - MISO. И, после окончания передачи, в регистре данных мастера будет принятый байт от слейва. Вы же хотите реакции от слева на команду. Т.е. слейву нужно принять команду, допустим измерения напряжения, выполнить её (посчитайте, сколько времени займут эти процессы) и, после измерения напряжения, поместить значение напряжения в регистр данных SPI, чтобы потом передать его ПО ТАКТИРУЮЩИМ ИМПУЛЬСАМ от мастера. Таким образом мастер сначала должен выдать команду на измерение напряжения, выждать необходимое время, и снова запустить обмен, чтобы считать значение напряжения, которое слейв к этому моменту поместит в регистр данных SPI. Лучше задействовать дополнительную линию от слейва на мастер, чтобы от по ней информировать мастер об окончании измерения и готовности передать измеренное значение.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Jack_A »

Goldkiller писал(а):Можно ли на Слейве порт SS просто заземлить, а на Мастере SS не куда не подключать ?
Категорически нельзя ! Я в одной из своих ранних работ так сделал - ужос ! Если в передаваемый поток случайно попадет лишний бит ( каким образом - помеха или что-нибудь - неважно ) - он там будет циркулировать до скончания века, сдвигая информацию на 1 бит. При выборке же через SS буфер очищается, и в описанном случае будет битым только один пакет.

Отправка и прием байта чрезвычайно просты. Вот из работающего проекта :

putSPI: out SPDR,r16
putin: sbis SPSR,SPIE
rjmp putin
ret

getSPI: ldi r16,0xF1
rcall putSPI
in r16,SPDR
ret
Оно на асме, но если надо перевеси на С - думаю, это не проблема. Да и вообще - отстой тот компилятор, что не допускает ассемблерные вставки. Всякие котавижны не люблю.
Причина граблей при обмене может быть в том, что для мастера и слейва назначены разные SPI MODE. Это легко ущучивается осциллом.
А еще не люблю диссертантов за то, что они заявление "Прошу повысить мне зарплату" пишут на 400стр. да еще и в твердом переплете :))

s_black Если там напряг с лишними линиями, можно, подав команду "Начать измерение" затем периодически подавать команду "Выдать данные", получая в ответ или статус "измерение не окончено", или готовые данные. Если, конечно, слейв тоже разрабатывается самостоятельно, и оба устройства можно "подружить" в смысле протокола обмена.
Аватара пользователя
s_black
Мучитель микросхем
Сообщения: 411
Зарегистрирован: Вс авг 10, 2008 19:35:49
Откуда: Евпатория
Контактная информация:

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение s_black »

Jack_A писал(а): s_black Если там напряг с лишними линиями, можно, подав команду "Начать измерение" затем периодически подавать команду "Выдать данные", получая в ответ или статус "измерение не окончено", или готовые данные. Если, конечно, слейв тоже разрабатывается самостоятельно, и оба устройства можно "подружить" в смысле протокола обмена.
Согласен . Кроме того желательно, чтобы слейв, перед загрузкой измеренного значения в регистр данных SPI, предварительно записал туда маркер "измерение завершено", чтобы мастер знал, что следующее считанное значение - результат. Я просто исходил из того что мастер и так загружен какими-то процессами, если по условию ТЗ напряжение и температуру измеряют внешние устройства.
Goldkiller
Родился
Сообщения: 6
Зарегистрирован: Чт апр 05, 2012 16:17:20

Re: ATMEGA8: подключение к другому контролеру(SPI,I2C)

Сообщение Goldkiller »

s_black писал(а): Согласен . Кроме того желательно, чтобы слейв, перед загрузкой измеренного значения в регистр данных SPI, предварительно записал туда маркер "измерение завершено", чтобы мастер знал, что следующее считанное значение - результат.
Спасибо вам большое, понял суть подключения SPI и отправку байтов.
Сделал все как вы написали, но почему то как и писал Jack_A, в конце отправленного байта добавляется лишний ноль. Т.е. отправляю 0b1110 а отправляется 0b11100 ? И как теперь с этим бороться ?

Можете оценить код и написать мои ошибки пожалуйста ?

Master:

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

#include <mega8.h>
#include <spi.h>
#include <delay.h>
float res;

unsigned char SPI_transmit(unsigned char data)
{
    SPDR = data;                     //отправка байта data
    while(!(SPSR & (1<<7)));         //Ожидание завершении отправки
    data = SPDR;                     //получение байта от Слейва и присвоении к переменной data
    return(data);
}

void main(void)
{ 
    PORTB=0x00;                      
    DDRB=0x2C;                       //Инициализация порта В MISO IN    
    PORTC=0xFF;
    DDRC=0x00;      
    SPCR = 0x50;                     //записываем Регистр управления SPE=1 MSTR=1
    SPSR = 0x00;
    res=0x80;
while (1)
{
    if(PINC.0==0)
    {
        res=SPI_transmit(0x7F);      //Отправляем запрос
        delay_ms(200);               //Ждем 
        res=SPI_transmit(0x80);      //Получаем ответ на первый запрос
        while(PINC.0==0){};            //Пока кнопка зажата программа зацикливается
    } 
    delay_ms(200);
};
}
Slave:

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

#include <mega8.h>
#include <spi.h>

int res;
unsigned char SPI_receive(void)
{
    unsigned char data;
    while(!(SPSR & (1<<7)));            //Жду завершении передачи
    data = SPDR;                        //присваиваю переменной принятый байт от мастера
    if(data==0b1110){SPDR=0b1110;}
    if(data==0x80){SPDR=0x80;}                
    else if(data!=14&&data!=0x80){SPDR=data;}
    return data;
}

void main(void)
{
    PORTB=0x00;                      
    DDRB=0x10;                       //инициализация порта MISO IN  
    SPCR=0xC0;                       //записываем Регистр управления SPIE=1 SPE=1
    SPSR=0x00;  
    res=SPI_receive();
}
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»