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

Программный SPI для PIC

Добавлено: Ср сен 07, 2011 20:38:50
Hispanus
За неимением на борту своего МК аппаратного spi, но при острой нужде реализовать этот протокол (общение с радиомодулем TR24A), а также нежеланием тратиться на новый чип (например 16f877), я обратился к даташитам. В результате в моём мозгу сложилось устойчивое понимание этого протокола:
-Выделяю три ножки любого порта: для сигнала синхронизации, исходящих данных, входящих данных.
-Мастер, которым является МК, начинает формировать синхроимпульсы, которые принимает Приёмник (в данном случае радиомодуль). При каждом спаде\возрастании этого синхроимпульса, мастер устанавливает ножку исходящих данных в состояние очередного бита данных. В это же время приёмник читает ножку для входящих данных и записывает их в сдвиговый регистр. Так повторяется пока не будет передан\получен целый байт. После того как он получен его значение загружается в буфер, после чего цикл чтения\записи заводится снова.
Поправьте меня, если что то не так :)

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 21:13:28
dosikus
Hispanus Прием обязателен ?
Если подключать что то типа LCD , прием не нужен . Интерфейс реализуется достаточно просто...

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 21:15:47
Hispanus
Мне нужно организовать обмен между МК и радиомодулем..без приёма думаю никак :) Для синхроимпульсов думаю использовать таймер, а приём и передачу сделать через прерывания...

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 21:56:17
dosikus
Hispanus писал(а):Мне нужно организовать обмен между МК и радиомодулем..без приёма думаю никак :) Для синхроимпульсов думаю использовать таймер, а приём и передачу сделать через прерывания...
Прием так же можно , тактирование все равно мастер задает .
Пока сделайте без таймеров и прерываний . Может этого вам и хватит.
На чем пишете ?

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:19:09
Hispanus
Пишу на Си в PIC C Compile (css). Если не использовать таймеры, откуда взять синхроимпульсы? :) Кварц использую внутренний...МК - pic16f628a.

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:26:26
dosikus
Hispanus писал(а):Пишу на Си в PIC C Compile (css). Если не использовать таймеры, откуда взять синхроимпульсы? :) Кварц использую внутренний...МК - pic16f628a.
Ручками , данные все равно придется так же ручками толкать.
Ничего страшного, скорости хватит . С LCD же работаем на софтовом SPI ...

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:33:22
Hispanus
Ну почему ручками..если вход для синхронизации зацепить на ножку RB0\INT, то при каждом новом импульсе будут вызываться прерывание, в обработчике которого и можно будет сделать запись\чтение :)

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:36:02
Hispanus
dosikus писал(а):
Hispanus писал(а):Пишу на Си в PIC C Compile (css). Если не использовать таймеры, откуда взять синхроимпульсы? :) Кварц использую внутренний...МК - pic16f628a.
Ручками , данные все равно придется так же ручками толкать.
Ничего страшного, скорости хватит . С LCD же работаем на софтовом SPI ...
У Вас случайно нет никакого рабочего примера, чтобы можно было подглядеть как другие это делали :)

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:36:35
Аlex
Но синхроимпульсы будет ловить модуль. Зачем их заводить на INT ?

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:41:30
Hispanus
Модуль это и есть главная проблема...В 628 вообще нету ножек, работающих под него..

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:42:22
Слесарь

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

void spi_io_w( char byte_h, char byte_l )
{

	unsigned char n;

	for( n = 0; n < 8; n++ )
	{
		SCK_PIN = 1;
		if ( byte_h & 0x80 ) /* most sign bit first */
		{
			SDO_PIN = 1;
		}
		else
		{
			SDO_PIN = 0;
		}
		DelayUs( 30 );
		byte_h = ( byte_h << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}
	
for( n=0; n < 8; n++ )
	{
		SCK_PIN = 1;
		if ( byte_l & 0x80 ) /* most sign bit first */
		{
			SDO_PIN = 1;
		}
		else
		{
			SDO_PIN = 0;
		}
		DelayUs( 30 );
		byte_l = ( byte_l << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

}

char write_byte( char dat )
{
	char n;
	for( n=0; n < 8; n++ )
	{
		SCK_PIN = 1;
		if ( dat & 0x80 ) /* most sign bit first */
		{
			SDO_PIN = 1;
		}
		else
		{
			SDO_PIN = 0;
		}
		DelayUs( 30 );
		dat = ( dat << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
	}

	return( dat );
}

void spi_io_24b( char * p_spi_byte_h, char * p_spi_byte_s, char * p_spi_byte_l )
{
	unsigned char byte_h = 0;
	unsigned char byte_s = 0;
	unsigned char byte_l = 0;
	char n;

	for( n = 0; n < 8; n++ )
	{
		SCK_PIN = 1;
		DelayUs( 30 );
		byte_h = ( byte_h << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

	for( n = 0; n < 8; n++ )
	{
		SCK_PIN = 1;
		DelayUs( 30 );
		byte_s = ( byte_s << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

	for( n=0; n < 8; n++ )
	{
		SCK_PIN = 1;
		DelayUs( 30 );
		byte_l = ( byte_l << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

	*p_spi_byte_l = byte_l;
	*p_spi_byte_s = byte_s;
	*p_spi_byte_h = byte_h;
}
Этот код я использую в промышленном аппарате. Проблем нет. Работа круглосуточная.
Задержки расчитать относительно тактовой частоты процессора и характеристик микросхем.

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:44:53
Аlex
Hispanus писал(а):Модуль это и есть главная проблема...В 628 вообще нету ножек, работающих под него..
Hispanus писал(а):Мне нужно организовать обмен между МК и радиомодулем..
Я про радиомодуль :)

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:49:13
Hispanus
Аlex писал(а):
Hispanus писал(а):Модуль это и есть главная проблема...В 628 вообще нету ножек, работающих под него..
Hispanus писал(а):Мне нужно организовать обмен между МК и радиомодулем..
Я про радиомодуль :)
А Вы про радиомодуль :) Тогда да, незачем..Но формировать то их всё равно надо, правильно же ведь?

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:50:20
Аlex
Формировать естественно надо. Но ловить их будет слейв (радиомодуль).

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:50:46
Hispanus
Слесарь писал(а):

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

void spi_io_w( char byte_h, char byte_l )
{

	unsigned char n;

	for( n = 0; n < 8; n++ )
	{
		SCK_PIN = 1;
		if ( byte_h & 0x80 ) /* most sign bit first */
		{
			SDO_PIN = 1;
		}
		else
		{
			SDO_PIN = 0;
		}
		DelayUs( 30 );
		byte_h = ( byte_h << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}
	
for( n=0; n < 8; n++ )
	{
		SCK_PIN = 1;
		if ( byte_l & 0x80 ) /* most sign bit first */
		{
			SDO_PIN = 1;
		}
		else
		{
			SDO_PIN = 0;
		}
		DelayUs( 30 );
		byte_l = ( byte_l << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

}

char write_byte( char dat )
{
	char n;
	for( n=0; n < 8; n++ )
	{
		SCK_PIN = 1;
		if ( dat & 0x80 ) /* most sign bit first */
		{
			SDO_PIN = 1;
		}
		else
		{
			SDO_PIN = 0;
		}
		DelayUs( 30 );
		dat = ( dat << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
	}

	return( dat );
}

void spi_io_24b( char * p_spi_byte_h, char * p_spi_byte_s, char * p_spi_byte_l )
{
	unsigned char byte_h = 0;
	unsigned char byte_s = 0;
	unsigned char byte_l = 0;
	char n;

	for( n = 0; n < 8; n++ )
	{
		SCK_PIN = 1;
		DelayUs( 30 );
		byte_h = ( byte_h << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

	for( n = 0; n < 8; n++ )
	{
		SCK_PIN = 1;
		DelayUs( 30 );
		byte_s = ( byte_s << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

	for( n=0; n < 8; n++ )
	{
		SCK_PIN = 1;
		DelayUs( 30 );
		byte_l = ( byte_l << 1 ) | SDI_PIN;
		DelayUs( 30 );
		SCK_PIN = 0;
		DelayUs( 30 );
 	}

	*p_spi_byte_l = byte_l;
	*p_spi_byte_s = byte_s;
	*p_spi_byte_h = byte_h;
}
Этот код я использую в промышленном аппарате. Проблем нет. Работа круглосуточная.
Задержки расчитать относительно тактовой частоты процессора и характеристик микросхем.
Еще бы разобраться теперь, Спасибо :)

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:51:18
Jack_A
Не знаю как у пиков, но вообще для SPI еще сигнал CS нужен.
Я когда-то по молодости сдуру CS слейва напостоянно на 0 посадил. И работало ! Но когда туда случайно ( помеха или что еще ) попадал импульс, он продолжал сдвигать на 1 бит всю последующую инфу, получалось в байте 7 бит - егоные, а 1 - из чужого байта.
Брр... Как меня начальство терпело !

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:53:10
Hispanus
Например, если в роли этого формирователя я возьму таймер2, тогда очередной бит я буду толкать после каждого его вызова, начиная со второго..так? :)

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:55:24
Hispanus
Теоретически SPI и на трёх линиях работать должен по моему, но я могу ошибаться :)

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:55:49
Аlex
Вам же уже посоветовали - попробуйте для начала запустить без таймеров и прерываний. Потом уже, если будет необходимо (я например не вижу в этом необходимости) , сделаете на таймерах.

Re: Программный SPI для PIC

Добавлено: Ср сен 07, 2011 22:59:38
Hispanus
Попробую без таймеров..