Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Работа с SD картой без AVR-DOS


Работа с SD картой без AVR-DOS

Сообщений 1 страница 30 из 45

1

Доброго Здоровья!

Кто нибудь работал с SD картой на уровне FAT (только чтение) без AVR-DOS?

Кто нибудь пользовал SD карту в полноценном 4-х битном режиме?

0

2

Неужели с SD картой никто не работал?

0

3

Присоединяюсь к вопросу.

0

4

Может это подойдет? http://mcselec.com/index2.php?option=co … m&f=18

0

5

Пётр написал(а):

Может это подойдет? http://mcselec.com/index2.php?option=co … m&f=18

Там так всё запутано, сам чёртик ногу сломает.

0

6

Работу с SD нельзя назвать слишком простой, и отсутствие структур в баскоме (странно что их нет) еще больше запутывают код.

0

7

Пётр написал(а):

Работу с SD нельзя назвать слишком простой, и отсутствие структур в баскоме (странно что их нет) еще больше запутывают код.

Да уж, прям в десятку.

0

8

Есть отличная библиотека, написана японцем, правда на СИ.

0

9

f

sasha_1973 написал(а):

Пётр написал(а):

    Работу с SD нельзя назвать слишком простой, и отсутствие структур в баскоме (странно что их нет) еще больше запутывают код.

Да уж, прям в десятку.

А что вы хотели, гибкая, файловая структура, которая требует определенных мощностей МК и при этом (кстати говоря) нет поддержки больших объёмов (что отбивает охоту довести всё разбирательство до конца (благо есть и более простые решения этой проблемы).

зы: тема уже не раз обсуждалась, ничего так и не поменялось.

Отредактировано RDW (2015-04-01 20:25:00)

0

10

Вот именно, что ничего не меняется!

Все ждут, что кто-то сделает и выложит.

0

11

Я не жду (терпеть не могу ковыряться в чужом).

А ты этого ждешь.)

Сядь, разберись и тогда поймешь все проблемы/причины сложившейся ситуации.

Отредактировано RDW (2015-04-01 21:36:09)

0

12

RDW написал(а):

А ты этого ждешь.)

Да уж, смешно, особенно жду, когда ты что-нибудь сделаешь для форума!

Любитель демагогии!

0

13

каждому - по потребностям
если надо именно Работать с FAT на разных картах, а не "поиграться" - то надо нормально делать
а если для себя логи залить или что-то читать - проще посекторно обращаться.
Как уже писали: тема разжевана. Бери да пользуйся

+2

14

Действительно, тема дубль. На форуме уже была
Работа с SD простая. Сложно работать с FAT потому что это FAT 8-) . Когда я пытался вникнуть, понял, что в итоге выйду к библиотеке AVR DOS. В итоге использовал SD как микросхему памяти. Записывал звук конкретно по адресам секторов, так и считывал. Плюс в том, что памяти минимум.

0

15

Плеер WAV, моно, 8 бит , работает с FAT16. Битрэйт любой, проверял на всех, что конвертер смог сделать. Воспроизводим на лету, по сему понятно, что записываем на только отформатированную карточку.  Проверялось на картах SD 1G "noname", SDC 2G "Kingston", SDHC/4 4G "Kingston". других нет. Код писался параллельно впитывания инфы из нета, посему он для ознакомления и развития. Если кто будет развивать тему, просьба выкладывать. Спикер- от обычного проводного телефона, пдключён на оба канала ШИМ, так что играет не тише некоторых смартфонов. Реализовать стерео тоже не проблема, но идея создать говорилку.

Код:
'=====================================================================
'  WAV плер , моно, 8 бит , работает с FAT16. Битрэйт любой
'   автор -  kip96
' звук на основе ШИМ    Pwm0
'  ====================================================================
' MMC2 - инициализация
'ММС3- работа с FAT16
'MMC4- МЕНЯЕМ РЕЖИМ SPI    , ДОБАВИЛИ МНОГОБЛОЧНОЕ ЧТЕНИЕ
'MMC5. поддержка карт SDSC/SD

$regfile = "m328pdef.dat"                                   'указать нужный
$crystal = 16000000
$baud = 38400                                               'указать нужный
$hwstack = 100
$swstack = 100
$framesize = 200
$loadersize = 1024

Print Version(3) ; Version(1)

Dim A As Byte

 Config Timer0 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down , Prescale = 1
Config Timer1 = Timer , Prescale = 1                        '1имп =62,9nS

Pwm0a = 125
Pwm0b = 125

Dim Speed As Word

'переменные ммс
Dim Init_err As Byte , Ccs As Bit , Sd As Bit , Fl_err As Bit
Dim Fl_data_is As Bit
Dim Fl As Bit , Cont_err As Byte
Dim Dat As Byte , N As Byte
Dim Resp As Byte
Dim I As Word
Dim Addr As Dword
Dim Ad(4) As Byte At Addr Overlay
Dim D(8) As Byte
Dim B(8) As Byte
Dim Sektor As Word
Dim G As Dword

'переменные FAT16
Dim Boot_sector As Dword
    Dim Bs(4)as Byte At Boot_sector Overlay
Dim Num_sector As Word                                      'размер секторов в байтах
Dim Num_claster As Byte                                     'количество секторов на кластер
Dim Tab_fat As Word                                         'Начало таблицы FAT. Через сколько секторов от Boot sector.
    Dim Tf(2) As Byte At Tab_fat Overlay
Dim Num_fat As Byte                                         'количество копий fat
                                       '                                                  флаг наличия данных
 Dim On_play As Bit                                         'флагжелания воспроизводить звук
Dim Size_tab As Word                                        'размер таблицы
    Dim St(2) As Byte At Size_tab Overlay
Dim Fat As Word                                             'адрес первой таблицы FAT
Dim Catalog As Dword                                        ' адрес каталога
Dim Adr_fail As Dword                                       ' адрес файла.
Dim Fail As Word
   Dim Fa(2) As Byte At Fail Overlay
Dim Size_fail As Dword                                      ' размер файла
         Dim Sf(4) As Byte At Size_fail Overlay
Dim End_fail As Dword
Dim Blok As Word                                            ' определение блоков по 32 байта
Dim Size_catalog as word                                            'размер каталога(как правило 512 байт, по сему можно и не считывать.
    dim sc(2) as Byte at size_catalog overlay
Dim Claster As Word
Dim Cl(2) As Byte At Claster Overlay
Dim Play As Byte                                            ' номер файла, который надо воспроизвести
Dim Sel As Byte
Dim Gword As Dword
'переменные  FAT
dim bit_rait as Word
     dim br(2) as Byte at bit_rait overlay
'Declarations
Declare Sub Minit
Declare Sub Readmmc
Declare Sub Readsd( , Byval Answer As Byte , Byval N As Byte)
Config Portb.3 = Output
Config Portb.5 = Output
Config Portb.2 = Output : Cs Alias Portb.2
Config Pinb.4 = Input


  Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Spiin = 255 , Clockrate = 4 , Noss = 1
   Spiinit
 Print "WelСom"
 Waitms 100
 'do
 Minit
 If Fl_err = 0 Then
  Print "Ok!"
        If Sd = 0 Then
              If Ccs = 0 Then Print "Карта SDSC " Else Print " Карта SDHC "
        Else
        Print "Карта SD "
        End If
  Else
  Print " Карта не обнаружена!"
  End
  End If
    Addr = 0
    Gword = 1
  Readmmc
   'if b(1) = 6 then Print" FAT 16 "
   print " адрес Boot_sector ";Boot_sector
   Addr = Boot_sector

  Readmmc
  print " Tab_fat";Tab_fat
  Fat = Boot_sector + Tab_fat
   print "адрес FAT ";fat
  Catalog = Num_fat * Size_tab
  Catalog = Catalog + Fat
   print "Каталог "; catalog

  Addr = Catalog
  gword=size_catalog
  Readmmc

    Do
  Input " Введите номер файла- " , Play

    Addr = Catalog
    Gword = 1
  Readmmc

Addr = Adr_fail
     Gword = Size_fail
    Readmmc
  Loop

 End






 '======= SUB ROUTINES AND FUNCTIONS =======
'*** Инициализация карты MMC ***
Sub Minit
Cont_err = 0
'Do
 Set Cs
D(1) = &HFF : D(2) = &HFF : D(3) = &HFF : D(4) = &HFF : D(5) = &HFF : D(6) = &HFF : D(7) = &HFF : D(8) = &HFF       'инициализация,  отправляем FF
 Spiout D(1) , 8
  Print " Cmd0"
  Waitms 1
 Reset Cs
 Cmd0:                                                      ' команда 0 сброс карты 40,00,00,00,00,95
  D(1) = &H40                                               '40
  D(2) = 0
  D(3) = 0
  D(4) = 0
  D(5) = 0
  D(6) = &H95
 ' D(7) =&hff
  Call Readsd(1 , 7)
If Fl_err = 1 Then Return


If A = 201 Then Init_err.0 = 1                              ' бит 0 -карты нет
  Print " Cmd1" ;
  Cmd1:
 D(1) = &HFF
D(2) = &H41                                                 ' команда 1 перевод карты в режим spi 41,00,00,00,00,FF
D(3) = 0
  D(4) = 0
  D(5) = 0
  D(6) = 0
For A = 1 To 200                                            ' ждем отклик 00 если всё нормально в противном случае повторяем
 Spiout D(1) , 8                                            ' принимаем отклик (01)
Spiin Resp , 1
 Delay
'Print Hex(resp) ; " " ;
If Resp = &H05 Then Goto Cmd_8
If Resp = &H00 Then
 Ccs = 0                                                    ' карта SD
   Print "OK"
       Return
 End If
  Next


 Cmd_8:
 Print " NO"
    Print " Smd8"
  'D(1) = &HFF
  D(2) = &H48
  D(3) = 0
  D(4) = 0
  D(5) = &H01
  D(6) = &HAA
  D(7) = &H87                                               '
 Call Readsd(&Haa , 7)


Print "ACMD-41"
   Print "CMD 55 "
 Acmd41:

    D(2) = &H77                                             ' 55 OR 64
    D(5) = 0
    D(6) = 0
     D(7) = 0
    ' Call Readsd(1 , 8)
    For A = 1 To 40
  Spiout D(1) , 8
   Spiin Resp , 1
     Print Hex(resp) ; " ";
  If Resp = &H01 Then Exit For
  Next

   D(1) = &H69
   D(2) = &H40
    For A = 1 To 40
  Spiout D(1) , 7
 Spiin Resp , 1
  If Resp = &H00 Then
     Init_err.2 = 0
 Exit For
 Else

 Init_err.2 = 1
 End If
Next
   Print "CMD 41 "
 Cmd_58:
 D(1) = &HFF
  D(2) = &H7A
  D(3) = 0
  D(4) = 0
  D(5) = 0
  D(6) = 0
  D(7) = &HFF
  Call Readsd(0 , 7)                                        '



 Spiin B(1) , 4
'Print Hex(b(1)) ; Hex(b(2)) ; Hex(b(3)) ; Hex(b(4))
If B(1) = &HC0 Then Ccs = 1 Else Ccs = 0                    'PRINT "Карта SDHC. Считывание поблочное"

 Set Cs
End Sub

 Sub Readmmc
 If Ccs = 0 Then Shift Addr , Left , 9                      'если карта SD , адрес указываем в байтах, если SDHC в блоках
 G = 0
   Reset Cs
    Print
  Print "Количество считываемых блоков " ; Gword
Print "адрес " ; Addr
  D(1) = &HFF
  D(2) = &H52                                               ' команда многоблочного чтения
  D(3) = Ad(4)
  D(4) = Ad(3)
  D(5) = Ad(2)
  D(6) = Ad(1)
  D(7) = &HFF
   Call Readsd(0 , 7)
If Ccs = 0 Then Shift Addr , Right , 9
    Print " Блок данных"

While G <> Gword
Incr G

    For A = 1 To 200                                        '
  Spiin Resp , 1
    '  Print Hex(resp) ; " ";
If Resp = &HFE Then Exit For
   Next A

    For I = 0 To 511

      Spiin Resp , 1



        Select Case Addr
           Case 0:
                                   If I = &H1C2 Then B(1) = Resp                 ' Fat
                                   If I = &H1C6 Then Bs(1) = Resp                'Boot sector
                                   If I = &H1C7 Then Bs(2) = Resp
                                   If I = &H1C8 Then Bs(3) = Resp                '
                                   If I = &H1C9 Then Bs(4) = Resp

           Case Boot_sector:
                                   If I = 13 Then Num_claster = Resp             'количество секторов в кластер
                                   If I = 14 Then Tf(1) = Resp                   'начало таблицы FAT
                                   If I = 15 Then Tf(2) = Resp
                                   If I = 16 Then Num_fat = Resp                 'количество копий FAT
                                   if i=17 then sc(1)=resp   '
                                   if i=18 then sc(2)=resp    ' размер каталога в байтах(как правило 512)
                                   If I = 22 Then St(1) = Resp       'размер таблицы в секторах
                                   If I = 23 Then St(2) = Resp
                                    'print hex(resp);" ";
           Case Catalog
                                   Blok = I / 32                                 'номер блока в каталоге (блок состоит из 32 байт)
                                   A = I Mod 32                                  '  номер байта в блоке
                                   If A = 0 And Resp = 0 Then
                                    Exit While
                                    Elseif Play = 0 Then
                                      Fl_data_is = 1        'выставляем флаг если в начеле блока нет нулей и не хотим воспроизводить
                                      End If

                                       If Fl_data_is = 1 Or Blok = Play Then     ' считываем данные файлов в начале, либо заданный файл
                                         If A = 0 Then Print Blok ; " ";
                                         'If A = 0 Then Fa(1) = Resp              ' имя файла
                                         'If A = 1 Then Fa(2) = Resp
                                         If A < 12 Then Print Chr(resp);
                                         If A = 26 Then Cl(1) = Resp             ' кластер
                                         If A = 27 Then Cl(2) = Resp
                                         If A = 28 Then Sf(1) = Resp             'размер файла
                                         If A = 29 Then Sf(2) = Resp
                                         If A = 30 Then Sf(3) = Resp
                                         If A = 31 Then Sf(4) = Resp
                                         If A = 31 Then
                                         Print Blok ; ". " ; Chr(fa(1)) ; Chr(fa(2 )) ; " размер " ; Size_fail ; " байт"
                                          Adr_fail = Claster - 2
                                          Adr_fail = Adr_fail * Num_claster
                                          Adr_fail = Adr_fail + Catalog
                                          Adr_fail = Adr_fail + 32
                                           Shift Size_fail , Right , 9           ' переводим размер из байт в сектора
                                          End_fail = Adr_fail + Size_fail        ' определяем адрес конца файла
                                            Fl_data_is = 0

                                         End If
                                       End If
                Case Adr_fail :

                                           If On_play = 0 Then
                                            if g=1 then
                                              If I = 24 Then Br(1) = Resp
                                              If I = 25 Then Br(2) = Resp
                                              If I = 55 Then
                                              Set On_play
                                              Print "Битрэйт " ; Bit_rait

                                                Bit_rait = Bit_rait / 10
                                              Boot_sector = 1000000000 / Bit_rait
                                              Boot_sector = Boot_sector / 629
                                              Speed = Boot_sector
                                              Print "Speed =" ; Speed
                                              End If
                                            end if

                                       Else

                                             Do

                                              If Timer1 > speed Then                        'для 22000гц.
                                            'If Timer1 > 362 Then                       'для 44100гц
                                    '  Stop Timer0
                                              Timer1 = 0
                                         '     Start Timer0
                                              Exit Do
                                              End If
                                             Loop


                                                  Pwm0a = Resp
                                                  Pwm0b = Resp
                                       ' Else
                                                  ' If Resp = &H80 Then Set On_play

                                       End If
                                                             Sel = Ischarwaiting()
                  End Select

              Next I
                         If Sel = 1 Then
                            Sel = Waitkey()
                            Print Sel
                              Select Case Sel
                              Case 115 : Exit While
                               Case 46 :
                          '                           Exit For
                               Case 44 :
                           '                          Exit For
                               End Select
                     End If


   Spiin B(1) , 2                                           'приём " в воздух" CRC



Wend
  Print "БЛОК " ; Blok ; " " ; G
 Reset On_play
  Pwm0a = 125
  Pwm0b = 125
  D(2) = &H4C                                               ' stop  read
 Call Readsd(0 , 7)                                         '

   Set Cs

End Sub




Sub Readsd(byval Answer As Byte , Byval N As Byte)          '
 Reset Fl_err
  Spiout D(1) , N
    For A = 1 To 200                                        '
  Spiin Resp , 1
      Print Hex(resp) ; " ";
If Resp = Answer Then Exit For
  If A = 200 Then Set Fl_err
   Next

  End Sub

+5

16

Крайний вариант говорилки. SDHD или SD карты, воспроизведение по 2-м каналам раздельно, управление при помощи UART командой формата «$TFAIL» / Говорим($) на телефон(T) файл по имени FAIL/
Статья -на РадиоКоте
Исходники На яндекс диске

+4

17

kip
Спасибо!

0

18

а кто-нибудь пробовал сделать что-то похожее на wav-плеер на тини85, по расхожей схеме Чана http://elm-chan.org/works/sd8p/report.html ? или на Баскоме это не выгорит?

0

19

IDok написал(а):

Баскоме это не выгорит

"выгорит", только никто так до этого не дошел
всё зависит от целесообразности подходов
я так лично это направление и не развил, только сел вникать в файловую систему и забросил, ибо чем больше разбирался, тем больше понимал отсутствие смысла в этом (проще придумать более легкий способ, свою файловую систему), а поддерживать мощнейшие системы на слабом МК - можно (в какой-то мере), видел даже как бэйсик делали/пихали...это скорее "политика партии"

0

20

RDW
гм. а если прошивку kip-а, которая выложена выше, портировать на тини85? без дисплейчика, ессно

0

21

IDok написал(а):

а если прошивку kip-а, которая выложена выше, портировать на тини85?

А попробовать не судьба ? ;)
В "тиньку" влезет ?.. ;)
Даже "без дисплейчика", который память практически не жрет...

Отредактировано Nord (2017-04-02 20:05:02)

0

22

Nord написал(а):

А попробовать не судьба ?

э! так это мозгой шевелить надо! а мне пока нечем :(
да и схемку бы не мешало иметь, чтоб не размышлять куда какая нога. ну, будет время и тинька - наверное и попробую

0

23

IDok написал(а):

э! так это мозгой шевелить надо!

Предлагаю для начала поместить указанный вами код в Bascom, заменить в заголовке тип МК и попробовать скомпилировать...
Шевелений - минимум... ;)
Зато (уверен) - появятся вопросы... ;)

Код:
$hwstack = 100
$swstack = 100
$framesize = 200

Хотя бы вот это меня бы уже насторожило по поводу использования "тиньки"... ;)

Отредактировано Nord (2017-04-02 20:56:09)

0

24

поместил.
Error : 222   Line :   89    Illegal character [expected (, got '' [PORT]]  , in File : D:\Ðàçíîå\ØÈÌ\SD.bas
Error : 7     Line :   89    IF THEN expected  , in File : D:\Ðàçíîå\ØÈÌ\SD.bas
в
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Spiin = 255 , Clockrate = 4 , Noss = 1
я ж грю - мозгой шевелить надо :)

0

25

IDok написал(а):

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Spiin = 255 , Clockrate = 4 , Noss = 1я ж грю - мозгой шевелить надо

Выделенное - несовместимость "ног" у вашего и изначального МК.
Меняйте "ноги" или используйте SOFT...

0

26

не выйдет, вощем. практически вся строка в ошибках. и аппаратного SPI нету и всего остального и прочего. ну, ладно. еще кстати моему Баскому не нравится выражение "Interrupt = Off "...

0

27

IDok написал(а):

еще кстати моему Баскому не нравится выражение "Interrupt = Off "...

Выход подсказать ? ;)

0

28

написать Disable Interrapts? :)
спасиба, на стока моих знаниев хватило. но Баском тут же ехидно переспросил "а ты его включал разве, что б выключать теперь?" ну там все остальные параметры в этой строке не подходят. а подбирать их, не понимая что и куда - бесперспективняк

0

29

IDok написал(а):

написать Disable Interrapts?

А банально "поиграться" со строкой ? ;)
Удалить из нее "ругающиеся" места...

От эксперимента дом не развалится, если это не эксперимент со взрывчаткой... ;)

Как думаете, sasha_1973 сколько раз строчки в программе правил/переписывал, прежде чем выкладывать свои шедевры ?
Живой же ! И еще сто лет прожить ! ;)

0

30

да я вообще всю программу удалить могу!  :flag:
только для чего она мне такая, удаленная :)
главная проблема в том, что баскомлю я месяц наверное. и если вычурно мигать светодиодом я еще научился, то остальные слова из кода для меня как устав китайской армии - нутром чую, что надо бежать, а куда - не понятно :(
ну и тиньки живой нет. есть мертвая, но она устала

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Работа с SD картой без AVR-DOS