AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
26.10.2018, 10:22
|
#11
|
Частый гость
Регистрация: 19.05.2014
Сообщений: 48
Сказал спасибо: 5
Сказали Спасибо 11 раз(а) в 11 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
SD Specifications V.3.01 есть? там описана работа с картами SDHC и SDXC: reset карты осуществляется с тактовой частотой 400 кГц.
У тебя на схеме нога MISO (выход SD-card) сделана через резисторы? если да, то сигналы от карты идут с заниженным напряжением (2.1v) - может здесь проблема.
|
|
|
|
26.10.2018, 15:12
|
#12
|
Временная регистрация
Регистрация: 12.09.2018
Сообщений: 92
Сказал спасибо: 6
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
-Alan-, этот код точный рабочий, откуда ты его взял?
Какие типы карточек он инициализирует?
Что за переменные arg, response, command и в uint8_t SPI_Rd_Byte(void)
Что из себя представляют функции SPI_UnSelect_CARD(); , SPI_Select_CARD(); , SPI_SD_SendCMD(?) , SPI_SetFast() ;,SPI_SD_READ_SECTOR(0); , переменная raw_block_buffered ?
|
|
|
|
26.10.2018, 19:32
|
#13
|
Временная регистрация
Регистрация: 12.09.2018
Сообщений: 92
Сказал спасибо: 6
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
Вот скажите, почему если там где проекте вызывается эта функция:
Нажмите, чтобы открыть спойлер
Код:
|
unsigned char spi_SD_Init(void) //инициализация SD карты
{
///////////////////////////////////////////////////////////////////////////////////////////
unsigned char temp;
long int cnt = 0;
SPI_SS_H;
SPI_MOSI_H;
SPI_SCK_L;
_delay_ms(1);
for (unsigned char i=0; i‹80; i++) //80 импульсов (не менее 74) Даташит стр 94
{
SPI_SCK_H;
_delay_us(5);
SPI_SCK_L;
_delay_us(5);
}
_delay_ms(1);
SPI_SS_L; //опускаем SS
_delay_ms(1);
temp = spi_SD_cmd (0x40,0x00,0x00,0x00,0x00,0x95); // CMD0 Даташит стр 102 и 96
if (temp!=0x01) { return 3;} //Выйти, если ответ не 0х01 (результат
spi_SendByte (0xFF);
//cnt=0;
do
{
temp=spi_SD_cmd (0x41,0x00,0x00,0x00,0x00,0x95); //CMD1 (аналогично CMD0, только индекс меняется)
spi_SendByte (0xFF);
cnt++;
}
while ( (temp!=0x00)&&(cnt‹0xFFFF) ); //Ждем ответа R1
if (cnt›=0xFFFF) {return 4;}
//SPI_SS_H;
return 0;
////////////////////////////////////////////////////////////////////////////////////////////
} |
вызвать её 2 раза:
Код:
|
result=spi_SD_Init(); //инициализация SD карты, вывод номера ошибки в первую строку экрана (первое число) 0 - нет ошибки
result=spi_SD_Init();
sprintf(str,"error: %d",result);
//clearlcd();//очистим дисплей
setpos(0,0);
str_lcd(str); |
то SD каточки v.1 начинают работать нормально, но зато перестаёт работать эмуляция в Протеусе?
Кстати, вот ёщё один источник по работе с SD картами:
http://s-engineer.ru/mikrokontroller...ovoj-sistemoj/
там есть вот что:
Цитата:
|
Все, инициализация завершена, теперь можно передавать и считать данные с SD карты. Но учтите, простой карты после инициализации должен быть не более 5 мс, иначе вам нужно заново подать команду инициализация SD карты, т.е. CMD1 или ACMD41 в зависимости от версии.
|
Насколько это соответствует действительности, у меня сейчас это нарушается (вывод на экран занимает около 25мс) ?
Последний раз редактировалось Donker; 26.10.2018 в 20:54.
|
|
|
|
28.10.2018, 19:38
|
#14
|
Временная регистрация
Регистрация: 12.09.2018
Сообщений: 92
Сказал спасибо: 6
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
Я решил, что не буду трать время на код поддерживающий старые карты SD, сосредоточусь на SDHC.
Существует ли протеуская модель карты памяти SDHC ?
Вот тут вычитал:
https://eax.me/stm32-sdcard/
Цитата:
|
Наконец, в третьих, карта может делить SPI-шину с другими устройствами. Понятно, что в этом случае первым делом после запуска прошивки нужно пометить все устройства, как неактивные, подав соответствующее напряжение, обычно высокое, на пины CS. После чего уже можно спокойно общаться с каждым устройством по отдельности, не беспокоясь, что какое-то другое устройство по ошибке решит, что обращались с нему. Но проблема заключается в том, что SD-карта определенным образом интерпретирует данные, передаваемые по SPI, даже не являясь выбранным устройством. Если конкретнее, то при инициализации карты нужно передать 74 или больше единицы (например, 10 байт 0xFF) с высоким напряжением на CS. По этой причине карта либо должна жить на отдельной шине, либо инициироваться перед всеми остальными устройствами. Иначе карта может отказаться работать, я проверял.
|
Эта проблема относится к SDHC ?
|
|
|
|
28.10.2018, 22:20
|
#15
|
Частый гость
Регистрация: 19.05.2014
Сообщений: 48
Сказал спасибо: 5
Сказали Спасибо 11 раз(а) в 11 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
Ну так после подачи питания на устройство установи все CS в 1 (а лучше установи внешнии подтяжки) и дай 74 импульса.
Перед каждым чтением/записи из/на карту делаеш инициализацию и не паришься со своим медленным экраном.
У меня на шине СПИ весят 3 устройства: экран, карта и разные СПИ-модули, и все работают без проблем.
|
|
|
|
02.11.2018, 20:21
|
#16
|
Прописка
Регистрация: 05.12.2008
Адрес: Россия, Омск
Сообщений: 145
Сказал спасибо: 39
Сказали Спасибо 29 раз(а) в 22 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
Сообщение от Donker
|
-Alan-, этот код точный рабочий, откуда ты его взял?
Какие типы карточек он инициализирует?
Что за переменные arg, response, command и в uint8_t SPI_Rd_Byte(void)
Что из себя представляют функции SPI_UnSelect_CARD(); , SPI_Select_CARD(); , SPI_SD_SendCMD(?) , SPI_SetFast() ;,SPI_SD_READ_SECTOR(0); , переменная raw_block_buffered ?
|
Код из моего проекта, он вполне адекватно работал с добрым десятком разных карт памяти. Даже некоторые на 8GB заводились с первой попытки.
SPI_UnSelect_CARD() - макрос или функция, поднимающая пин /CS
SPI_Select_CARD() - Аналогично, отпускающая этот пин вниз
При использовании аппаратного SPI нужно настроить родной пин /CS на выход, иначе не будет работать режим мастера, а в качестве реального пина /CS использовать свободный GPIO пин.
SPI_SD_SendCMD():
Нажмите, чтобы открыть спойлер
Код:
|
uint8_t SPI_SD_SendCMD(uint8_t command, uint32_t arg) {
uint8_t response;
/* wait some clock cycles */
SPI_Rd_Byte(); // DUMMY
SPI_Rd_Byte(); // DUMMY
SPI_Wr_Byte(0x40 | command);
SPI_Wr_Byte((arg ›› 24) & 0xFF);
SPI_Wr_Byte((arg ›› 16) & 0xFF);
SPI_Wr_Byte((arg ›› 8) & 0xFF);
SPI_Wr_Byte((arg ›› 0 )& 0xFF);
switch(command)
{
case CMD_GO_IDLE_STATE:
SPI_Wr_Byte(0x95);
break;
case CMD_SEND_IF_COND:
SPI_Wr_Byte(0x87);
break;
default:
SPI_Wr_Byte(0xff);
break;
};
/* receive response */
for(uint8_t i = 0; i ‹ 10; ++i)
{
response = SPI_Rd_Byte();
if(response != 0xff)
break;
};
return response;
}; |
SPI_SetFast() - функция, переключающая скорость работы SPI на максимальную.
SPI_SD_READ_SECTOR():
Нажмите, чтобы открыть спойлер
Код:
|
uint8_t SPI_SD_READ_SECTOR(uint32_t Sector) {
uint16_t i;
uint32_t calc_Addr;
if (Sector == raw_block_buffered) // Если начало блока совпадает с буфферезованным сектором
{
return R_OK; // Возвращаем успех. Ничего не нужно делать, ибо данные в буфере.
};
SPI_Select_CARD();
if (!(sd_raw_card_type & (1 ‹‹ SD_RAW_SPEC_SDHC))) // Если карта НЕ является SDHC - добавляем 9 бит к адресу.
{
// !SDHC
calc_Addr = ((Sector+249) ‹‹ 9); // DaFaq?! But will not work in other case.
} else {
// SDHC
calc_Addr = (Sector+2048); // And one more DAFAQ!
};
i = SPI_SD_SendCMD(CMD_READ_SINGLE_BLOCK, calc_Addr); // Передаём вычисленный адрес карте
card_answ_at_read = i; // DEBUUUUUG!
if(i)
{
SPI_UnSelect_CARD(); // Отпускаем карту
return R_ERR; // Возвращаем ошибку. =(
};
while (SPI_Rd_Byte() != 0xFE); // Ждём начала блока. Чаще всего до 30-40 итераций.
for (i=0; i‹512; i++) // Читаем байт и заносим его в буфер (512 байт)
{
raw_block[i] = SPI_Rd_Byte();
};
SPI_Rd_Byte(); // CRC
SPI_Rd_Byte(); // CRC (2) // IGNORED T_T
/* deaddress card */
SPI_UnSelect_CARD(); // Отпускаем карту (шину)
SPI_Rd_Byte(); // Тактирование.
raw_block_buffered = Sector; // Запоминаем сектор, коотрый считали.
return R_OK;
}; |
arg - Аргумент команды, если есть. 4 байта. Может быть нулями.
response - Байт-ответа, после которого начинается фактический ответ карты памяти. (Карта может задуматься на десяток циклов).
|
|
|
|
04.11.2018, 19:44
|
#17
|
Временная регистрация
Регистрация: 12.09.2018
Сообщений: 92
Сказал спасибо: 6
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
-Alan-, спасибо, но я уже отказался от идеи работать с SD картами, и сосредоточился на SDHC.
Новый вопрос ко всем:
Нужно ли посылать для инициализации SDHC 74 импульса до опускания chip select?
|
|
|
|
06.11.2018, 13:40
|
#18
|
Временная регистрация
Регистрация: 12.09.2018
Сообщений: 92
Сказал спасибо: 6
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
Ещё вопрос:
В процессе инициализации SDHC, после опускания chip select перед командой CMD0,
нужно ли посылать 0xFF и ждать пока придет ответ 0xFF?
Сейчас у меня проект заработал, сектора пишутся читаются, но есть нюанс - после подключения SDHC, при первой попытке
инициализации превышается время ожидания ответа 0xFF перед CMD0 при количестве циклов 0xFFFF (или 1,5 сек ожидания), но далее инициализация проходит нормально и нормально записывается читается сектор, при последующих попытках
инициализации-записи-чтения, затыка в это месте уже не происходит, почему так?
|
|
|
|
14.11.2018, 20:30
|
#19
|
Прописка
Регистрация: 05.12.2008
Адрес: Россия, Омск
Сообщений: 145
Сказал спасибо: 39
Сказали Спасибо 29 раз(а) в 22 сообщении(ях)
|
Re: Подключение разных SD карт к ATmega328P, как?
Перед началом инициализации, НЕОБХОДИМО послать не менее 74 тактовых импульсов для начала работы в режиме SPI.
В моём коде уже есть полноценная инициализация.
После подачи питания нужно:
1. Выждать 300+мс для внутренних рутин карты памяти.
2. Подать 74+ тактовых импульса на низкой частоте ‹100кГц
3. Вычитать информацию о карте и подготовить её к работе на высокоскоростном режиме (насколько это возможно при SPI интерфейсе). Лично мне удавалось выжать около 8МГц тактирования, выше начиналась фигня.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 13:01.
|
|