Подключаем внешнюю флеш-память SD-Card к МиниБоту
<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>