Инициализация SD карты+Atmega128a

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

nikityan писал(а):Простите за глупый вопрос: но чем на языке отличается == и != ?
И какой ответ должен быть уже после CMD1?
"==" - равно
"!=" - не равно
после CMD1 должен быть 0x00, если нет ошибок.
Реклама
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

CMD0 проходит успешно в результате 0x01. Далее какие только команды не пробую 0x00 не возвращает. Что делать в этом случае? Какие команды являются основные для разных видов флешек? Я даже не догадываюсь какая у меня версия флешки.
Реклама
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

Научился инициализировать флешку) Теперь читаю с неё подряд все сектора. На флешку записан WAV файл со звуком. Хочу его вывести как звук. Но наработок по ШИМ у меня нету. Как вывести то что я получаю с флешки в виде звука (аналоговых колебаний)? Может у кого есть примерчик кода? Атмега работает на частоте 8 мГц
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

Как вывести то что я получаю с флешки в виде звука
... если хватит 8-ми битного разрешения можно обойтись ЦАП на матрице R-2R.
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

А без кучи резисторов?
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Во-первых какой формат WAV файла (частота и бит).? Если выводить через один провод, с 8-битного в ШИМ выводим подряд данные, а с 16-битного только старшие значения, ну и для понимания процесса проще пробовать сначала моно 8 бит, для 8МГц тактовой частота должна быть не больше 22050Гц
Реклама
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

Я согласен на эти параметры) С чего начать? Я ешё очень слаб в этом деле. Даже при чтении блока с флешки у меня возникает чувство что он читается по кругу а дальше чтение не идёт.

#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Начинаем с того, что читаем шапку файла, в шапке ищем частоту дискретизации и настраиваем какой нибудь таймер на эту частоту, затем проверяем сколько бит данные и сколько каналов, соответственно читаем эти данные и выводим их на ШИМ(ы). Можно и другим путем, записать все файлы на флешке с одинаковой частотой ,битностью и количеством каналов. Частота у нас определяет с какой периодичностью нужно изменять данные на ШИМе, соответственно таймер, который мы настроим на частоту дискретизации, будет выполнять функцию обновления значений ШИМа(ов), сам ШИМ нужен 8-битный.
Допустим есть параметры файла: 8 бит, моно, 22050Гц.
1. Таймер дискрет. настраиваем на частоту 22050Гц.
8000000/8/22050-1=44 ; возьмем прескалер 1/8 , тогда регистр OCRn таймера будет 44.
Тоже самое можно сделать по переполнению с таймером у которого нет OCR регистра, но возьни немного больше.
2. В основном цикле из шапки файла берем значение длины данных и организуем переменную-счетчик, организуем буфер куда будем читать данные с флехи, с этого буфера берем данные для вывода в ШИМ, ну соответственно проверяем на конец буфера, подгружаем его данными из файла.
3. 8-бит моно, значит данные идут однобайтовые в один канал, их и нужно в каждом прерывании таймера выводить по очереди на ШИМ.
В обработчике таймера, который отвечает за частоту дискретности, берем байт данных из файла и выводим его в OCRn таймера, который будет ШИМом, и так далее выводим все данные по очереди, пока не достигли конца данных файла, конец определяем по длине данных (в шапке файла), уменьшая счетчик этих данных.
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

УРАА! Получилось) Вот как только убрать сопровождаюший свист?
Друг Кота
Аватара пользователя
Сообщения: 6322
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

ФНЧ с крутым срезом или заграждающий фильтр на частоту дискретизации
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

http://www.youtube.com/watch?v=KsdKzQ1so2U свист я убрал, ошибка была в регистре ШИМА, он был выставлен на 10 бит. а звук 8. я это исправил). но слышно наглое тарохтение сопровождаюшее звук. я подозреваю что на флешке есть так называемые паразитные сектора, которые не несут ничего полезного. Вопрос: может нужно организовать буфер и постепенно его освобождать? потому что звук у меня идёт на прямую с флешки, как бы в цикле принял-отдал. Если да то попрошу примерчик кода)
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

512 байт прочитали и вывели в шим, там после еще байт CRC, еще байт, и еще почитать пока не будет байт OxFE, после опять 512 байт нужных данных и т.д.
да и вообще велосипедом воспользовались бы: http://elm-chan.org/works/sd8p/report.html
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

вот как убрать всё лишнее? оставить только данные
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

У меня так играло, вполне неплохо:

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

#pragma vector = TIMER1_OVF_vect
__interrupt void Timer1_Ovf (void)
{
//TIMER1 has overflowed
    TCNT1H = 0xFE; //reload counter high value
    TCNT1L = 0x0C; //reload counter low value
    SETBIT(Flags,UPD);
}

void Play_512()
{
unsigned int c;
    for(c=0; c<512; c++)
    {
        OCR0A=SPI_R();
        while(CHKBIT(Flags,UPD)==0);
        CLRBIT(Flags,UPD);        
    }
    SPI_R();    //CRC
    SPI_R();
    while (SPI_R()!=0xFE);
}
Вызываем Play_512() пока музыка не закончится, бит UPD устанавливается в "1" с нужной частотой 8/16 кГц
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

Не получаеться. Вот мой кусок кода:
  • void MMC_Read(void)
    {
    DDRB |=(1<<5);
    PORTD|=(1<<7);
    TCCR1A = (0<<WGM11)|(1<<WGM10)|(1<<COM1A1);
    TCCR1B = (1<<CS10)|(1<<ICNC1);
    TCNT1H = 0xFE; //reload counter high value
    TCNT1L = 0x0C; //reload counter low value
    OCR1A = 0;
    data(0x52);
    data(0x00);
    data(0x04);






    while (1)
    {
    data(0xff);

    temp= SPDR;


    OCR1A =SPDR;
    __delay_cycles(80);

    }



    }
Читает всё с тем же тарахтением!
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

data(0xff); temp= SPDR для чего?
Я уж не помню - вроде читаем с сектора 512 байт и выводим в шим с нужной частотой, дальше идет несколько байт, их не надо в шим (будет мусор), байт 0xFE сигнализирует, что далее будет опять полезных 512 байт и т.д. Это все при условии карточка после форматирования и файлы записаны один раз. У вас в коде этого не видно. Лучше использовать FatFs от Чена (ссылку давал).
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

А дайте ка код процедуры SPI_R();
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

Да там ничего такого:

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

//*********************************************************
unsigned char SPI_R()
{
    SPDR=0xFF;
    while(CHKBIT(SPSR,1<<SPIF)==0);
    return SPDR;
}
//*********************************************************
void SPI_W(unsigned char Data)
{
    SPDR=Data;
    while(CHKBIT(SPSR,1<<SPIF)==0);
}
data(0xff); понял для чего
Встал на лапы
Сообщения: 91
Зарегистрирован: Сб авг 11, 2012 22:31:57

Сообщение nikityan »

Ешё вопросик: CHKBIT и CLRBIT это процедурки? Вторая удаляет паразитные два бита в конце?
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

пользуюсь этим:

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

#define SETBIT(x,y) (x |= (y))      // Set bit y in byte x
#define CLRBIT(x,y) (x &= (~(y)))   // Clear bit y in byte x
#define CHKBIT(x,y) (x & (y))       // Check bit y in byte x
#define TOGGLEBIT(x,y) (x^=y)
Ответить

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