Страница 1 из 1

Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 11:48:15
kotriks
Подскажите можно ли меня ноги в программном SPI , а то меняю не работает. Вот код.

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

#define SPI_PORT	PORTB
#define SPI_DDR		DDRB
#define SPI_PIN		PINB

#define SPI_CS_PORT	PORTB
#define SPI_CS_DIR	DDRB


#define SPI_SCK		5
#define SPI_MOSI	3
#define SPI_MISO	4
#define SPI_CS		2 

unsigned char spi_rw(unsigned char byte)
{
	SPDR = byte;
	while(!(SPSR & (1<<SPIF)));
	return SPDR;
}



void spi_init() {

   SPI_DDR = (1<<SPI_SCK)|(1<<SPI_MOSI)|(1<<SPI_CS);   // SCK,MOSI,SS
                  
   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);   // Enable SPI, 

}
или какие выводы у мк MOSI MISO и тд есть то и менять их нельзя?

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 12:00:18
uk8amk
Менять ножки можете до посинения. В коде SPI аппаратный и ему это не поможет.

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 12:01:59
Mishany
нельзя менять, в режиме программирования в мк не будет работать ни какя программа вами написанная

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 12:06:55
uk8amk
Можете пояснить, как режим программирования влияет на другой режим - режим исполнения программы?

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 12:24:31
kotriks
uk8amk писал(а):Менять ножки можете до посинения. В коде SPI аппаратный и ему это не поможет.
подскажите а как реализовать програмно чтобы можно было выбрать какие захочу? или в атмеге это не потдерживается?

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 15:11:36
Мурик
kotriks писал(а):как реализовать програмно
Написать программу (или использовать готовую библиотеку) реализующую программный SPI.

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 15:30:46
uk8amk
Можно как-то так:

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

void sw_spi( uint8_t byte )
{
	uint8_t i;

	STROB_PIN = 0;
	for( i=0; i<8; i++ )
	{
		CLOCK_PIN = 0;
		if( byte & ( 1<<i ) )
			DATA_PIN = 1;
		else
			DATA_PIN = 0;
		CLOCK_PIN = 1;
	};
	STROB_PIN = 1;
}
Нужные порты и пины сами подставите.

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 16:38:19
kotriks
нашёл на одном из сайтов, сделал так

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

char spi_rw(char write)
{
char i, read=0;
for(i=0;i!=8;i++)
{
SPI_MOSI = ( ((write<<i)&0?80)==0?80)?1:0;
_delay_ms(1);
PORTB |= ( 1 << SPI_SCK );//SPI_SCK = 1;
_delay_ms(1);
read<<=1;
if(SPI_MISO) read|=1;
PORTB &= ~( 1 << SPI_SCK );// SPI_SCK = 0;
}
PORTB &= ~( 1 << SPI_MOSI );//SPI_MOSI=0;
return read;

}

void spi_init()
{
PORTB |= ( 1 << SPI_CS );//SPI_CS = 1; // высокий уровень chip select, порт трансивера
// не активен. (cs_ask настроен на выход)
PORTB |= ( 1 << SPI_MISO );//SPI_MISO = 1; // пулл ап, (spi_miso настроен на вход)
PORTB &= ~( 1 << SPI_MOSI );//SPI_MOSI = 0; // мастер аут (spi_mosi настроен на выход)
PORTB &= ~( 1 << SPI_SCK );//SPI_SCK = 0; // spi_sck настроен на выход
}
но авр студия ругается на ошибку в этой строке

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

SPI_MOSI = ( ((write<<i)&0?80)==0?80)?1:0;
помогите исправить.

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 17:10:49
uk8amk
Мы то можем подсказать, но вам лучше самому прочитать про тернарный оператор в условных выражениях.

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 17:47:34
kotriks
uk8amk писал(а):Мы то можем подсказать, но вам лучше самому прочитать про тернарный оператор в условных выражениях.
читал и не въехал :))

Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 18:04:31
kotriks
kotriks писал(а):
uk8amk писал(а):Мы то можем подсказать, но вам лучше самому прочитать про тернарный оператор в условных выражениях.
читал и не въехал :))
кажись дошло, компилиться но как покажет себя в работе будем пробывать. это мне для модуля сс1101.

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


//инициализация SPI интерфейса
#define SPI_PORT	PORTB
#define SPI_DDR		DDRB
#define SPI_PIN		PINB

#define SPI_CS_PORT	PORTB
#define SPI_CS_DIR	DDRB


#define SPI_SCK		х
#define SPI_MOSI	х
#define SPI_MISO	х
#define SPI_CS		х

char spi_rw(char write)
{
char i, read=0;
for(i=0;i!=8;i++)
{
if(((write<<i)&0x80)==0x80) PORTB |= ( 1 << SPI_MOSI );
_delay_ms(1);
PORTB |= ( 1 << SPI_SCK );//SPI_SCK = 1;
_delay_ms(1);
read<<=1;
if(SPI_MISO) read|=1;
PORTB &= ~( 1 << SPI_SCK );// SPI_SCK = 0;
}
PORTB &= ~( 1 << SPI_MOSI );//SPI_MOSI=0;
return read;

}

void spi_init()
{
PORTB |= ( 1 << SPI_CS );//SPI_CS = 1; // высокий уровень chip select, порт трансивера
// не активен. (cs_ask настроен на выход)
PORTB |= ( 1 << SPI_MISO );//SPI_MISO = 1; // пулл ап, (spi_miso настроен на вход)
PORTB &= ~( 1 << SPI_MOSI );//SPI_MOSI = 0; // мастер аут (spi_mosi настроен на выход)
PORTB &= ~( 1 << SPI_SCK );//SPI_SCK = 0; // spi_sck настроен на выход
}


Re: Програмный SPI ATmega168

Добавлено: Вс сен 21, 2014 21:04:25
uk8amk
Не совсем так.
Тернарный оператор имеет 2 ветки: истина и ложь, точно также как с if-else.
В первоначальном коде он по идее возвращает 1 или 0, которые присваиваются разряду порта. Только код был либо криво скопипастен, либо неверно переписан. Оттого и выдавало ошибку на 0х80.
В вашем коде вы присваеваете пину SPI_MOSI единицу когда условие истинно. Но подумайте, что произойдёт с разрядом порта когда нужно записать 0? Правильно, там останется единица от прошлого разряда. В результате на шину уйдёт совсем не то что ожидалось.

Re: Програмный SPI ATmega168

Добавлено: Пн сен 22, 2014 05:12:20
kotriks
если я вас правильно понял тогда это должно выглядеть примерно так

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

if(((write<<i)&0x80)==0x80) PORTB |= ( 1 << SPI_MOSI );
else 
PORTB &= ~( 1 << SPI_MOSI );
:)