Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Problem z obsługą karty SD 32MB pod Atmega 32

mwet 20 Paź 2010 14:40 3484 6
  • #1 20 Paź 2010 14:40
    mwet
    Poziom 9  

    Wykonałem termometr, który ma rejestrować wyniki z pomiaru temperatury na karcie SD w pliku TXT. Wzorowałem się na projekcie rejestratora pogodowego wykonanego przez kolegę Duch_a. Napisałem, krótki program na podstawie w/w projektu, który ma utworzyć plik na karcie i zapisać w nim krótki tekst. Niestety w wyniku działania programu plik nie zostaje utworzony na karcie. Jeżeli utworzę sam plik na PC i próbuję zapisać coś do niego przez mój program to po przełożeniu karty ponownie do PC otrzymuję informację o uszkodzonym pliku.
    Program prawidłowo rozpoznaję rozmiar karty i ilość wolnego miejsca. Format karty FAT16. W załączniku zamieściłem schemat połączeń.




    Code:
    $regfile = "m32def.dat"
    
    $include "Config_MMC.bas"                                   'Konfiguracja karty SD
    $include "Config_AVR-DOS.BAS"
    $crystal = 8000000
    $hwstack = 128
    $swstack = 128
    $framesize = 128
    $baud = 9600



    'AVR-DOS config
                                   'Biblioteka AVR-DOS


    'MMC adapter pin config    /atmega32/  , hardware SPI
    'DATA3 -> PORTB.4
    'DI    -> PORTB.5
    'DATA0 -> PORTB.6                                             'piny do których podpięte jest karta SD
    'CLK   -> PORTB.7

    Config Lcd = 20 * 4
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Disconnect , Prescale = 1
    Config Clock = Soft
    Config Porta.0 = Output
    Config Porta.1 = Output
    Config Porta.2 = Output

    Dim A As String * 5
    Dim Errorcode As Byte
    Dim Blad_sd As Bit

    Led1 Alias Porta.0
    Led2 Alias Porta.1
    Led3 Alias Porta.2

    Set Porta.0
    Set Porta.1
    Set Porta.2


    Time$ = "12:00:00"
    Date$ = "01.01.09"
    Cursor Off
    Cls
    Enable Interrupts
    Wait 1
    A = "tekst"


       Gbdriveerror = Driveinit()
       If Gbdriveerror = 0 Then
          Errorcode = Initfilesystem(1)
          Locate 2 , 1
          Lcd Errorcode
          If Errorcode <> 0 Then
          Blad_sd = 1
       Else
          Locate 1 , 1
          Lcd "Zapis"
          Wait 1
          Open "testtest.txt" For Output As #2




          Write #2 , A
          Flush #2
          Close #2
          Locate 1 , 1
          Lcd "Koniec zapisu"
       End If
       Else
          Locate 2 , 1
          Lcd "blad"
       End If
       Wait 1

       Cls
       Do
          Locate 1 , 1
          Lcd Disksize()
          Locate 2 , 1
          Lcd Diskfree()
          Locate 3 , 1
          Lcd Date$
          Locate 4 , 1
          Lcd Time$
       Loop



    Config mmc

    Code:
    '-------------------------------------------------------------------------------
    
    '                         Config_MMC.BAS
    '               Config File for MMC Flash Cards Driver
    '        (c) 2003-2005 , MCS Electronics / Vögel Franz Josef
    '-------------------------------------------------------------------------------
    ' Place MMC.LIB version 5.6 in the LIB-Path of BASCOM-AVR installation
    '
    'Connection as following
    'MMC    M128/M103           M32
    '1      MMC_CS PORTB.0      MMC_CS PORTB.4
    '2      MOSI PORTB.2        MOSI PORTB.5
    '3      GND                 GND
    '4      +3.3V               +3.3V
    '5      CLOCK PORTB.1       CLOCK PORTB.7
    '6      GND                 GND
    '7      MISO, PORTB.3       MISO, PORTB.6

    ' you can vary MMC_CS on HW-SPI and all pins on SOFT-SPI, check settings
    ' ========== Start of user definable range =====================================

    ' you can use HW-SPI of the AVR (recommended) or a driver build in Soft-SPI, if
    ' the HW-SPI of the AVR is occupied by an other SPI-Device with different settings

    ' Declare here you SPI-Mode
    ' using HW-SPI:     cMMC_Soft = 0
    ' not using HW_SPI: cMMC_Soft = 1

    Const Cmmc_soft = 0

    #if Cmmc_soft = 0

    ' --------- Start of Section for HW-SPI ----------------------------------------


       ' define Chip-Select Pin
       Config Pinb.4 = Output                                   ' define here Pin for CS of MMC/SD Card
       Mmc_cs Alias Portb.4
       Set Mmc_cs

       ' Define here SS Pin of HW-SPI of the CPU (f.e. Pinb.0 on M128)
       'Config Pinb.4 = Output                                   ' define here Pin of SPI SS
       'Spi_ss Alias Portb.4
       'Set Spi_ss                                               ' Set SPI-SS to Output and High por Proper work of
                                                      ' SPI as Master

       ' HW-SPI is configured to highest Speed
       Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1
       Spsr = 1                                                 ' Double speed on ATMega128 default = commented changed by author
       Spiinit                                                  ' Init SPI

    ' --------- End of Section for HW-SPI ------------------------------------------

    #else                                                       ' Config here SPI pins, if not using HW SPI

    ' --------- Start of Section for Soft-SPI --------------------------------------

       ' Chip Select Pin  => Pin 1 of MMC/SD
       Config Pinb.4 = Output
       Mmc_cs Alias Portb.4
       Set Mmc_cs

       ' MOSI - Pin DI => Pin 2 of MMC/SD
       Config Pinb.5 = Output
       Set Pinb.5
       Mmc_portmosi Alias Portb
       Bmmc_mosi Alias 2

       ' MISO - Pin  D0 => Pin 7 of MMC/SD
       Config Pinb.6 = Input
       Mmc_portmiso Alias Pinb
       Bmmc_miso Alias 3

       ' SCK - Pin CLK  => Pin 1 of MMC/SD
       Config Pinb.1 = Output
       Set Pinb.7
       Mmc_portsck Alias Portb
       Bmmc_sck Alias 1

    ' --------- End of Section for Soft-SPI ----------------------------------------

    #endif

    ' ========== End of user definable range =======================================


    ' Error
    Const Cperrdrivereset = 225                                 ' Error response Byte at Reset command
    Const Cperrdriveinit = 226                                  ' Error response Byte at Init Command
    Const Cperrdrivereadcommand = 227                           ' Error response Byte at Read Command
    Const Cperrdrivewritecommand = 228                          ' Error response Byte at Write Command
    Const Cperrdrivereadresponse = 229                          ' No Data response Byte from MMC at Read
    Const Cperrdrivewriteresponse = 230                         ' No Data response Byte from MMC at Write
    Const Cperrdrive = 231
    Const Cperrdrivenotsupported = 232                          ' return code for DriveGetIdentity, not supported yet

    Waitms 1                                                    ' Wait some time before initialising MMC/SD
    Dim Gbdriveerror As Byte                                    ' General Driver Error register
    Dim Gbdriveerrorreg As Byte                                 ' Driver load Error-Register of HD in case of error
    Dim Gbdrivestatusreg As Byte                                ' Driver load Status-Register of HD on case of error
    Dim Gbdrivedebug As Byte
    $lib "MMC.LIB"                                              ' link driver library
    $external _mmc
    Gbdriveerror = Driveinit()                                  ' Init MMC/SD Card

    0 6
  • #2 23 Paź 2010 09:34
    darres1
    Poziom 12  

    Witam,
    Należy zastosować odpowiedni tryb otwarcia pliku do zapisu:

    INPUT plik będzie otwarty tylko do odczytu,
    OUTPUT plik będzie otwarty tylko do zapisu,
    APPEND plik zostanie otwarty dla operacji dopisywania danych na końcu pliku,
    BINARY plik zostanie otwarty w trybie w którym można odczytywać i zapisywać dane binarne.

    w tym przypadku "APPEND"

    Code:

          Open "testtest.txt" For Append As #2
          Write #2 , A
          Flush #2
          Close #2



    Informacja z: "BASCOM AVR Help by Zbigniew Gibek" w wersji PDF,
    w załączniku

    Moderowany przez _Robak_:

    Na prośbę autora pliku kasuję załącznik.

    0
  • #3 23 Paź 2010 11:18
    mwet
    Poziom 9  

    Kolego Darres1 zastosowałem polecenie Append aby dane były zapisywane na końcu pliku. Gdy utworzę plik ręcznie z jednym znakiem w nim to dane są zapisywane. Niestety po kilkunastu zapisach program przestaje działać, a po próbie odczytania pliku w PC otrzymuję informację o uszkodzonym pliku. Jeśli kartę wyjmę po kilku zapisach wszystko jest OK.


    Code:
    $regfile = "m32def.dat"
    
    $crystal = 8000000
    $include "Config_AVR-DOS.BAS"
    $include "Config_MMC.bas"
    $lib "MMC.LIB"
    $external _mmc

    Declare Sub Zapis

    Config Pinb.0 = Input
    Config Pinb.1 = Input
    Config Pinb.2 = Input
    Config Pinb.3 = Input
    Config Porta.0 = Output
    Config Porta.1 = Output
    Config Porta.2 = Output
    Config 1wire = Portd.7
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Lcd = 20 * 4
    Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Disconnect , Prescale = 1
    Config Clock = Soft , Gosub = Sectic
    Config Date = Dmy , Separator = /


    Dim Temp1_lcd As String * 6
    Dim Tempmin_lcd As String * 6
    Dim Tempmax_lcd As String * 6
    Dim Flaga_zapisz As Bit
    Dim Flaga_menu As Bit
    Dim Flaga_1w As Bit
    Dim Blad_sd As Bit
    Dim Dsid1(8) As Byte
    Dim Czujnik As Byte
    Dim Errorcode As Byte
    Dim Temp1 As Integer
    Dim Tempmin As Integer
    Dim Tempmax As Integer

    Deflcdchar 1 , 12 , 18 , 18 , 12 , 32 , 32 , 32 , 32        ' Stopnie
    Deflcdchar 2 , 32 , 7 , 15 , 31 , 31 , 31 , 31 , 31         ' karta

    S1 Alias Pinb.0
    S2 Alias Pinb.1
    S3 Alias Pinb.2
    S4 Alias Pinb.3
    Led1 Alias Porta.0
    Led2 Alias Porta.1
    Led3 Alias Porta.2

    Set Porta.0
    Set Porta.1
    Set Porta.2
    Set Portb.0
    Set Portb.1
    Set Portb.2
    Set Portb.3




    Time$ = "01:32:31"
    Date$ = "23.10.10"
    Flaga_zapisz = 0
    Tempmin = 1000
    Tempmax = -1000

    Dsid1(1) = 1wsearchfirst()
    Cursor Off
    Cls
    Enable Interrupts
    Wait 4

    Do

    If S4 = 0 Then
       Waitms 25
          If S4 = 0 Then
             Flaga_menu = 1
             Cls
                Locate 1 , 6
                Lcd "MENU TIME    "
                Wait 2
                Do
                Locate 2 , 1
                Lcd "minuty:" ; _min ; "     "
                Locate 3 , 1
                Lcd "godziny:" ; _hour ; "     "
                Waitms 700
                If S3 = 0 Then
                   Waitms 25
                      If S3 = 0 Then
                         _sec = 0
                         Incr _min
                         If _min = 60 Then
                            _min = 0
                         End If
                      End If
                End If
                If S2 = 0 Then
                   Waitms 25
                      If S2 = 0 Then
                         _sec = 0
                         Incr _hour
                         If _hour = 24 Then
                            _hour = 0
                         End If
                      End If
                End If
                Loop Until S4 = 0
                Cls
                Locate 1 , 6
                Lcd "MENU DATE    "
                Wait 3
                Do
                Locate 2 , 1
                Lcd "dzien:" ; _day ; "     "
                Locate 3 , 1
                Lcd "miesiac:" ; _month ; "     "
                Locate 4 , 1
                Lcd "rok:" ; _year ; "     "
                Waitms 700
                If S3 = 0 Then
                   Waitms 25
                      If S3 = 0 Then
                         Incr _day
                         If _day = 31 Then
                            _day = 0
                         End If
                      End If
                End If
                If S2 = 0 Then
                   Waitms 25
                      If S2 = 0 Then
                         Incr _month
                         If _month = 12 Then
                            _month = 12
                         End If
                      End If
                End If
                If S1 = 0 Then
                   Waitms 25
                      If S1 = 0 Then
                         Incr _year
                         If _year = 20 Then
                            _year = 10
                         End If
                      End If
                End If

                Loop Until S4 = 0
                Cls
                Locate 1 , 6
                Lcd "EXIT MENU"
                Wait 2
                Flaga_menu = 0
                Cls
             End If
       End If
       If Flaga_zapisz = 1 Then
          Call Zapis
          Waitms 500
       End If

    Loop


    Sectic:

    Led1 = 0
             Czujnik = 1wirecount()
             1wreset
             1wwrite &H55
             1wverify Dsid1(1)
             1wwrite &HBE
             Temp1 = 1wread(2)
             1wreset
             1wwrite &HCC
             1wwrite &H44
             Temp1 = Temp1 * 10
             Temp1 = Temp1 \ 16
             If Temp1 < Tempmin Then
                Tempmin = Temp1
             End If
             If Temp1 > Tempmax Then
                Tempmax = Temp1
             End If
             Temp1_lcd = Str(temp1)
             Temp1_lcd = Format(temp1_lcd , "0.0")
             Tempmin_lcd = Str(tempmin)
             Tempmin_lcd = Format(tempmin_lcd , "0.0")
             Tempmax_lcd = Str(tempmax)
             Tempmax_lcd = Format(tempmax_lcd , "0.0")
             If S1 = 0 Then
                Tempmin = 1000
                Tempmax = -1000
             End If
             Led1 = 1

             If Flaga_menu = 0 Then
             Locate 1 , 1
             Lcd Time$ ; "   "
             Locate 1 , 12
             Lcd Date$
             Locate 2 , 1
             Lcd "Temp.out:" ; Temp1_lcd ; Chr(1) ; "   "
             Locate 3 , 1
             Lcd "Temp.min:" ; Tempmin_lcd ; Chr(1) ; "    "
             Locate 4 , 1
             Lcd "Temp.max:" ; Tempmax_lcd ; Chr(1) ; "    "
             End If
             'If _sec = 0 And _min = 0 Or _min = 10 Or _min = 20 Or _min = 30 Or _min = 40 Or _min = 50 Then
             If _sec = 0 Or _sec = 10 Or _sec = 20 Or _sec = 30 Or _sec = 40 Or _sec = 50 Then
                Flaga_zapisz = 1
             End If
    Return


    Zapis:

    If Flaga_menu = 0 Then
       Gbdriveerror = Driveinit()
          If Gbdriveerror = 0 Then
             Errorcode = Initfilesystem(1)
             If Errorcode <> 0 Then
                Blad_sd = 1
                Else
                   Led2 = 0
                   Waitms 25
                   Led2 = 1
                   [color=red]Open "a.txt" For Append As #2
                   Write #2 , Date$ , Time$ , Temp1_lcd
                   Flush #2
                   Close #2[/color]               Led3 = 0
                   Waitms 25
                   Led3 = 1
                   Flaga_zapisz = 0
             End If
             Else
             Locate 2 , 1
             Lcd "blad"
             Locate 1 , 1
             Lcd Errorcode ; "gb" ; Gbdriveerror
          End If
    End If
    Return
    [/code]

    0
  • #4 23 Paź 2010 13:41
    inventco.eu

    Poziom 29  

    Witam.
    Nie piszę w Bascomie już kawałek czasu.
    Ale może dobrym rozwiązaniem jest :
    1) otwierać plik i trzymać go otwartym aż do chwili kiedy chcemy kartę wyjąć (jakaś opcja w menu typu "wyjęcie karty") ?
    2) może kolejność CLOSE i FLUSH powinna być na odwrót (to tylko moje gdybanie bo nie wiem czy da się tak) bo może przepełnia się jakiś stos ...
    3) dobrym pomysłem byłoby aby program sprawdzał czy jest plik na karcie i w razie gdy pliku nie ma tworzył plik nowy (a nie otwierał w trybie append). Dopiero gdy po teście wyjdzie, że plik jest to wtedy otwierać plik z opcją append.


    Nie wiem czy to coś pomoże ale miałem podobne kłopoty w C. Rozwiązaniem okazał się punkt 1.

    Pozdrawiam
    Marek

    0
  • #5 23 Paź 2010 13:56
    mwet
    Poziom 9  

    Inventco.eu sprawdzę to dopiero wieczorem. Prędzej napisałem, krótki program, który zapisuje na kartę zmienną o stałej wartości. Okazuję się, że program prawidłowo zapisuje zmienną na karcie tylko 124 razy, a później "wykłada sie". Powtarzalność zawsze jest taka sama.

    Code:
    Temp1 = 0
    

    Do
       Incr Temp1
       Locate 1 , 1
       Lcd Temp1 ; "   "
       Gbdriveerror = Driveinit()
          If Gbdriveerror = 0 Then
             Errorcode = Initfilesystem(1)
             If Errorcode <> 0 Then
                Blad_sd = 1
                Else
                   Open "a.txt" For Append As #2
                   Write #2 , Temp1
                   Flush #2
                   Close #2
                   Led3 = 0
                   Waitms 25
                   Led3 = 1
                   Flaga_zapisz = 0
             End If
             Else
             Locate 2 , 1
             Lcd "blad"
             Locate 1 , 1
             Lcd Errorcode ; "gb"
             End If
             Wait 1

    Loop

    0
  • #7 23 Paź 2010 23:14
    mwet
    Poziom 9  

    Dziękuję wszystkim za pomoc i poświęcony czas. Program pracuje już poprawnie. Przyczyną kłopotów okazało się formatowanie karty. Dopiero po użyciu programu SDFormatter 2.0 jest wszystko ok. Tym samym zamykam temat.

    0
  Szukaj w 5mln produktów