Подключаем внешнюю флеш-память SD-Card к МиниБоту

Материал из roboforum.ru Wiki
Версия от 06:34, 7 июля 2008; EdGull (обсуждение | вклад) (Новая: <source lang="vb"> $prog &HFF , &HE4 , &HD9 , &HFF ' generated. Take care that the chip supports all fuse bytes. $regfile = "m128DEF.dat" $crystal = 8000000 ...)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

<source lang="vb">

$prog &HFF , &HE4 , &HD9 , &HFF ' generated. Take care that the chip supports all fuse bytes. $regfile = "m128DEF.dat" $crystal = 8000000 $baud = 4800

'Нога отвечает за Вкл/Откл SD карты в SPI режиме Config Porte.2 = Output : Chip_select Alias Porte.2

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4

Dim Флаг As Bit Dim ФлагПроверкиЗаписи As Bit Dim ФлагДанныеЗаписаныВерно As Bit

Dim ПринятыйБайт As Byte Dim Sd_command(6) As Byte 'Ответ максимум состоит из 10 байт Dim Size_answer As Byte Dim Sd_answer(10) As Byte Dim Sd_data(512) As Byte

Dim Tmp_byt1 As Byte Dim Tmp_byt2 As Byte Dim Tmp_byt3 As Byte

Dim Count_wrd As Word

Dim Tmp_wrd1 As Word Dim Tmp_wrd2 As Word

Dim Sd_address As Long

Print "Старт программы"

Begin: 'Отключить SD карту Chip_select = 1 'Ответ максимум состоит из 1 байт Size_answer = 1 ФлагПроверкиЗаписи = 0 Sd_address = &H0

'Инициализация SPI у меги Spiinit

'Инициализация SPI у SD карты Gosub Init_sd

 Do
 'Очистить буфер для чтения/записи SD карты
 Gosub Clear_sd_buffer
 Sd_data(1) = 10
 Sd_data(2) = 20
 Sd_data(3) = 30
 Sd_data(4) = 40
 Sd_data(5) = 50
 Sd_data(6) = 60
 Sd_data(7) = 70
 Sd_data(8) = 80
 Sd_data(9) = 90
 Sd_data(10) = 100
 'Записать данные в SD карту
 Gosub Write_sd_data
 'Прочитать данные из SD карты
 Gosub Read_sd_data
 Sd_address = Sd_address + 512
 Loop Until Sd_address = 2048

End

'-------------------------------------------------------------------------------

Init_sd: 'Подпограмма инициализирует SPI у SD карты

Print "Инициализация SPI у SD карты"

'Переводим SD карту в SPI режим ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff)

'Включить SD карту Chip_select = 0

Print "Ресет" 'Послать команду ресет SD карты Sd_command(1) = &H40 Sd_command(2) = &H00 Sd_command(3) = &H00 Sd_command(4) = &H00 Sd_command(5) = &H00 Sd_command(6) = &H95 Gosub Send_sd_command

Print "Инициализация"

 Do
 'Послать команду инициализации SD карты
 Sd_command(1) = &H41
 Sd_command(2) = &H00
 Sd_command(3) = &H00
 Sd_command(4) = &H00
 Sd_command(5) = &H00
 Sd_command(6) = &H55
 Gosub Send_sd_command
 Waitms 100
 Loop Until Sd_answer(1) = 0

'Отключить SD карту Chip_select = 1

Print "Инициализация SPI у SD карты окончена" Return

Send_sd_command: 'Подпограмма посылает команду SD карте

ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(sd_command(1)) ПринятыйБайт = Spimove(sd_command(2)) ПринятыйБайт = Spimove(sd_command(3)) ПринятыйБайт = Spimove(sd_command(4)) ПринятыйБайт = Spimove(sd_command(5)) ПринятыйБайт = Spimove(sd_command(6))

'Получить ответ от SD карты Gosub Receive_sd_command

ПринятыйБайт = Spimove(ПринятыйБайт) Return

Receive_sd_command: 'Подпограмма получает ответ от SD карты

 Do
 ПринятыйБайт = Spimove(&Hff)
 Loop Until ПринятыйБайт <> &HFF

Tmp_byt1 = 0

 Do
 Incr Tmp_byt1
 Sd_answer(tmp_byt1) = ПринятыйБайт
 ПринятыйБайт = Spimove(&Hff)
 Loop Until ПринятыйБайт = &HFF Or Size_answer = Tmp_byt1

Print "Ответ SD карты" For Tmp_byt2 = 1 To Tmp_byt1

 Print "Байт №" ; Tmp_byt2 ; " = " ; Sd_answer(tmp_byt2)

Next Return

Clear_sd_buffer: 'Подпограмма очищяет буфер для чтения/записи SD карты

For Count_wrd = 1 To 512

 Sd_data(count_wrd) = 0

Next Return

Write_sd_data: 'Подпограмма записывает данные в SD карту по адресу Sd_address размером 512 байт 'данные берёт из Sd_data(512)

 Do
 Tmp_byt3 = 0
   Do
   Флаг = 0
   'Включить SD карту
   Chip_select = 0
   Print "Запись"
   Print "Записать блок данных (512 байт) по адресу " ; Hex(sd_address)
     Do
     Incr Tmp_byt3
     Print "Попытка записать данные №" ; Tmp_byt3
     'Послать команду записать блок данных по адресу (sd_address) в SD карту
     Sd_command(1) = &H58
     Tmp_wrd1 = Highw(sd_address)
     Tmp_wrd2 = Sd_address
     Sd_command(2) = High(tmp_wrd1)
     Sd_command(3) = Low(tmp_wrd1)
     Sd_command(4) = High(tmp_wrd2)
     Sd_command(5) = Low(tmp_wrd2)
     Sd_command(6) = &H55
     Gosub Send_sd_command
     Loop Until Sd_answer(1) = 0 Or Tmp_byt3 = 5
   If Sd_answer(1) <> 0 Then
     'Команда на запись не прошла
     Флаг = 1
     Print "Пришёл неверный ответ от команды записи"
   Else
     Print "Послать данные"
     'Послать данные
     'Послать стартовые байты
     ПринятыйБайт = Spimove(&Hff)
     ПринятыйБайт = Spimove(&Hfe)
     'Послать данные
     For Count_wrd = 1 To 512
       ПринятыйБайт = Spimove(sd_data(count_wrd))
     Next
     'Послать CRC16
     ПринятыйБайт = &H55
     ПринятыйБайт = Spimove(ПринятыйБайт)
     ПринятыйБайт = &H55
     ПринятыйБайт = Spimove(ПринятыйБайт)
     'Получить ответ от SD карты
     Gosub Receive_sd_command
     If Sd_answer(1) <> 229 Then
       'Данные не записались
       Sd_answer(1) = 1
       If Tmp_byt3 = 5 Then
         Флаг = 1
         Print "Пришёл неверный ответ после записи данных"
       End If
     Else
       ПринятыйБайт = Spimove(&Hff)
       'Отключить Sd карту
       Chip_select = 1
       ПринятыйБайт = Spimove(&Hff)
       'Включить SD карту
       Chip_select = 0
       ПринятыйБайт = Spimove(&Hff)
       Print "Данные успешно записаны"
       Sd_answer(1) = 0
     End If
   End If
   'Отключить Sd карту
   Chip_select = 1
   'Время, которое неоюходимо, для записи данных в SD карту
   Waitms 10
   If Флаг = 1 Then
     'Произошла ошибка при записи команды или данных
     Tmp_byt3 = 0
     'Инициализация SPI у SD карты
     Gosub Init_sd
   End If
   Loop Until Флаг = 0 And Sd_answer(1) = 0
 'Проверить правильно ли записали
 ФлагПроверкиЗаписи = 1
 'Прочитать данные из SD карты
 Gosub Read_sd_data
 If ФлагДанныеЗаписаныВерно = 1 Then
   Print "Верификация прошла успешно"
 Else
   Print "Верификация не прошла"
 End If
 Loop Until ФлагДанныеЗаписаныВерно = 1

Return

Read_sd_data: 'Подпограмма читает данные из SD карты по адресу Sd_address размером 512 байт 'данные записывает в Sd_data(512) ФлагДанныеЗаписаныВерно = 1

 Do
 Флаг = 0
 'Включить SD карту
 Chip_select = 0
 If ФлагПроверкиЗаписи = 1 Then
   Print "Верификация"
 Else
   Print "Чтение"
 End If
 Print "Установить размер блока чтения данных - 512"
 'Послать команду установить размер блока 512 в SD карту
 Sd_command(1) = &H50
 Sd_command(2) = &H00
 Sd_command(3) = &H00
 Sd_command(4) = &H02
 Sd_command(5) = &H00
 Sd_command(6) = &H55
 Gosub Send_sd_command
 Print "Прочитать блок данных по адресу " ; Hex(sd_address)
 'Послать команду прочитать блок данных по адресу (sd_address) в SD карту
 Tmp_byt3 = 0
   Do
   Incr Tmp_byt3
   Print "Попытка прочитать данные №" ; Tmp_byt3
   Sd_command(1) = &H51
   Tmp_wrd1 = Highw(sd_address)
   Tmp_wrd2 = Sd_address
   Sd_command(2) = High(tmp_wrd1)
   Sd_command(3) = Low(tmp_wrd1)
   Sd_command(4) = High(tmp_wrd2)
   Sd_command(5) = Low(tmp_wrd2)
   Sd_command(6) = &H55
   Gosub Send_sd_command
   Loop Until Sd_answer(1) = 0 Or Tmp_byt3 = 5
 If Sd_answer(1) <> 0 Then
   'Команда на чтение не прошла
   Флаг = 1
   Print "Пришёл неверный ответ от команды чтения"
 Else
   'Получение данных
   'Поймать стартовый байт
     Do
     ПринятыйБайт = Spimove(&Hff)
     Loop Until ПринятыйБайт = &HFE
   'Получить 512 байт данных
   For Count_wrd = 1 To 512
     If ФлагПроверкиЗаписи = 1 Then
       'Читаем и сравниваем с Sd_data(512)
       ПринятыйБайт = Spimove(&Hff)
       If ПринятыйБайт <> Sd_data(count_wrd) Then
         ФлагДанныеЗаписаныВерно = 0
       End If
     Else
       'Читаем и записываем в Sd_data(512)
       Sd_data(count_wrd) = Spimove(&Hff)
     End If
   Next
   'Получить КС
   ПринятыйБайт = Spimove(&Hff)
   ПринятыйБайт = Spimove(&Hff)
   Print "Данные успешно считаны"
 End If
 'Отключить Sd карту'
 Chip_select = 1
 If Флаг = 1 Then
   'Произошла ошибка при записи команды или данных
   'Инициализация SPI у SD карты
   Gosub Init_sd
 End If
 Loop Until Флаг = 0

ФлагПроверкиЗаписи = 0 Return

</source>