Подключаем внешнюю флеш-память SD-Card к МиниБоту — различия между версиями
EdGull (обсуждение | вклад) |
SkyStorm (обсуждение | вклад) м |
||
Строка 1: | Строка 1: | ||
+ | [[Категория:МиниБот]] | ||
<source lang="vb"> | <source lang="vb"> | ||
Версия 10:09, 7 июля 2008
<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: Chip_select = 1 'Отключить SD карту 'Ответ максимум состоит из 1 байт Size_answer = 1 ФлагПроверкиЗаписи = 0 Sd_address = &H0
Spiinit 'Инициализация SPI у меги
Gosub Init_sd 'Инициализация SPI у SD карты
Do Gosub Clear_sd_buffer 'Очистить буфер для чтения/записи SD карты
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
Gosub Write_sd_data 'Записать данные в SD карту
Gosub Read_sd_data 'Прочитать данные из SD карты
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)
Chip_select = 0 'Включить SD карту
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
Chip_select = 1 'Отключить SD карту
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))
Gosub Receive_sd_command 'Получить ответ от SD карты
ПринятыйБайт = 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 Chip_select = 0 'Включить SD карту
Print "Запись"
Print "Записать блок данных (512 байт) по адресу " ; Hex(sd_address)
Do Incr Tmp_byt3 Print "Попытка записать данные №" ; Tmp_byt3 Sd_command(1) = &H58 'Послать команду записать блок данных по адресу (sd_address) в SD карту
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(ПринятыйБайт)
Gosub Receive_sd_command 'Получить ответ от SD карты
If Sd_answer(1) <> 229 Then Sd_answer(1) = 1 'Данные не записались If Tmp_byt3 = 5 Then Флаг = 1 Print "Пришёл неверный ответ после записи данных" End If Else ПринятыйБайт = Spimove(&Hff)
Chip_select = 1 'Отключить Sd карту
ПринятыйБайт = Spimove(&Hff)
Chip_select = 0 'Включить SD карту
ПринятыйБайт = Spimove(&Hff)
Print "Данные успешно записаны" Sd_answer(1) = 0 End If End If
Chip_select = 1 'Отключить Sd карту Waitms 10 'Время, которое неоюходимо, для записи данных в SD карту
If Флаг = 1 Then Tmp_byt3 = 0 'Произошла ошибка при записи команды или данных Gosub Init_sd 'Инициализация SPI у SD карты End If Loop Until Флаг = 0 And Sd_answer(1) = 0 ФлагПроверкиЗаписи = 1 'Проверить правильно ли записали Gosub Read_sd_data 'Прочитать данные из SD карты
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 Chip_select = 0 'Включить SD карту
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 For Count_wrd = 1 To 512 'Получить 512 байт данных If ФлагПроверкиЗаписи = 1 Then ПринятыйБайт = Spimove(&Hff) 'Читаем и сравниваем с Sd_data(512) If ПринятыйБайт <> Sd_data(count_wrd) Then ФлагДанныеЗаписаныВерно = 0 End If Else Sd_data(count_wrd) = Spimove(&Hff) 'Читаем и записываем в Sd_data(512) End If Next 'Получить КС ПринятыйБайт = Spimove(&Hff) ПринятыйБайт = Spimove(&Hff)
Print "Данные успешно считаны" End If
Chip_select = 1 'Отключить Sd карту'
If Флаг = 1 Then 'Произошла ошибка при записи команды или данных
Gosub Init_sd 'Инициализация SPI у SD карты End If Loop Until Флаг = 0
ФлагПроверкиЗаписи = 0 Return
</source>