Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI из USI на tiny85
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Dimon49773
Всем привет...
решил создать WAV проигрыватель на ATtiny85. Сам wav файл закидываю во внешнею eeprom AT25P1024. Она работает по протоколу SPI, но так как мой МК не подерживает хардварно этот протокол, решил сделать его софтварно. Но тут и вся загвоздка...в инете ничего толкового не нашёл. Даже написал пару строк, вроде чтото отправляется, но как получать???

Если вам не трудно и есть какие-то соображения поделитесь очень прошу...уже неделю снятся кошмары про SPI
CODE
#include <avr/io.h>
#include "util/delay.h"

unsigned char _FF_spi(unsigned char mydata);

unsigned char _FF_spi(unsigned char mydata)
{
unsigned char temp;

USIDR = mydata;
mydata = 0x11;
temp = 0x13;

USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;

return (USIDR);
}
void port_init(void)
{ DDRB |= _BV(PB3); // as output (CS)
DDRB |= _BV(PB1); // as output (DO)
DDRB |= _BV(PB2); // as output (USISCK)
DDRB &= ~_BV(PB0); // as input (DI)
PORTB |= _BV(PB0); // pullup on (DI)
PORTB |= _BV(PB3); // CS HI
}

int main(void)
{unsigned char resive_byte;

port_init();

while(1){
_delay_ms(100);
PORTB &= 0xFF- _BV(PB3);
resive_byte = _FF_spi(0x03);
PORTB |= _BV(PB3);
}

return 0;
}
_Артём_
Цитата(Dimon49773 @ Jan 18 2012, 18:34) *
Она работает по протоколу SPI, но так как мой МК не подерживает хардварно этот протокол, решил сделать его софтварно.


Поддерживает...
Смотрите модуль USI, ражим SPI master mode 0.

Цитата(Dimon49773 @ Jan 18 2012, 18:34) *
Но тут и вся загвоздка...в инете ничего толкового не нашёл.


Плохо искали. SPI - простейший протокол, поэтому его реализаций - море.

Цитата(Dimon49773 @ Jan 18 2012, 18:34) *
решил сделать его софтварно. Но тут и вся загвоздка...в инете ничего толкового не нашёл. Даже написал пару строк, вроде чтото отправляется, но как получать???

Если вам не трудно и есть какие-то соображения поделитесь очень прошу...уже неделю снятся кошмары про SPI


Что там соображать:
принцып прост:

CODE
void SendByteToSPI(unsigned char data)
{
SS=0;// выход - перед началом посылки ставится в 0
unsigned char bit_cnt=0;
do {
// старший бит первым
if (data&0x80) SPIOUT=1; else SPIOUT=0;
data<<=1;
SPICLK=0;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SPICLK=1;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
if (SPIIN) data|=1;
SPICLK=0;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
} while (++bit_cnt<8)

SS=1;
return data;
}

Цитата(Dimon49773 @ Jan 18 2012, 18:34) *
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;


Статус почему не используется? И регистр данных?

Читайте AVR319: Using the USI module for SPI communication on tinyAVR and megaAVR devices.
Там всё должно быть понятно и готовый драйвер тоже должен быть.
Клим
http://elm-chan.org/works/sd8p/report.html
Получилось урезать до тини261, только файлы должны лежать последовательно(без фрагментации) на карте
s_black
Чтобы Вам не снились кошмары читайте
Dimon49773
Добрый всем день...
вроде с спи разобрался, за что огромно благодарен... а вот с воспроизведением то звука как быть???вроде бы делаю пвм а не поёт....
может посмотрите и направите на правильный путь???
CODE
#include <avr/io.h>
#include "util/delay.h"
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/wdt.h>


unsigned int MODE = 0;

unsigned char _FF_spi(unsigned char mydata);

unsigned char _FF_spi(unsigned char mydata)
{
unsigned char temp;

USIDR = mydata;
mydata = 0x11;
temp = 0x13;

USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;
USICR = mydata;
USICR = temp;

return (USIDR);
}
void port_init(void)
{ DDRB |= _BV(PB3); // as output (CS)
DDRB |= _BV(PB1); // as output (DO)
DDRB |= _BV(PB2); // as output (USISCK)
DDRB &= ~_BV(PB0); // as input (DI)
PORTB |= _BV(PB0); // pullup on (DI)
PORTB |= _BV(PB3); // CS HI

MCUSR = 0;
WDTCR = _BV(WDE) | 0b110;
}

void timer_init(void)
{
PLLCSR = 0b00000110; /* Select PLL clock for TC1.ck */
GTCCR = 0b01100000; /* Enable TC1.OCB as PWM out (L-ch) */
TCCR1 = MODE ? 0b01100001 : 0b00000001; /* Start TC1 with TC1.OCA is enabled as PWM out (R-ch) */
TCCR0A = 0b00000010; /* Enable TC0.ck = 2MHz as interval timer */
TCCR0B = 0b00000010;
TIMSK = _BV(OCIE0A);

}


int main(void)
{unsigned char resive_byte,count;

port_init();

while(1){
count=128;
_delay_ms(1);
PORTB &= 0xFF- _BV(PB3);
_FF_spi(0x3);
_FF_spi(0x0);
_FF_spi(0x0);
_FF_spi(0x0);
while(count--) OCR1B = _FF_spi(0xFF);
PORTB |= _BV(PB3);
}

return 0;
}
Клим
ну так а чего бы ему нормально работать...
Смотрите внимательно Чановский проект.
Таймер1 работает на частоте 64мгц и используется для ШИМа, а от Таймер0 должен быть настроен на выдачу прерываний с частотой семлирования вашего wav-файла.
B как раз по этому прерыванию надо обновлять OCR1B. Обновлять из буфера, в который поступает информация через SPI
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.