Страница 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
Попробую без таймеров..