Страница 1 из 1

Подключение разных SD карт к ATmega328P, как?

Добавлено: Вт окт 23, 2018 23:16:20
DENIS451
Хочу разобраться как подключать разные типы SD карт, в том числе SDHC к AVR, взял за основу этот пример:
http://narodstream.ru/avr-urok-33-spi-k ... t-chast-1/
для начала хотя бы освоить чтение запись в сектора карты, а потом уже разбираться с файловой системой.

Написал проект (см. ATmega328P + SD.zip (Atmel Studio 7 + эмуляция Proteus 8.7 + схема)) и собрал макетку
(см. Схема.pdf), от примера отличается - с секторами я пытаюсь работать сразу на ATmega328P а не на ATmega8A и экран у меня работает через I2C шину, а не напрямую, в качестве разъёма карточки - припаял переходник SD-microSD, т.е. работать
предполагается только с форматом microSD.

В Протеусе работает нормально, в железе нет.

Алгоритм работы макетной платы: по очереди бесконечно зажигаюnся светодиоды D1...D3, выводятся тестовые строки на экран, запускается таймер1, в нем опрашивается кнопка S3 на PC0, нажатие кнопки на S3 очищает экран, в первой строке
экрана выводятся три числа с номерами ошибок, если ошибок нет то все числа нули, во второй строке четыре байта адреса
начала сектора 512 байт в шестнадцатеричном формате, начиная с сектора 4096, в третьей строке начало буфера чтения забитого символами "c", в четвёртой строке начало буфера чтения после считывание туда сектора из карточки, если всё нормально, видно начало тестового паттерна, каждое следующие нажатие на кнопку увеличивает адрес на один сектор.

Проверял на четырёх карточках:

1) microSD на 64Мб - первое нажатие на кнопку ошибка инициализации 3, последующие пишется-читается нормально

2) microSD на 1Гб - всегда ошибка инициализации 3

3) microSD на 2Гб - первое нажатие на кнопку ошибка инициализации 3, последующие пишется-читается нормально

4) microSDHC на 4Гб - всегда ошибка инициализации 4

Какие будут идеи ?

Есть подозрение что проблемма только в неправильной инициализации карточек.

Листинг файла main.cpp:
Спойлер

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


//*******************************************************************************
#include "main.h"
//*******************************************************************************
#define MOSI   3
#define MISO   4
#define SCK  5
#define SS   2
//*******************************************************************************
char buffer[512] = "SD test SD test SD яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111111199999999яяяяяяяя1111"; //Буфер данных для записи/чтения
char buffer2[512] ={}; //Буфер данных для чтения
//*******************************************************************************
signed char stethik_kn = 0;
uint32_t SD_adr = 2097152; // будем записывать сектора по 512 байт начиная с сектора 4096
//*******************************************************************************

void port_ini(void) //настройка четырёх выводов порта для софтового SPI
{
PORTB|=(1<<SS)|(1<<MISO)|(1<<MOSI);
DDRB|=(1<<SS)|(1<<MOSI)|(1<<SCK);
}

void SPI_SendByte (unsigned char byte)
{
/////////////////////////////////////////////////////////////////////////
for (unsigned char i=0; i<8; i++) //движемся по битам байта
  {
  if ((byte&0x80)==0x00)//проверяем левый бит
  PORTB&=~(1<<MOSI); //если 0, то выставляем 0 на шине
  else PORTB|=(1<<MOSI); //если 1, то выставляем 1
  byte<<=1; //сдвигаем влево, в сторону старшего для проверки следующего бита
  PORTB|=(1<<SCK); //фронт на ножке SCK
  asm("nop"); //1 такт подождём
//   asm("nop"); //1 такт подождём
//   asm("nop"); //1 такт подождём
  PORTB&=~(1<<SCK); //спад на ножке SCK
  }
/////////////////////////////////////////////////////////////////////////
}

unsigned char SPI_ReceiveByte (void)
{
//////////////////////////////////////////////////////////////////////////////
unsigned char result=0;
for(unsigned char i=0; i<8; i++)
  {
  PORTB|=(1<<SCK); //фронт на ножке SCK
  result<<=1; //сдвигаем влево, чтобы записать новый бит
  if ((PINB&(1<<MISO))!=0x00) //запишем новый бит (в младший разряд)
  result=result|0x01; //Считать бит данных
  PORTB&=~(1<<SCK); //спад на ножке SCK
  asm("nop"); //1 такт подождём
//   asm("nop"); //1 такт подождём
//   asm("nop"); //1 такт подождём
  }
return result;
/////////////////////////////////////////////////////////////////////////////
}

unsigned char SD_cmd(char dt0, char dt1, char dt2, char dt3, char dt4, char dt5) //передача команды (пример даташит стр 40)
{
////////////////////////////////////////////////////////////////////////////
unsigned char result;
long int cnt;
SPI_SendByte (dt0);		//Индекс
SPI_SendByte (dt1);		//Аргумент
SPI_SendByte (dt2);
SPI_SendByte (dt3);
SPI_SendByte (dt4);
SPI_SendByte (dt5);		//контрольная сумма
cnt=0;
do   //Ждем ответ в формате R1 (даташит стр 109)
  {				
  result=SPI_ReceiveByte();
  cnt++;
  }
  while ( ((result&0x80)!=0x00)&&(cnt<0xFFFF) );
return result;
////////////////////////////////////////////////////////////////////////////
}

unsigned char SD_Init(void)
{
///////////////////////////////////////////////////////////////////////////////////////////
unsigned char temp;
long int cnt;
for (unsigned char i=0; i<10; i++)	{ SPI_SendByte(0xFF); }		//80 импульсов (не менее 74) Даташит стр 94
PORTB&=~(1<<SS);			//опускаем SS
temp=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=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;}
return 0;
////////////////////////////////////////////////////////////////////////////////////////////
}

unsigned char SD_Write_Block (char* bf, unsigned char dt1, unsigned char dt2, unsigned char dt3, unsigned char dt4)
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char result;
long int cnt;
result=SD_cmd(0x58,dt1,dt2,dt3,dt4,0x95);		//CMD24 даташит стр 51 и 97-98
if (result!=0x00) return 6;			//Выйти, если результат не 0x00
SPI_SendByte (0xFF);
SPI_SendByte (0xFE);				//Начало буфера
for (cnt=0;cnt<512;cnt++)	SPI_SendByte(bf[cnt]); //Данные
SPI_SendByte (0xFF);				//Котрольная сумма
SPI_SendByte (0xFF);
result=SPI_ReceiveByte();
if ((result&0x05)!=0x05) return 6;		//Выйти, если результат не 0x05 (Даташит стр 111)
cnt=0;
do   //Ждем окончания состояния BUSY
  {						
  result=SPI_ReceiveByte();
  cnt++;
  }
  while ( (result!=0xFF)&&(cnt<0xFFFF) );
if (cnt>=0xFFFF) return 6;
return 0;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

unsigned char SD_Read_Block (char* bf, unsigned char dt1, unsigned char dt2, unsigned char dt3, unsigned char dt4)
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char result;
long int cnt;
result=SD_cmd (0x51,dt1,dt2,dt3,dt4,0x95);		//CMD17 даташит стр 50 и 96
if (result!=0x00) return 5;			//Выйти, если результат не 0x00
SPI_SendByte (0xFF);
cnt=0;
do     //Ждем начала блока
  {						
  result=SPI_ReceiveByte();
  cnt++;
  }
  while ( (result!=0xFE)&&(cnt<0xFFFF) );
if (cnt>=0xFFFF) return 5;
for (cnt=0;cnt<512;cnt++)	bf[cnt]=SPI_ReceiveByte(); //получаем байты блока из шины в буфер
SPI_ReceiveByte();					//Получаем контрольную сумму
SPI_ReceiveByte();
return 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

void SD_work (void)  //основная функция чтения-записи SD
{
//-----------------------------------------------------------------
unsigned char result;
char str[20];

unsigned char SD_adr_0 = 0;
unsigned char SD_adr_1 = 0;
unsigned char SD_adr_2 = 0;
unsigned char SD_adr_3 = 0;

// SD_adr_0 =  SD_adr & 0xff;
// SD_adr_1 = (SD_adr & 0xff00) >> 8;
// SD_adr_2 = (SD_adr & 0xff0000) >> 16;
// SD_adr_3 = (SD_adr & 0xff000000) >> 24;

SD_adr_0 = SD_adr;            //разбивка адреса uint32_t на 4 байта 
SD_adr_1 = SD_adr >> 8;
SD_adr_2 = SD_adr >> 16;
SD_adr_3 = SD_adr >> 24;

sprintf(str,"adr: %02x %02x %02x %02x",SD_adr_3, SD_adr_2, SD_adr_1, SD_adr_0);  //вывод адреса начала блока во 2 сторку экрана
clearlcd();//очистим дисплей
setpos(0,1);
str_lcd(str);

for (unsigned int i=0; i<512; i++) //затирание buffer2 символами "с" и вывод первых 19 в 3 строку экрана
  {
  buffer2[i] = 'c';
  }
for (unsigned char i=0; i<=19; i++)
  {
  str[i] = buffer2[i];
  }
setpos(0,2);
str_lcd(str);

port_ini();    //инициализация SD карты, вывод номера ошибки в первую строку экрана (первое число) 0 - нет ошибки
result=SD_Init();
sprintf(str,"error: %d",result);
//clearlcd();//очистим дисплей
setpos(0,0);
str_lcd(str);

result=SD_Write_Block(buffer,SD_adr_3,SD_adr_2,SD_adr_1,SD_adr_0);//Запишем блок из буфера, вывод номера ошибки в первую строку экрана (второе число) 0 - нет ошибки
sprintf(str,"%d",result);
setpos(9,0);
str_lcd(str);

result=SD_Read_Block(buffer2,SD_adr_3,SD_adr_2,SD_adr_1,SD_adr_0);	//Считаем блок в буфер, вывод номера ошибки в первую строку экрана (третье число) 0 - нет ошибки
sprintf(str,"%d",result);
setpos(11,0);
str_lcd(str);
//_delay_ms(1000);
for (unsigned char i=0; i<=19; i++) //вывод первых 19 символолв из буффера в 4 строку экрана
  {
  str[i] = buffer2[i];
  }
buffer2[19] = '\0';
setpos(0,3);
str_lcd(str);
//_delay_ms(1000);

SD_adr = SD_adr + 512;
//-----------------------------------------------------------------
}
//-----------------------------------------------------------------------------------------------------------------------------------
void bibip (uint32_t time_ms, uint32_t freq_hz) //пишание пьезодинамиком на PD0 (время в милисикундах, частота а Герцах)
{
//////////////////////////////////////////////////////////////
uint32_t cycles = 0;
uint32_t period = 0;
period = F_CPU / (24 * freq_hz); //24 - подобранный коэфициент в Протеусе для ATmega328P
cycles = (833 * time_ms)/period; //833 - подобранный коэфициент в Протеусе для ATmega328P
for (unsigned int i =0; i <= cycles; i++)
  {
  PORTD |= (1<<0);
  for (unsigned int q = 0; q <= period; q++){asm("nop");}		
  PORTD &= ~(1<<0);
  for (unsigned int q = 0; q <= period; q++){asm("nop");}						
  }
///////////////////////////////////////////////////////////////
}

void migalka (void) //мигание светодиодами под пишалку для отладки
{
///////////////////////////////////////////////
PORTB |= (1<<0);
bibip(50,500);
_delay_ms(500);
PORTB &= ~(1<<0);
PORTB |= (1<<1);
bibip(50,1000);
_delay_ms(500);
PORTB &= ~(1<<1);
PORTD |= (1<<1);
bibip(50,2000);
_delay_ms(500);
PORTD &= ~(1<<1);
///////////////////////////////////////////
}
//-----------------------------------------------------------------------------------------------------------------------------------
void timers_ini(void) //настройка таймера1 на 10 ms
{
///////////////////////////////////////////////////////////////////////////
TCCR1B = 0;
TCCR1A = 0;
TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению) для первого таймера
// 	OCR1AH = 0xFF; //записываем в регистр число для сравнения - старшый байт
// 	OCR1AL = 0x7F; //записываем в регистр число для сравнения - младший байт
OCR1A = 196; //записываем в регистр число для сравнения

TCCR1B |= ( 1 << CS12 ) | ( 1 << CS10 );//устанавливаем предделитель на 1024
TIMSK1 |= (1<<OCIE1A);   // Разрешить прерывание по совпадению OCR1A
//TIMSK1 |= (1<<OCIE1B);   // Разрешить прерывание по совпадению OCR1B
//TIMSK1 |= (1<<TOIE1);    // Разрешить прерывание по переполнению	
/////////////////////////////////////////////////////////////////////////////
}

ISR (TIMER1_COMPA_vect ) //прерывание таймера1
{
//////////////////дрыгаем PC1 для отладки таймера в протеусе/////////
if ((PINC&0b00000010)) //проверяем состояние PC1
  {
  PORTC &= ~(1<<1); //записать в PC1 ноль
  }
  else
   {
   PORTC |= (1<<1); //записать в PC1 единицу
   }
///////////////////////антидребезговый код кнопки на PC1/////////////////////
if (0 == (PINC&0b00000001))
  {
  stethik_kn++;
  }
  else
    {
	if (stethik_kn < 0)
	  {
	  stethik_kn++; return;
	  }
    }
if ((stethik_kn > 2)  && (0 == (PINC&0b00000001)))
  {
  stethik_kn = -100;
  bibip(50,1200);
  cli(); //запрещаем прерывание
  SD_work();  
  sei();//разрешить прерывания
  }
///////////////////////////////////////////////////////////////////
}
//-----------------------------------------------------------------------------------------------------------------------------------
int main(void)
{
////////////////////////////////////////////////////////////////////////////////////////////////////	
DDRB |= (1<<0); //записать в PC0 единицу (что бы выставить его на выход)
PORTB &= ~(1<<0); //записать в PC0 ноль
DDRB |= (1<<1); 
PORTB &= ~(1<<1);

DDRD |= (1<<0);
PORTD &= ~(1<<0);
DDRD |= (1<<1);
PORTD &= ~(1<<1);

DDRC &= ~(1<<0); //записать в PC0 ноль (что бы выставить его на вход)
PORTC |= (1<<0); //записать в PC0 единицу, для включения резистора подтяжки
DDRC |= (1<<1); //записать в PC1 единицу (что бы выставить его на выход)
PORTC &= ~(1<<1); //записать в PC1 ноль
//*****************************************************************************************************
timers_ini();
sei();//разрешить прерывания

migalka();

//-----------------------------------------------------------------

	I2C_Init();//инициализируем TWI
	LCD_ini();  //инициализируем дисплей
	clearlcd();//очистим дисплей
	setpos(0,0);
	str_lcd("Hello World!");
	setpos(2,1);
	str_lcd("String 2");
	setpos(4,2);
	str_lcd("String 3");
	setpos(6,3);
	str_lcd("String 4");

//-----------------------------------------------------------------
while(1)
  {					
  migalka();	
  }
////////////////////////////////////////////////////////////////////////////////////////////////
}


Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Ср окт 24, 2018 17:55:37
Dimon456
DENIS451 писал(а):В Протеусе работает нормально, в железе нет.
А чем petit fatfs не устроил?
И да, в протеусе карта MMC, а у вас в железе SD.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Ср окт 24, 2018 18:31:35
DENIS451
Компонент Протеуса я скопировал из примера (там исходники выложены), а что, есть компонент лучше?

petit fatfs я собираюсь использовать, просто пока хочу убедится, что железо работает нормально на работе без файловой системы,
кроме того, файловая система с petit fatfs это использование дорогого контроллера с 32Кб памяти минимум.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Ср окт 24, 2018 18:40:54
ARV
petit fatfs работает на atmega8 с 512 байтами ОЗУ и 8К flash

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Ср окт 24, 2018 23:06:49
DENIS451
Я пока застрял на проблеме отображения сигнала SPI в Протеусе,
даже тему отдельную создал:
http://kazus.ru/forums/showthread.php?p ... ost1224937

потому как отлаживать в желе долго, и можно израсходовать ресурс записи
контроллера, и так ничего и не добиться, да и нормального физического осциллографа у меня нет.


ARV, что не так сделано в этом примере, что у прошивка весит 20Кб и в ATmega8 не полезет:
http://narodstream.ru/avr-urok-33-spi-k ... t-chast-6/
(исходный код выложен в конце страницы)

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Чт окт 25, 2018 04:21:52
Dimon456
DENIS451 писал(а):ARV, что не так сделано в этом примере, что у прошивка весит 20Кб и в ATmega8 не полезет:
Потому что в файле pff.h у вас ВСЕ включено, (подкорректируйте так)
Спойлер

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

#define	_USE_READ	1	/* pf_read(): 0:Remove ,1:Enable */ 

#define	_USE_DIR	0	/* pf_opendir() and pf_readdir(): 0:Remove ,1:Enable */ 

#define	_USE_LSEEK	0	/* pf_lseek(): 0:Remove ,1:Enable */ 

#define	_USE_WRITE	1	/* pf_write(): 0:Remove ,1:Enable */ 

#define _FS_FAT32	0	/* 0:Supports FAT12/16 only, 1:Enable FAT32 supprt */ поддержка файловой системы FAT32 

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Чт окт 25, 2018 10:01:55
DENIS451
Спасибо, только это не у меня включено это у Владимира, это не мой сайт.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Чт окт 25, 2018 10:04:14
ARV
кстати, запись на флешку в petit fatfs - это просто насмешка какая-то, пользоваться ею все равно толком нереально, так что лучше себя и не тешить этой надеждой - выключать и юзать только чтение.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Пт окт 26, 2018 18:47:36
DENIS451
Вот скажите, почему если там где проекте вызывается эта функция:
Спойлер

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

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-ra ... -sistemoj/

там есть вот что:
Все, инициализация завершена, теперь можно передавать и считать данные с SD карты. Но учтите, простой карты после инициализации должен быть не более 5 мс, иначе вам нужно заново подать команду инициализация SD карты, т.е. CMD1 или ACMD41 в зависимости от версии.
Насколько это соответствует действительности, у меня сейчас это нарушается (вывод на экран занимает около 25мс) ?

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Сб окт 27, 2018 14:51:18
Dimon456
По WinImage создает не форматированную карту, даже не карту, а образ какой то. Заставить работать через эту программу мне не удалось.
Самый простой вариант, берем UltraISO и вашу карту на 64Мб, создаем образ диска, и вот этот образ уже используем.
Как мой пример, распакуйте и подсуньте протеусу.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Сб окт 27, 2018 21:25:15
DENIS451
Dimon456, спасибо.

Я уже заметил, что этот компонент Протеуса или подглючивает иногда, или там есть эмуляция случайного разброса параметров,
например превышения скорости передачи на 5% от датащита должно приводить к ошибке чтения в 20% случаях (это так?)!

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Вс окт 28, 2018 13:11:09
Мурик
DENIS451 писал(а):файловая система с petit fatfs это использование дорогого контроллера с 32Кб памяти минимум.
Тогда используйте STM32. МК с 32 КБ флеша и 4 КБ ОЗУ стоит 0.5$. Можно будет использовать FatFs.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Вс окт 28, 2018 14:56:13
Dimon456
Вот пример, перепишите под свои нужды.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Вс окт 28, 2018 17:27:41
DENIS451
Мурик, я уже давно собираюсь переходить на STM32, уже купил сами чипы, но программатор с али не ещё пришёл.
Только как только он придёт, нужно будет решать проблемы уровня по какой схеме собрать макетку, какую среду разработки ставить, как помигать светодиодом и т.п.

Dimon456, спасибо.

Я решил, что не буду трать время на код поддерживающий старые карты SD, сосредоточусь на SDHC.

Существует ли протеуская модель карты памяти SDHC ?


Вот тут вычитал:
https://eax.me/stm32-sdcard/
Наконец, в третьих, карта может делить SPI-шину с другими устройствами. Понятно, что в этом случае первым делом после запуска прошивки нужно пометить все устройства, как неактивные, подав соответствующее напряжение, обычно высокое, на пины CS. После чего уже можно спокойно общаться с каждым устройством по отдельности, не беспокоясь, что какое-то другое устройство по ошибке решит, что обращались с нему. Но проблема заключается в том, что SD-карта определенным образом интерпретирует данные, передаваемые по SPI, даже не являясь выбранным устройством. Если конкретнее, то при инициализации карты нужно передать 74 или больше единицы (например, 10 байт 0xFF) с высоким напряжением на CS. По этой причине карта либо должна жить на отдельной шине, либо инициироваться перед всеми остальными устройствами. Иначе карта может отказаться работать, я проверял.
Эта проблема относится к SDHC ?

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Вс окт 28, 2018 20:19:02
Мурик
DENIS451 писал(а):но программатор с али не ещё пришёл.
Программатор не нужен.
МК прошиваются обычным конвертером USB-USART. http://easystm32.ru/useful-things/42-bootloader-stm32
http://ravenium.ru/прошивка-stm32-с-пом ... onstrator/
http://www.avislab.com/blog/stm32_st_link_ru/
https://radiokot.ru/articles/56/
То что называете программатором, на самом деле отладчик.

DENIS451 писал(а):Только как только он придёт, нужно будет решать проблемы уровня по какой схеме собрать макетку, какую среду разработки ставить, как помигать светодиодом и т.п.
Купили МК или "синюю" плату? На ней есть светодиод.
Помигать. http://purebasic.mybb.ru/viewtopic.php?id=575
Отладить. http://purebasic.mybb.ru/viewtopic.php?id=564

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Вс окт 28, 2018 21:49:31
DENIS451
Только сами чипы, например STM32F103C8T6TR (я так понял, он единственный есть в Протеусе ? Почему так?!).

Макетная плата будет выглядеть как то так: http://kazus.ru/forums/attachment.php?a ... 1538912237

Программаторы такие: http://ali.onl/16BA заказал 2 штуки хотя хотел 4, но дешевле 2 раза по 2 заказать.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Пн окт 29, 2018 10:25:51
Мурик
Конвертер USB-UART есть? Тогда ничего не мешает подключится в выводам A9 и A10 и прошить через загрузчик.
ST-Link нужен при необходимости отладки, т. е. это не программатор, а отладчик.

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Вс ноя 04, 2018 17:30:34
DENIS451
Нужно ли посылать для инициализации SDHC 74 импульса до опускания chip select?

Re: Подключение разных SD карт к ATmega328P, как?

Добавлено: Вт ноя 06, 2018 11:29:16
DENIS451
Ещё вопрос:

В процессе инициализации SDHC, после опускания chip select перед командой CMD0,
нужно ли посылать 0xFF и ждать пока придет ответ 0xFF?

Сейчас у меня проект заработал, сектора пишутся читаются, но есть нюанс - после подключения SDHC, при первой попытке
инициализации превышается время ожидания ответа 0xFF перед CMD0 при количестве циклов 0xFFFF (или 1,5 сек ожидания), но далее инициализация проходит нормально и нормально записывается читается сектор, при последующих попытках
инициализации-записи-чтения, затыка в это месте уже не происходит, почему так?