Witam,
Od 3 dni próbuję skomunikować się przy pomocy AVR z kartami sd/mmc, jak narazie bez skutku.
Próbowałem zastosować biblioteki:
http://www.roland-riegel.de/sd-reader/index.html
http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html
W obu przypadkach stosowałem się do schematu podłączenia karty z pierwszej biblioteki:
Usuwając jedynie obwody podłączone do PC4 i PC5 (sprawdzanie czy karta wsunięta do czytnika). Autor pierwszej biblioteki przewidział taką opcje i opisał co trzeba zmienić w pliku konfiguracyjnym.
Karta zasilana zasilaczem stabilizowanym z 3.3V, uC z 5V, podłączenie linii wejściowych karty poprzez dzielniki napięcia.
Układ zmontowałem na płytce uniwersalnej, w pierwszej wersji karta na osobnej płytce, połączonej z płytka uC taśmą 10cm, w drugiej wersji gniazdo wlutowane bezpośrednio obok uC (najdłuższe połączenie od karty do uC ma 4cm).
Połączenia wykonane poprawnie, wielokrotnie sprawdzałem poziomy napięć i oporności.
Jako że używam laptopa, nie mam coma, ani stosownej przejściówki, stąd do debuggowania używam LCD 2x16.
W tym celu usunąłem z przykładowych implementacji komunikacje USART, a dodałem biblioteke obsługi LCD, ograniczyłem komunikaty do niezbędnego minimum.
uC to AtMega 32 / AtMega16 / AtMega644 wszystkie z kwarcem 16MHz.
Testuje na kartach SD 16 MB oraz 2GB (2 sztuki różnych producentów) oraz 3 różnych kartach MMC 32 MB.
Niestety, jak do tej pory nie udało mi się nic sensownego osiągnąć.
Druga biblioteka każdorazowo nie potrafi zainicjalizować połączenia z kartą.
Pierwsza, tu bywa różnie. W przykładowej realizacji inicjalizacja wywoływana jest w nieskończonej pętli, wykorzystałem to by sprawdzić czy układ reaguje na włożenie karty. Reaguje, gdy karta jest włożona inicjalizacja zachodzi, gdy nie jest nie. Przy czym zdarzają się pomyłki kiedy karty nie ma w czytniku a inicjalizacja podobno zachodzi... (jakieś 5-10 % przypadków). Próba oczytania partycji (funkcja biblioteki) zawsze kończy się porażka, natomiast próba odczytania danych w trybie raw (lub zapisu) zawsze kończy się sukcesem (funkcja zwraca 1) nawet gdy w podstawce nie ma karty...
By nieco rozjaśnić sytuacje, postanowiłem cyklicznie 'czytać' kolejno po 16 bajtów danych z przesunięciem ofsetu o 8 tak by czytać te same 8 bajtów dwukrotnie i zobaczyć czy wartości będą się zmieniać. Dane wyświetlam hexadecymalnie na LCD. Co jest zaskakujące, nie zmieniaja się, czytanie działa tak jakby rzeczywiście odczytywało takie wartości z karty gdyż za każdym razem są to te same dane, przy czym, odczytywane wartości są te same niezależnie od karty (poza 2 z 3 kart MMC dla których odczytywane są zera). Problem w tym że nigdzie na kartach nie ma takich ciągów danych, sprawdzałem karty winhexem.
Co ciekawe, gdy jedną karte w całości nadpisałem zerami, uC dalej odczytywał ten sam ciąg.
Gdy czytam dane gdy karta jest wyjęta z podstawki wartości wyglądają na pseudolosowe.
Przy kompilacji korzystam z dostarczonego z bibliotekami MakeFile.
Za kilka minut wrzucę moje wersje main.c
Szczerze mówiąc, wymiękam.
Drugi problem, polega na tym że gdy układ czytnika jest podłączony do uC, nie mogę programować go poprzez ISP. AVR Dude wyrzuca bład:
(jest połączenie z programatorem). Programuję przy użyciu programatora AVRDoper, zgodny z STK500v2 (pod USB). Problem stał się nad wyraz dokuczliwy kiedy wlutowałem podstawkę i dzielniki na stałe w płytkę z uC.
Czuję, że bez Waszej pomocy nie dam rady znaleźć i rozwiązać problemów przez które nie mogę dokończyć projektu.
Rafał.
KOD: (od notorycznego sprawdzania różnych koncepcji zrobił mi się spory bałagan w kodzie).
Od 3 dni próbuję skomunikować się przy pomocy AVR z kartami sd/mmc, jak narazie bez skutku.
Próbowałem zastosować biblioteki:
http://www.roland-riegel.de/sd-reader/index.html
http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html
W obu przypadkach stosowałem się do schematu podłączenia karty z pierwszej biblioteki:
Usuwając jedynie obwody podłączone do PC4 i PC5 (sprawdzanie czy karta wsunięta do czytnika). Autor pierwszej biblioteki przewidział taką opcje i opisał co trzeba zmienić w pliku konfiguracyjnym.
Karta zasilana zasilaczem stabilizowanym z 3.3V, uC z 5V, podłączenie linii wejściowych karty poprzez dzielniki napięcia.
Układ zmontowałem na płytce uniwersalnej, w pierwszej wersji karta na osobnej płytce, połączonej z płytka uC taśmą 10cm, w drugiej wersji gniazdo wlutowane bezpośrednio obok uC (najdłuższe połączenie od karty do uC ma 4cm).
Połączenia wykonane poprawnie, wielokrotnie sprawdzałem poziomy napięć i oporności.
Jako że używam laptopa, nie mam coma, ani stosownej przejściówki, stąd do debuggowania używam LCD 2x16.
W tym celu usunąłem z przykładowych implementacji komunikacje USART, a dodałem biblioteke obsługi LCD, ograniczyłem komunikaty do niezbędnego minimum.
uC to AtMega 32 / AtMega16 / AtMega644 wszystkie z kwarcem 16MHz.
Testuje na kartach SD 16 MB oraz 2GB (2 sztuki różnych producentów) oraz 3 różnych kartach MMC 32 MB.
Niestety, jak do tej pory nie udało mi się nic sensownego osiągnąć.
Druga biblioteka każdorazowo nie potrafi zainicjalizować połączenia z kartą.
Pierwsza, tu bywa różnie. W przykładowej realizacji inicjalizacja wywoływana jest w nieskończonej pętli, wykorzystałem to by sprawdzić czy układ reaguje na włożenie karty. Reaguje, gdy karta jest włożona inicjalizacja zachodzi, gdy nie jest nie. Przy czym zdarzają się pomyłki kiedy karty nie ma w czytniku a inicjalizacja podobno zachodzi... (jakieś 5-10 % przypadków). Próba oczytania partycji (funkcja biblioteki) zawsze kończy się porażka, natomiast próba odczytania danych w trybie raw (lub zapisu) zawsze kończy się sukcesem (funkcja zwraca 1) nawet gdy w podstawce nie ma karty...
By nieco rozjaśnić sytuacje, postanowiłem cyklicznie 'czytać' kolejno po 16 bajtów danych z przesunięciem ofsetu o 8 tak by czytać te same 8 bajtów dwukrotnie i zobaczyć czy wartości będą się zmieniać. Dane wyświetlam hexadecymalnie na LCD. Co jest zaskakujące, nie zmieniaja się, czytanie działa tak jakby rzeczywiście odczytywało takie wartości z karty gdyż za każdym razem są to te same dane, przy czym, odczytywane wartości są te same niezależnie od karty (poza 2 z 3 kart MMC dla których odczytywane są zera). Problem w tym że nigdzie na kartach nie ma takich ciągów danych, sprawdzałem karty winhexem.
Co ciekawe, gdy jedną karte w całości nadpisałem zerami, uC dalej odczytywał ten sam ciąg.
Gdy czytam dane gdy karta jest wyjęta z podstawki wartości wyglądają na pseudolosowe.
Przy kompilacji korzystam z dostarczonego z bibliotekami MakeFile.
Za kilka minut wrzucę moje wersje main.c
Szczerze mówiąc, wymiękam.
Drugi problem, polega na tym że gdy układ czytnika jest podłączony do uC, nie mogę programować go poprzez ISP. AVR Dude wyrzuca bład:
avrdude.exe: stk500v2_command(): command failed
avrdude.exe: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.
avrdude.exe done. Thank you.(jest połączenie z programatorem). Programuję przy użyciu programatora AVRDoper, zgodny z STK500v2 (pod USB). Problem stał się nad wyraz dokuczliwy kiedy wlutowałem podstawkę i dzielniki na stałe w płytkę z uC.
Czuję, że bez Waszej pomocy nie dam rady znaleźć i rozwiązać problemów przez które nie mogę dokończyć projektu.
Rafał.
KOD: (od notorycznego sprawdzania różnych koncepcji zrobił mi się spory bałagan w kodzie).
//#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include "fat.h"
#include "fat_config.h"
#include "partition.h"
#include "sd_raw.h"
#include "sd_raw_config.h"
#define DEBUG 1
//deklaracje dla AtMega644 (nie przewidziane w oryginalnej bibliotece)
#define configure_pin_mosi() DDRB |= (1 << DDB5)
#define configure_pin_sck() DDRB |= (1 << DDB7)
#define configure_pin_ss() DDRB |= (1 << DDB4)
#define configure_pin_miso() DDRB &= ~(1 << DDB6)
#define select_card() PORTB &= ~(1 << PORTB4)
#define unselect_card() PORTB |= (1 << PORTB4)
//sterownik wyswietlacza
#include "HD44780.h"
void waw(char * a){
LCD_Clear();
LCD_WriteText(a);
_delay_ms(500);
}
void wawt(char * a, unsigned int i){
LCD_Clear();
LCD_WriteText(a);
_delay_ms(i);
}
void lcd_putc_hex(uint8_t b)
{ char a,c;
/* upper nibble */
if((b >> 4) < 0x0a)
a = ((b >> 4) + '0');
else
a = ((b >> 4) - 0x0a + 'a');
/* lower nibble */
if((b & 0x0f) < 0x0a)
c = ((b & 0x0f) + '0');
else
c = ((b & 0x0f) - 0x0a + 'a');
LCD_WriteData(a);
LCD_WriteData(c);
}
void lcd_putw_hex(uint16_t w)
{
lcd_putc_hex((uint8_t) (w >> 8));
lcd_putc_hex((uint8_t) (w & 0xff));
}
void lcd_putdw_hex(uint32_t dw)
{
lcd_putw_hex((uint16_t) (dw >> 16));
lcd_putw_hex((uint16_t) (dw & 0xffff));
}
int main(void)
{
LCD_Initalize();
LCD_Clear();
LCD_WriteText("test");
lcd_putc_hex(sd_raw_init());
_delay_ms(900);
lcd_putc_hex(sd_raw_available());
_delay_ms(900);
uint8_t buf[512];
unsigned int i;
unsigned int pos=0;
//set_sleep_mode(SLEEP_MODE_IDLE);
while(1)
{
for(i=0; i<512; i++) buf[i] &= 0x00;
if(!sd_raw_init())
{
waw("z");
}//else{waw("zdechlo");}
LCD_Clear();
if(sd_raw_read(pos, buf, 8)){
for(i=0; i<8; i++) lcd_putc_hex(buf[i]);
}else{ waw("n"); }
LCD_GoTo(0,1);
if(sd_raw_read(pos+4, buf, 8)){
for(i=0; i<8; i++) lcd_putc_hex(buf[i]);
}else{ waw("n"); }
_delay_ms(900);
_delay_ms(900);
wawt("s", 500);
pos+=8;
}
return 0;
}
