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

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск
(Новая: <source lang="vb"> $prog &HFF , &HE4 , &HD9 , &HFF ' generated. Take care that the chip supports all fuse bytes. $regfile = "m128DEF.dat" $crystal = 8000000 ...)
 
Строка 36: Строка 36:
  
 
Begin:
 
Begin:
'Отключить SD карту
+
Chip_select = 1 'Отключить SD карту
Chip_select = 1
 
 
'Ответ максимум состоит из 1 байт
 
'Ответ максимум состоит из 1 байт
 
Size_answer = 1
 
Size_answer = 1
Строка 43: Строка 42:
 
Sd_address = &H0
 
Sd_address = &H0
  
'Инициализация SPI у меги
+
Spiinit 'Инициализация SPI у меги
Spiinit
 
  
'Инициализация SPI у SD карты
+
Gosub Init_sd 'Инициализация SPI у SD карты
Gosub Init_sd
 
  
 
   Do
 
   Do
   'Очистить буфер для чтения/записи SD карты
+
  Gosub Clear_sd_buffer   'Очистить буфер для чтения/записи SD карты
  Gosub Clear_sd_buffer
 
  
 
   Sd_data(1) = 10
 
   Sd_data(1) = 10
Строка 64: Строка 60:
 
   Sd_data(10) = 100
 
   Sd_data(10) = 100
  
   'Записать данные в SD карту
+
   Gosub Write_sd_data  'Записать данные в SD карту
  Gosub Write_sd_data
 
  
   'Прочитать данные из SD карты
+
   Gosub Read_sd_data  'Прочитать данные из SD карты
  Gosub Read_sd_data
 
  
 
   Sd_address = Sd_address + 512
 
   Sd_address = Sd_address + 512
Строка 77: Строка 71:
 
'-------------------------------------------------------------------------------
 
'-------------------------------------------------------------------------------
  
Init_sd:
+
Init_sd: 'Подпограмма инициализирует SPI у SD карты
'Подпограмма инициализирует SPI у SD карты
 
  
 
Print "Инициализация SPI у SD карты"
 
Print "Инициализация SPI у SD карты"
Строка 94: Строка 87:
 
ПринятыйБайт = Spimove(&Hff)
 
ПринятыйБайт = Spimove(&Hff)
  
'Включить SD карту
+
Chip_select = 0 'Включить SD карту
Chip_select = 0
 
  
 
Print "Ресет"
 
Print "Ресет"
Строка 108: Строка 100:
  
 
Print "Инициализация"
 
Print "Инициализация"
   Do
+
   Do 'Послать команду инициализации SD карты
  'Послать команду инициализации SD карты
 
 
   Sd_command(1) = &H41
 
   Sd_command(1) = &H41
 
   Sd_command(2) = &H00
 
   Sd_command(2) = &H00
Строка 120: Строка 111:
 
   Loop Until Sd_answer(1) = 0
 
   Loop Until Sd_answer(1) = 0
  
'Отключить SD карту
+
Chip_select = 1 'Отключить SD карту
Chip_select = 1
 
  
 
Print "Инициализация SPI у SD карты окончена"
 
Print "Инициализация SPI у SD карты окончена"
 
Return
 
Return
  
Send_sd_command:
+
Send_sd_command: 'Подпограмма посылает команду SD карте
'Подпограмма посылает команду SD карте
 
  
 
ПринятыйБайт = Spimove(&Hff)
 
ПринятыйБайт = Spimove(&Hff)
Строка 137: Строка 126:
 
ПринятыйБайт = Spimove(sd_command(6))
 
ПринятыйБайт = Spimove(sd_command(6))
  
'Получить ответ от SD карты
+
Gosub Receive_sd_command 'Получить ответ от SD карты
Gosub Receive_sd_command
 
  
 
ПринятыйБайт = Spimove(ПринятыйБайт)
 
ПринятыйБайт = Spimove(ПринятыйБайт)
 
Return
 
Return
  
Receive_sd_command:
+
Receive_sd_command: 'Подпограмма получает ответ от SD карты
'Подпограмма получает ответ от SD карты
 
  
 
   Do
 
   Do
Строка 163: Строка 150:
 
Return
 
Return
  
Clear_sd_buffer:
+
Clear_sd_buffer: 'Подпограмма очищяет буфер для чтения/записи SD карты
'Подпограмма очищяет буфер для чтения/записи SD карты
 
  
 
For Count_wrd = 1 To 512
 
For Count_wrd = 1 To 512
Строка 171: Строка 157:
 
Return
 
Return
  
Write_sd_data:
+
Write_sd_data: 'Подпограмма записывает данные в SD карту по адресу Sd_address размером 512 байт
'Подпограмма записывает данные в SD карту по адресу Sd_address размером 512 байт
 
 
'данные берёт из Sd_data(512)
 
'данные берёт из Sd_data(512)
  
Строка 179: Строка 164:
 
     Do
 
     Do
 
     Флаг = 0
 
     Флаг = 0
     'Включить SD карту
+
    Chip_select = 0     'Включить SD карту
    Chip_select = 0
 
  
 
     Print "Запись"
 
     Print "Запись"
Строка 189: Строка 173:
 
       Incr Tmp_byt3
 
       Incr Tmp_byt3
 
       Print "Попытка записать данные №" ; Tmp_byt3
 
       Print "Попытка записать данные №" ; Tmp_byt3
       'Послать команду записать блок данных по адресу (sd_address) в SD карту
+
       Sd_command(1) = &H58  'Послать команду записать блок данных по адресу (sd_address) в SD карту
      Sd_command(1) = &H58
 
  
 
       Tmp_wrd1 = Highw(sd_address)
 
       Tmp_wrd1 = Highw(sd_address)
Строка 204: Строка 187:
  
 
     If Sd_answer(1) <> 0 Then
 
     If Sd_answer(1) <> 0 Then
       'Команда на запись не прошла
+
      Флаг = 1       'Команда на запись не прошла
      Флаг = 1
 
 
       Print "Пришёл неверный ответ от команды записи"
 
       Print "Пришёл неверный ответ от команды записи"
 
     Else
 
     Else
 
       Print "Послать данные"
 
       Print "Послать данные"
      'Послать данные
+
       ПринятыйБайт = Spimove(&Hff)     'Послать данные
      'Послать стартовые байты
+
       ПринятыйБайт = Spimove(&Hfe)     'Послать стартовые байты
       ПринятыйБайт = Spimove(&Hff)
 
       ПринятыйБайт = Spimove(&Hfe)
 
 
       'Послать данные
 
       'Послать данные
 
       For Count_wrd = 1 To 512
 
       For Count_wrd = 1 To 512
Строка 223: Строка 203:
 
       ПринятыйБайт = Spimove(ПринятыйБайт)
 
       ПринятыйБайт = Spimove(ПринятыйБайт)
  
       'Получить ответ от SD карты
+
       Gosub Receive_sd_command      'Получить ответ от SD карты
      Gosub Receive_sd_command
 
  
 
       If Sd_answer(1) <> 229 Then
 
       If Sd_answer(1) <> 229 Then
        'Данные не записались
+
         Sd_answer(1) = 1         'Данные не записались
         Sd_answer(1) = 1
 
 
         If Tmp_byt3 = 5 Then
 
         If Tmp_byt3 = 5 Then
 
           Флаг = 1
 
           Флаг = 1
Строка 236: Строка 214:
 
         ПринятыйБайт = Spimove(&Hff)
 
         ПринятыйБайт = Spimove(&Hff)
  
         'Отключить Sd карту
+
         Chip_select = 1        'Отключить Sd карту
        Chip_select = 1
 
  
 
         ПринятыйБайт = Spimove(&Hff)
 
         ПринятыйБайт = Spimove(&Hff)
  
         'Включить SD карту
+
         Chip_select = 0        'Включить SD карту
        Chip_select = 0
 
  
 
         ПринятыйБайт = Spimove(&Hff)
 
         ПринятыйБайт = Spimove(&Hff)
Строка 251: Строка 227:
 
     End If
 
     End If
  
     'Отключить Sd карту
+
    Chip_select = 1     'Отключить Sd карту
     Chip_select = 1
+
     Waitms 10     'Время, которое неоюходимо, для записи данных в SD карту
     'Время, которое неоюходимо, для записи данных в SD карту
 
    Waitms 10
 
  
 
     If Флаг = 1 Then
 
     If Флаг = 1 Then
       'Произошла ошибка при записи команды или данных
+
       Tmp_byt3 = 0      'Произошла ошибка при записи команды или данных
       Tmp_byt3 = 0
+
       Gosub Init_sd      'Инициализация SPI у SD карты
 
 
      'Инициализация SPI у SD карты
 
      Gosub Init_sd
 
 
     End If
 
     End If
 
     Loop Until Флаг = 0 And Sd_answer(1) = 0
 
     Loop Until Флаг = 0 And Sd_answer(1) = 0
   'Проверить правильно ли записали
+
   ФлагПроверкиЗаписи = 1  'Проверить правильно ли записали
   ФлагПроверкиЗаписи = 1
+
   Gosub Read_sd_data  'Прочитать данные из SD карты
  'Прочитать данные из SD карты
 
  Gosub Read_sd_data
 
  
 
   If ФлагДанныеЗаписаныВерно = 1 Then
 
   If ФлагДанныеЗаписаныВерно = 1 Then
Строка 284: Строка 253:
 
   Do
 
   Do
 
   Флаг = 0
 
   Флаг = 0
   'Включить SD карту
+
   Chip_select = 0  'Включить SD карту
  Chip_select = 0
 
  
 
   If ФлагПроверкиЗаписи = 1 Then
 
   If ФлагПроверкиЗаписи = 1 Then
Строка 324: Строка 292:
  
 
   If Sd_answer(1) <> 0 Then
 
   If Sd_answer(1) <> 0 Then
     'Команда на чтение не прошла
+
    Флаг = 1     'Команда на чтение не прошла
    Флаг = 1
 
 
     Print "Пришёл неверный ответ от команды чтения"
 
     Print "Пришёл неверный ответ от команды чтения"
 
   Else
 
   Else
Строка 333: Строка 300:
 
       ПринятыйБайт = Spimove(&Hff)
 
       ПринятыйБайт = Spimove(&Hff)
 
       Loop Until ПринятыйБайт = &HFE
 
       Loop Until ПринятыйБайт = &HFE
    'Получить 512 байт данных
+
     For Count_wrd = 1 To 512     'Получить 512 байт данных
     For Count_wrd = 1 To 512
 
 
       If ФлагПроверкиЗаписи = 1 Then
 
       If ФлагПроверкиЗаписи = 1 Then
         'Читаем и сравниваем с Sd_data(512)
+
         ПринятыйБайт = Spimove(&Hff)        'Читаем и сравниваем с Sd_data(512)
        ПринятыйБайт = Spimove(&Hff)
 
 
         If ПринятыйБайт <> Sd_data(count_wrd) Then
 
         If ПринятыйБайт <> Sd_data(count_wrd) Then
 
           ФлагДанныеЗаписаныВерно = 0
 
           ФлагДанныеЗаписаныВерно = 0
 
         End If
 
         End If
 
       Else
 
       Else
        'Читаем и записываем в Sd_data(512)
+
         Sd_data(count_wrd) = Spimove(&Hff)        'Читаем и записываем в Sd_data(512)
         Sd_data(count_wrd) = Spimove(&Hff)
 
 
       End If
 
       End If
 
     Next
 
     Next
Строка 353: Строка 317:
 
   End If
 
   End If
  
   'Отключить Sd карту'
+
  Chip_select = 1   'Отключить Sd карту'
  Chip_select = 1
 
  
 
   If Флаг = 1 Then
 
   If Флаг = 1 Then
 
     'Произошла ошибка при записи команды или данных
 
     'Произошла ошибка при записи команды или данных
  
     'Инициализация SPI у SD карты
+
     Gosub Init_sd    'Инициализация SPI у SD карты
    Gosub Init_sd
 
 
   End If
 
   End If
 
   Loop Until Флаг = 0
 
   Loop Until Флаг = 0

Версия 06:42, 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>