Передача данных по SPI

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Prosperous
Встал на лапы
Сообщения: 129
Зарегистрирован: Ср янв 18, 2012 19:37:10

Передача данных по SPI

Сообщение Prosperous »

Здравствуйте! Начал осваивать МК. Нужно передать данные от одного МК другому по SPI. МК atmega 128. Взял готовую реализацию SPI из datasheet. Вроде ничего сложного. Данные как бы передаются, а в порт ничего не выводится. Подскажите, пожалуйста, неучу, где ошибка.

Инициализация мастера

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

void SPI_MasterTransmit()
{
unsigned char cData;
/* Запуск передачи данных */
cData = 0x55;
SPDR = cData;
/* Ожидание завершения передачи данных */
while(!(SPSR & (1<<SPIF)))
;
}

void main(void) 
{
PORTB=0x00;
DDRB=0x07;
SPCR=0x50;
SPSR=0x00;
SPI_MasterTransmit();
}
Инициализация слэйва

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

unsigned char SPI_receive(void)
{
unsigned char data;
data = SPDR;
while(!(SPSR & (1<<SPIF)));
return data;
}

void main(void)
{
PORTB=0x00;
DDRB=0x08;
PORTE=0x00;
DDRE=0xFF;
SPCR=0x40;
SPSR=0x00;
PORTE = SPI_receive();
}
Реклама
Prosperous
Встал на лапы
Сообщения: 129
Зарегистрирован: Ср янв 18, 2012 19:37:10

Re: Передача данных по SPI

Сообщение Prosperous »

вопрос решен. Возник еще один. откуда взялись 2 еденицы перед 0х55?
Вложения
симуляция_1.jpg
(115.69 КБ) 776 скачиваний
Последний раз редактировалось Prosperous Пн фев 13, 2012 15:30:05, всего редактировалось 1 раз.
Реклама
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Передача данных по SPI

Сообщение Engineer_Keen »

Не видно что это за единицы, не хватает графика линии CLK.
Prosperous
Встал на лапы
Сообщения: 129
Зарегистрирован: Ср янв 18, 2012 19:37:10

Re: Передача данных по SPI

Сообщение Prosperous »

перезалил файл
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Передача данных по SPI

Сообщение Engineer_Keen »

Как я и думал, это никакие не единицы на SPI, это просто до первой передачи или инициализации нога, которая MOSI висит в "1". Ее при инициализации перед выводом в DDRB нужно сразу в "0" поставить, хотя это не должно влиять на обмен по SPI.
Реклама
Prosperous
Встал на лапы
Сообщения: 129
Зарегистрирован: Ср янв 18, 2012 19:37:10

Re: Передача данных по SPI

Сообщение Prosperous »

так вроде судя по инициализации (см код выше) Это нога в нуле
Реклама
Prosperous
Встал на лапы
Сообщения: 129
Зарегистрирован: Ср янв 18, 2012 19:37:10

Re: Передача данных по SPI

Сообщение Prosperous »

Добрый день. Есть такая, на мой взгляд, не тривиальная задача. Нужно организовать передачу данных между ПЛИС(slave) и МК(master) по SPI. Т.к. с такими системами отладки я не знаком, то не придумал ничего умнее, как на время отладки заменить ПЛИС микроконтроллером с программным SPI. Полазил по форуму и нашел решение программного SPI для mastera и переделал под slave.

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

#define MOSI   PINA.0
#define MISO PORTA.1
#define SS PINA.2
#define SCK  PORTB.3

char data[96]; // в плисене в очереди на передачу стоит 96 бит данных. м.б. тип данных тут другой нужен?
unsigned char spi(char *data){
   unsigned char mosi = 0;
   unsigned char mask = 0x01; // если надо начинать со старшего бита - заменить на 0x80
if (SS==0)
{
   for( ; mask; mask <<= 1){ // если надо начинать со старшего бита - заменить на mask >>= 1;
       MISO = data & mask;
       SCK = 1;
       if(MOSI) mosi |= mask;
       SCK = 0;
   }
}
   return mosi;
}

void main(void)
{
//инициализацию портов пропускаю

spi(data);

}


пока возникли 2 вопроса:
1. здесь линия SCK программно настраивается, а в ПЛИС она аппаратная. Как реализовать это здесь сохранив программный SPI?
2. Нужно передать 12 байт данных, а тут после байта программа завершает свою работу. Чего не хватает?

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

Re: Передача данных по SPI

Сообщение s_black »

Здесь почитайте
Аватара пользователя
Meteor
Друг Кота
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....
Контактная информация:

Re: Передача данных по SPI

Сообщение Meteor »

пока возникли 2 вопроса:
1. здесь линия SCK программно настраивается, а в ПЛИС она аппаратная. Как реализовать это здесь сохранив программный SPI?
2. Нужно передать 12 байт данных, а тут после байта программа завершает свою работу. Чего не хватает?
1) Раз у вас МК является ведущим, то так и оставьте. ПЛИС надо только соединить с МК (при наличии конечно конфигурации ПЛИС).
2) Можно сделать просто. Если используется SPI МК - передавать 2 байта один из которых упаковать не полностью или разделить на старший\младший с признаком (полет фантазии неисчерпаем). Если же делается чисто программный протокол (плевать какие выводы МК задействованы), то в рамках него можно сделать передачу и 4 бит и 12 бит и 35 бит - тут опять ничего не держит за руки\ноги\лапы и хвосты
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Prosperous
Встал на лапы
Сообщения: 129
Зарегистрирован: Ср янв 18, 2012 19:37:10

Re: Передача данных по SPI

Сообщение Prosperous »

подумав, сварганил програмку под slave. токо чето не работает. хотя на мой взгляд все логично :) Укажите, пожалуйста, где я не прав

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

#define BYTES_NUMBER	12 //количество байт, которое над передать
#define MOSI   PINA.1         
#define MISO PORTA.0
#define SCK  PIND.0    // повесил на ногу прерывания
#define SS  PINA.2

#include <mega128.h>

char TX_DataBuffer[BYTES_NUMBER]={0xF9,0x55,0x33,0x01,0xBC,0x4A,0x80,0x12,0xCB,0x55,0x73,0x62}; //данные
char TX_Cnt = 0; //счетчик бит
char Bits_Cnt = 0; // счетчик байт
char Flag_Int0 = 0; // выполняет роль нарастающего фронта CLK

unsigned char SPI_receive();


interrupt [EXT_INT0] void ext_int0_isr(void)
{
Flag_Int0++;
}

unsigned char SPI_receive()
{
unsigned char cData = 0;
unsigned char mask = 0x80; 
unsigned char temp = 0;
    if (SS == 0)
    {
      for (Bits_Cnt=0; Bits_Cnt<8;Bits_Cnt++)
      {
      cData << Bits_Cnt;
      temp=cData&mask;
      MISO = temp;
      }
      
    }
              
    else
      MISO = 0;	
    
    if(Bits_Cnt == 7)
    {  
      Bits_Cnt=0;
      TX_Cnt++;
    }
	
    if(TX_Cnt < 12)
    cData = TX_DataBuffer[TX_Cnt];
    if(TX_Cnt == 12)
    {
    Flag_Int0 = 0;
    #asm("cli")
    TX_Cnt=0;
    Bits_Cnt=0;
    }
return MISO;
}


void main(void)
{

PORTA=0x00;               
DDRA=0x01;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

PORTF=0x00;
DDRF=0x01;

EICRA=0x03;
EICRB=0x00;
EIMSK=0x01;
EIFR=0x01;

TX_Cnt = 0;
Bits_Cnt = 0;
#asm("sei")
while (1)
{

PORTF = PINC & 1;
if (Flag_Int0>=1)
SPI_receive();
};
 
}
Закрыто

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