Jump to content

    

SPI из USI на tiny85

Всем привет...

решил создать WAV проигрыватель на ATtiny85. Сам wav файл закидываю во внешнею eeprom AT25P1024. Она работает по протоколу SPI, но так как мой МК не подерживает хардварно этот протокол, решил сделать его софтварно. Но тут и вся загвоздка...в инете ничего толкового не нашёл. Даже написал пару строк, вроде чтото отправляется, но как получать???

 

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

#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;
}

Edited by IgorKossak
[codebox]

Share this post


Link to post
Share on other sites
Она работает по протоколу SPI, но так как мой МК не подерживает хардварно этот протокол, решил сделать его софтварно.

 

Поддерживает...

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

 

Но тут и вся загвоздка...в инете ничего толкового не нашёл.

 

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

 

решил сделать его софтварно. Но тут и вся загвоздка...в инете ничего толкового не нашёл. Даже написал пару строк, вроде чтото отправляется, но как получать???

 

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

 

Что там соображать:

принцып прост:

 

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;
}

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.

Там всё должно быть понятно и готовый драйвер тоже должен быть.

Edited by IgorKossak
[codebox], лишние пустые строки

Share this post


Link to post
Share on other sites

Добрый всем день...

вроде с спи разобрался, за что огромно благодарен... а вот с воспроизведением то звука как быть???вроде бы делаю пвм а не поёт....

может посмотрите и направите на правильный путь???

#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;
}

attiny85_eeprom_wav.rar

Edited by IgorKossak
[codebox]

Share this post


Link to post
Share on other sites

ну так а чего бы ему нормально работать...

Смотрите внимательно Чановский проект.

Таймер1 работает на частоте 64мгц и используется для ШИМа, а от Таймер0 должен быть настроен на выдачу прерываний с частотой семлирования вашего wav-файла.

B как раз по этому прерыванию надо обновлять OCR1B. Обновлять из буфера, в который поступает информация через SPI

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this