Инициализация SD карты+Atmega128a
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Добрый лень уважаемые форумчане. Столкнулся с глобальной на моё мнение проблемой. Необходимо инициализировать карточку MicroSD, которая стоит на борту Atmega128a, и подключена к выводам на порте B MOSI, MISO, CLK соответственно. В качестве CS задействован вывод SS (Порт B0). Работать с SPI аппаратно у меня не получается, перерыл кучу исходников. Задумался эмулировать SPI програмно, пока не знаю. Мне нужен проверенный рабочий код инициализации MicroSD карточки желательно под IAR компилятор. Очень буду признателен за помошь. Кто то наверняка пробовал работать с карточкой. Спасибо!
- Реклама
- Сообщения: 160
- Зарегистрирован: Сб дек 08, 2012 16:40:40
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Примеры сложные. Можно пару своих проверенных примеров? Меня инициализация интересует и посылка команд.
- Сообщения: 303
- Зарегистрирован: Сб янв 08, 2011 13:48:41
Вот я делал на мега 48 давно.
Красным цветом инициализация: Подача 74 импульса,потом CMD0(0x40,0,0,0,0,0xff),потом CMD0(0x41,0,0,0,0,0xff)
Команда состоит из 6 отправленных байтов в скопках.
Чтение секторов CMD18 в буфер.
#include <stdio.h>
#include <mega48.h>
#include <delay.h>
#include <string.h>
#include <io.h>
#include <spi.h>
#define data(x) SPDR=x; while (!( SPSR&(1<<7)));
void main() {
int i,temp;
int b;
char array[100] ;
DDRD.2=0;
DDRB=255;
DDRC=255;
// 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x33;
//настройка SPI
SPCR=0b01010000;
SPSR=0x00;
//подаем 74 импульса
PORTB.2=1;
PORTB.3=1;
for(i=0;i<80;i++)
{
data(0xff)
}
PORTB.2=0;
delay_ms(1);
putchar('a');
while(1){
//CMD0
data(0x40);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
putchar('b');
//CMD1
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
}
//CMD17 чтение байтов
data(0x52);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0xfe)
{temp= SPDR;
data(0xff);
}
while(1){
for (i=0;i<100;i++)
{
data(0xff);
array=SPDR ;
}
for (i=0;i<100;i++)
{
putchar(array);
}
}
}
Красным цветом инициализация: Подача 74 импульса,потом CMD0(0x40,0,0,0,0,0xff),потом CMD0(0x41,0,0,0,0,0xff)
Команда состоит из 6 отправленных байтов в скопках.
Чтение секторов CMD18 в буфер.
Спойлер
#define _IO_BITS_DEFINITIONS_#include <stdio.h>
#include <mega48.h>
#include <delay.h>
#include <string.h>
#include <io.h>
#include <spi.h>
#define data(x) SPDR=x; while (!( SPSR&(1<<7)));
void main() {
int i,temp;
int b;
char array[100] ;
DDRD.2=0;
DDRB=255;
DDRC=255;
// 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x33;
//настройка SPI
SPCR=0b01010000;
SPSR=0x00;
//подаем 74 импульса
PORTB.2=1;
PORTB.3=1;
for(i=0;i<80;i++)
{
data(0xff)
}
PORTB.2=0;
delay_ms(1);
putchar('a');
while(1){
//CMD0
data(0x40);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
putchar('b');
//CMD1
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
}
//CMD17 чтение байтов
data(0x52);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0xfe)
{temp= SPDR;
data(0xff);
}
while(1){
for (i=0;i<100;i++)
{
data(0xff);
array=SPDR ;
}
for (i=0;i<100;i++)
{
putchar(array);
}
}
}
- Реклама
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Спасибо) А можете пару библиотек кинуть которые в проэкте есть? А то мне ешё нужна процедура передачи команд.
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Ситуация такова:
У меня объявлены ножки МК которые будут принимать участие в работе с MicroSD.
Обозвал их так:
#define SDDO 3
#define SDCS 0
#define SDDI 2
Теперь мне просто нужно инициализировать карточку.
Дрыгаю портами (не доделано)
DDRB |= (1<<SDCLK)|(1<<SDDO)|(1<<SDCS);
После того как подрыгаю портами и подам 74 импульса, мне нужно передавать команды, которые дадут мне нужный результат.
Так как в Си я только начинающий прошу очень написать мне процедурку отправки команды\данных.
Ноги у меня указаны, нужно только сделать процедуру которая по ним будет отпралять команды\данные.
Помогите пожалуйста начинающему) Спасибо)
У меня объявлены ножки МК которые будут принимать участие в работе с MicroSD.
Обозвал их так:
Спойлер
#define SDCLK 1#define SDDO 3
#define SDCS 0
#define SDDI 2
Теперь мне просто нужно инициализировать карточку.
Дрыгаю портами (не доделано)
Спойлер
PORTB |= (1<<SDDO)|(1<<SDDI)|(1<<SDCS);DDRB |= (1<<SDCLK)|(1<<SDDO)|(1<<SDCS);
Так как в Си я только начинающий прошу очень написать мне процедурку отправки команды\данных.
Ноги у меня указаны, нужно только сделать процедуру которая по ним будет отпралять команды\данные.
Помогите пожалуйста начинающему) Спасибо)
- Сообщения: 303
- Зарегистрирован: Сб янв 08, 2011 13:48:41
#include <stdio.h>
#include <mega48.h>
#include <delay.h>
#include <string.h>
#include <io.h>
#include <spi.h>
это все стандартные библиотеки в Коде висион.Щас перешол на STM32 коде висиона нет.
data(x) -это отправка команд.
#define data(x) SPDR=x; while (!( SPSR&(1<<7)));
temp= SPDR; это принятие ответа,но чтобы ее получить нужно отправить 0xFF data(0xff)
вот отправляем CMD1 и проверяем ответ
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
}
обычно ответ приходил на 3 раз отправки 0xff
data(0x52); или CMD18 непрерывно читает
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
#include <mega48.h>
#include <delay.h>
#include <string.h>
#include <io.h>
#include <spi.h>
это все стандартные библиотеки в Коде висион.Щас перешол на STM32 коде висиона нет.
data(x) -это отправка команд.
#define data(x) SPDR=x; while (!( SPSR&(1<<7)));
temp= SPDR; это принятие ответа,но чтобы ее получить нужно отправить 0xFF data(0xff)
вот отправляем CMD1 и проверяем ответ
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
}
обычно ответ приходил на 3 раз отправки 0xff
Спойлер
//CMD17 чтение байтов читает по 512 байтdata(0x52); или CMD18 непрерывно читает
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Не получается инициализация
{
DDRB = (1<<SDDI)|(1<<SDCLK)|(1<<SDCS)|(0<<SDDO);
PORTB = (1<<SDDI)|(1<<SDCLK)|(1<<SDCS)|(1<<SDDO);
SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0);
SPSR = (0x00);
for(i=0;i<80;i++)
{
data(0xff)
}
PORTB&=(~(1<<SDCS));
__delay_cycles(4000);
while(1){
//CMD0
data(0x40);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
nlcd_Text("SD готова!...",20,5,BLUE,BLACK);
}
}
Спойлер
void MMC_Init(void){
DDRB = (1<<SDDI)|(1<<SDCLK)|(1<<SDCS)|(0<<SDDO);
PORTB = (1<<SDDI)|(1<<SDCLK)|(1<<SDCS)|(1<<SDDO);
SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0);
SPSR = (0x00);
for(i=0;i<80;i++)
{
data(0xff)
}
PORTB&=(~(1<<SDCS));
__delay_cycles(4000);
while(1){
//CMD0
data(0x40);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
nlcd_Text("SD готова!...",20,5,BLUE,BLACK);
}
}
- Сообщения: 303
- Зарегистрирован: Сб янв 08, 2011 13:48:41
попробуй заменить
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
на просото ответ несразу приходит,и после каждой команды выводи число на экран чтобы найти ошибку,и сказать на какой команде косячит
putchar(temp);
while (temp!=0x01)
{temp= SPDR;
data(0xff)}
если непоможит настраивай SPI и проверь правильность подключения(я перепутал MISO и MOSI при подключении)
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
на просото ответ несразу приходит,и после каждой команды выводи число на экран чтобы найти ошибку,и сказать на какой команде косячит
putchar(temp);
while (temp!=0x01)
{temp= SPDR;
data(0xff)}
если непоможит настраивай SPI и проверь правильность подключения(я перепутал MISO и MOSI при подключении)
В С не силен, но мне кажется команда сброса в цикле крутится, её на до один раз отправить, а потом отправлять в цикле 0xFF и ждать ответа 0x01, потом команда инициализацииnikityan писал(а):Не получается инициализация
//CMD0
data(0x40);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while(1){
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
nlcd_Text("SD готова!...",20,5,BLUE,BLACK);
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Ещё как силён) Спасибо помогли вы мне! Первый цикл проходит удачно. Второй тоже проходит но не выдаёт результата на экран, но если while (temp!=0x01) вместо 0x00 то результат есть и цикл заканчивается. Тоесть я могу работать дальше. Если флешки нет то циклы не прекрашаються следовательно всё виснет. Вообшем я убидился что он видит флешку) Естественно я хочу ститать wav файл простейшим образом и вывести звук. Есть у кого примерчики?
data(0x40);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while(1){
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
nlcd_Text("SD готова!...",20,5,BLUE,BLACK);
Спойлер
//CMD0data(0x40);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while(1){
data(0xFF);
b=SPDR;
if(b==0x01){break; }
}
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp!=0x00)
{temp= SPDR;
data(0xff)
nlcd_Text("SD готова!...",20,5,BLUE,BLACK);
После CMD0 нужно сделать паузу в несколько милисекунд пока карта просыпается, ответ 0х01 говорит о том, что карта еще не проснулась. После паузы запускать команду инициализации CMD1 и ответом тогда будет 0х00, дальше можно без пауз отправлять команды.
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Тогда для проверки правильного ответа 0x00 я сделал вот так:
//CMD1
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp==0x00)
{temp= SPDR;
data(0xff)
nlcd_Text("SD готова!",20,5,RED,BLACK);
}
В cmd0 мы принимаем 0x01, что говорит о том что флешка жива но не проснулась, после окончания цикла мы передаём CMD1 и отлавливаем 0x00 как сделал я. Работает, пишет на экране что флешка готова значит принял ответ.
Есть один вопрос: было while (temp!=0x01) я поменял на while (temp==0x00) это правильно?
//CMD1
data(0x41);
data(0x00);
data(0x00);
data(0x00);
data(0x00);
data(0x95);
while (temp==0x00)
{temp= SPDR;
data(0xff)
nlcd_Text("SD готова!",20,5,RED,BLACK);
}
В cmd0 мы принимаем 0x01, что говорит о том что флешка жива но не проснулась, после окончания цикла мы передаём CMD1 и отлавливаем 0x00 как сделал я. Работает, пишет на экране что флешка готова значит принял ответ.
Есть один вопрос: было while (temp!=0x01) я поменял на while (temp==0x00) это правильно?
Я, понимаю, крутимся в цикле пока temp=0? Но так получается сразу вылетаем, потому что первый ответ будет 0xFF. Чтобы проверить, нужно вывести на экран ответ от карты, тогда будет понятно с каким кодом выходим из цикла.nikityan писал(а): Есть один вопрос: было while (temp!=0x01) я поменял на while (temp==0x00) это правильно?
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
На экран не выходит. Я не знаю как выводить значения типа 0х00 как текст.
s=(char*)b;
if(b==0x01){
s=(char*)b;
nlcd_Text(s,20,5,BLUE,BLACK);
пробовал так не выводит
s=(char*)b;
if(b==0x01){
s=(char*)b;
nlcd_Text(s,20,5,BLUE,BLACK);
пробовал так не выводит
Выведи как десятичное, вроде как то так:
printf(“Ответ: %d\n”,temp);
printf(“Ответ: %d\n”,temp);
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
должно быть 0x01nikityan писал(а):После посылки CMD0 какой ответ нужно получить?
- Сообщения: 91
- Зарегистрирован: Сб авг 11, 2012 22:31:57
Простите за глупый вопрос: но чем на языке отличается == и != ?
И какой ответ должен быть уже после CMD1?
p.s. с выводом значений не получается(вылазят кракозябры).
После CMD0 получаю как надо 0x01
И какой ответ должен быть уже после CMD1?
p.s. с выводом значений не получается(вылазят кракозябры).
После CMD0 получаю как надо 0x01


