программный SPI + радиомодуль SI4432

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 75
Зарегистрирован: Пн авг 08, 2011 15:55:47
Откуда: Лысьва

Сообщение kolovrat5 »

Здравствуйте, собрал схему с tiny2313 и радиомодулем SI4432 (точнее две схемы, передатчик и приемник). Оказалось что у этого МК нет SPI. Нашел программный SPI. Тут.
Попытался переделать функции записи и чтения SPI как в статье о работе с модулями SI4432 на Хабре. Все скомпилировалось в WinAVR и прогрузилось. Вроде этот код не зависает (вставлял для теста строчки мигание светодиодом).
Но радиосвязь не заработала.
Спецы, как еще можно проверить что мой программный SPI работает?
ПС. Код функций
Спойлер

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

#define PORT_SPI PORTB
#define PORT_D	 PORTD

#define DDR_SPI  DDRB
#define DDR_D    DDRD

#define PIN_SPI  PINB

#define UCSK     PB7	//CLK
#define DO       PB6	//MISO
#define DI       PB5	//MOSI
#define SS       PD0
#define NIRQ     PD1
#define LED	     PD5

unsigned char tmp;


void USI_init_SPI (void)
{
    DDR_SPI |=  (1<<DO);  			//линия выхода данных - выход
	DDR_SPI |=  (1<<UCSK);			//линия тактирующего сигнала - выход
	DDR_SPI &= ~(1<<DI);  			//линия входа данных - вход
	DDR_D	|=  (1<<SS);  			//линия выбора кристалла - выход
}

//**************функция ЗАПИСИ байта по USI*******************//
void SPI_W (unsigned char reg, unsigned char data_w)
{
	PORT_D &= ~(1<<SS);			//выбираем кристалл, т.е. SI4432
	//------Запись адреса регистра в буфер SPI МК
	//------Установка старшего бита в адресе регистра необходима для проведения операции записи (всего 127 регистров) 
    USIDR = reg | 0x80;				//передаваемые данные в сдвиговый регистр
	USISR |= (1<<USIOIF);			//сбрасываем флаг
	while(!(USISR & (1<<USIOIF)))	//пока нет флага окончания передачи
	{
	   USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
	}
    USIDR = data_w;					//передаваемые данные в сдвиговый регистр
	USISR |= (1<<USIOIF);			//сбрасываем флаг
	while(!(USISR & (1<<USIOIF)))	//пока нет флага окончания передачи
	{
	   USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
	}	
	PORT_D |= (1<<SS);				//отпускаем модуль SI4432
	//return (USIDR);					
}

//*************функция ЧТЕНИЯ байта по USI*******************//
unsigned char SPI_R (unsigned char reg)
{
	PORT_D &= ~(1<<SS);			//выбираем кристалл, т.е. SI4432
	//Запись адреса регистра в буфер SPI МК
	//Установка старшего бита в адресе регистра необходима для проведения операции записи (всего 127 регистров) 
    USIDR = reg;					//передаваемые данные в сдвиговый регистр
	USISR |= (1<<USIOIF);			//сбрасываем флаг
	while(!(USISR & (1<<USIOIF)))	//пока нет флага окончания передачи
	{
	   USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
	}
    USIDR = 0xFF;					//порожняк
	USISR |= (1<<USIOIF);			//сбрасываем флаг
	while(!(USISR & (1<<USIOIF)))	//пока нет флага окончания передачи
	{
	   USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
	}		
	PORT_D |= (1<<SS);				//отпускаем модуль SI4432
	return (USIDR);					//возвращаем полученные данные
}
Исходник приемника
Спойлерmain.c
ППС. На ардуине связь на этих модулях работала хорошо. На библиотеке RadioHead
Вложения
main.c
(7.79 КБ) 569 скачиваний
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

в тини2313 есть USI а его можно в режим И2С или в SPI настроить...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Открыл глаза
Сообщения: 75
Зарегистрирован: Пн авг 08, 2011 15:55:47
Откуда: Лысьва

Сообщение kolovrat5 »

короче нашел способ проверить работоспособность программного SPI. Сначала буду добиваться связи по SPI между моими платами, а потом уже пытаться конфигурировать модули SI4432
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3202727#p3202727"]в тини2313 есть USI а его можно в режим И2С или в SPI настроить...[/uquote]
вышеприведенный код топикстартера и есть USI в режиме SPI. чем городить такое уродство, как USI, лучше б его вообще не было - тупым дрыгоножеством получилось бы красивее и проще.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

да, точно, с телефона неудобно под спойлеры заглядывать (он всю страницу заново грузит, а с моим инетом это около минуты), потому и поверил на слово, что СПИ программный.
чето тне очень понял, какойто микс похоже - и аппаратные регистры задействованы и ноги переназначены, вечером с компа вчитаюсь, а может и у себя чего найду готового.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

да, аппаратный...
непонятно, почему строчка:
.....//формируем тактирующие импульсы
внутри цикла?
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Ivanoff-iv писал(а):непонятно, почему строчка:
.....//формируем тактирующие импульсы
внутри цикла?
потому что дебильный USI сам этого не делает! можете себе представить, в каком то ли пьяном, то ли наркотическом угаре разработчики создавали АППАРАТНЫЙ модуль последовательного интерфейса, которому для работы сдвигового регистра НЕОБХОДИМО ПРОГРАММНО подавать тактовые импульсы путем записи в регистр управления?! у меня даже матерных слов не хватает на это... :kill:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Открыл глаза
Сообщения: 75
Зарегистрирован: Пн авг 08, 2011 15:55:47
Откуда: Лысьва

Сообщение kolovrat5 »

Ура. Похоже я отмучался. Вспомнил я про великий протеус и в нем домучал код. Этот код что в первом посте работает тока если два контроллера связывать (проверил работоспособность в протеусе).
Нашел другой код функции работы с SPI, подшаманил под свои нужды, и в пихнул его в код для теста SPI и драйвера 7сегментного индикатора, проверил в протеусе... и заработало!!!
Спойлер

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

/* Использование семисегментного индикатора с общим катодом и сдвиговым регистром по протоколу SPI */

#include <avr/io.h>         //подключаем библиотеки
#include <util/delay.h>

#define SPI_DDR     DDRB    //назначаем имя для изменеия направления на порту B
#define SPI_PORT    PORTB   //назначаем имя для используемого порта
#define SPI_SS      PB4     //назначаем имя выхода SS
#define SPI_MOSI    PB5     //назначаем имя выхода MOSI
#define SPI_MISO    PB6     //назначаем имя выхода MISO
#define SPI_SCK     PB7     //назначаем имя выхода SCK

char d[18] ={               //кодирование знаков для семисегментного индикатора
    0x7E,  //0
    0x30,  //1
    0x6D,  //2
    0x79,  //3
    0x33,  //4
    0x5B,  //5
    0x5F,  //6
    0x70,  //7
    0x7F,  //8
    0x7B,  //9
    0x77,  //a
    0x1F,  //b
    0x4E,  //c
    0x3D,  //d
    0x4F,  //e
    0x47,  //f
    0x80,   //.
    0x00   //пусто
};

void spi(unsigned char cmd, unsigned char data)                //Функция передачи двух пакетов по 8 бит по протоколу SPI
{
	unsigned char i=0; 
	SPI_PORT &= ~(1<<SPI_SS);                      //сбрасываем SS в 0
	
	_delay_us(10);
	for (i=0; i<8; i++)
       {
		if( (cmd>>(7-i))&0x01 ) SPI_PORT |= (1<<SPI_MOSI); else SPI_PORT &= ~(1<<SPI_MOSI);		//SPI_MOSI = (cmd>>(7-i))&0x01
        _delay_us(10);        
		SPI_PORT |= (1<<SPI_SCK);					//SPI_SCK=1;
        _delay_us(30);
        SPI_PORT &= ~(1<<SPI_SCK);					//SPI_SCK=0;
        _delay_us(20);
       }
	for (i=0; i<8; i++)
       {
        if( (data>>(7-i))&0x01 ) SPI_PORT |= (1<<SPI_MOSI); else SPI_PORT &= ~(1<<SPI_MOSI);		//SPI_MOSI = (cmd>>(7-i))&0x01
        _delay_us(10);
        SPI_PORT |= (1<<SPI_SCK);					//SPI_SCK=1;
        _delay_us(30);
        SPI_PORT &= ~(1<<SPI_SCK);					//SPI_SCK=0;
        _delay_us(20);
       }
	SPI_PORT |= (1<<SPI_SS);                        //устанавливаем SS в 1
	_delay_us(20);		
}

void clrdig (void)          //Функция очистки индикаторов
{
    spi(0x01,d[17]);
    spi(0x02,d[17]);
    spi(0x03,d[17]);
    spi(0x04,d[17]);
    spi(0x05,d[17]);
}

int main(void)
{
   SPI_DDR = (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS);    //настраиваем MOSI, SCK, SS как выходы
   SPI_PORT |= (1<<SPI_SS);                              //устанавливаем SS в 1
 
   //Инициализация MAX7221
    spi(0x0C,0x00);     //Отключение индикаторов
    spi(0x09,0x00);     //Отключение декодирования
    spi(0x0A,0x0A);     //Интенсивность свечения индикаторов
    spi(0x0B,0x04);     //Количество индикаторов начиная с 0
    spi(0x0F,0x00);     //Отключение теста индикаторов
    spi(0x0C,0x01);     //Включение индикаторов

    clrdig();           //Очистка всех индикаторов

    int i=0;                //Переменная перебора выводимых символов
    int j=1;                //Переменная осчета номера индикатора

    while(1){           //Бесконечный цикл
        spi(j,d[i]);    //Вывод на индикатор j символа i
        _delay_ms(1000);    //Задержка выполнения 1000мс
        i++;
        if(i>17)i=0;
        j++;
        if(j>5)j=1;
    }
    return 0;
}
Сейчес буду отлаживать непосредственно SI4432 и 2313
Вложения
main.c
(3.67 КБ) 522 скачивания
Proteus_7led_2313.zip
(14.97 КБ) 147 скачиваний
Ответить

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