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

Обсуждаем контроллеры компании Atmel.
Ответить
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение 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 и тд есть то и менять их нельзя?
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Менять ножки можете до посинения. В коде SPI аппаратный и ему это не поможет.
Реклама
Электрический кот
Аватара пользователя
Сообщения: 1031
Зарегистрирован: Чт июн 20, 2013 00:00:58
Откуда: москва, м.Сходненская

Сообщение Mishany »

нельзя менять, в режиме программирования в мк не будет работать ни какя программа вами написанная
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Можете пояснить, как режим программирования влияет на другой режим - режим исполнения программы?
Реклама
Эиком - электронные компоненты и радиодетали
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение kotriks »

uk8amk писал(а):Менять ножки можете до посинения. В коде SPI аппаратный и ему это не поможет.
подскажите а как реализовать програмно чтобы можно было выбрать какие захочу? или в атмеге это не потдерживается?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3385
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

kotriks писал(а):как реализовать програмно
Написать программу (или использовать готовую библиотеку) реализующую программный SPI.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение 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;
}
Нужные порты и пины сами подставите.
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение 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;
помогите исправить.
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Мы то можем подсказать, но вам лучше самому прочитать про тернарный оператор в условных выражениях.
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение kotriks »

uk8amk писал(а):Мы то можем подсказать, но вам лучше самому прочитать про тернарный оператор в условных выражениях.
читал и не въехал :))
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение 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 настроен на выход
}

Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Не совсем так.
Тернарный оператор имеет 2 ветки: истина и ложь, точно также как с if-else.
В первоначальном коде он по идее возвращает 1 или 0, которые присваиваются разряду порта. Только код был либо криво скопипастен, либо неверно переписан. Оттого и выдавало ошибку на 0х80.
В вашем коде вы присваеваете пину SPI_MOSI единицу когда условие истинно. Но подумайте, что произойдёт с разрядом порта когда нужно записать 0? Правильно, там останется единица от прошлого разряда. В результате на шину уйдёт совсем не то что ожидалось.
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение kotriks »

если я вас правильно понял тогда это должно выглядеть примерно так

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

if(((write<<i)&0x80)==0x80) PORTB |= ( 1 << SPI_MOSI );
else 
PORTB &= ~( 1 << SPI_MOSI );
:)
Ответить

Вернуться в «AVR»