Нет.Не просто пишите кучу кода, а затем посмотрите, что он делает.Такой подход к дробовику (или, если вы предпочитаете, спагетти к стене) - пустая трата усилий.
Во-первых, отбросьте все эти макросы.Вместо этого напишите комментарии, которые описывают назначение каждого куска кода, например, первые три назначения в вашей функции SPI_Initialize()
.
Затем преобразуйте свою спецификацию в псевдокод.Формат не имеет большого значения, просто используйте что-то, что позволит вам сосредоточиться на цели , а не на деталях, как это сделать.
Лист данных говорит, что с SPI есть три выхода из PIC (^ SS, SCK, MOSI на QT1481) и два входа (^ DRDY и MISO на QT1481).Я буду использовать эти имена для линий данных и для их соответствующих имен выводов ввода / вывода на PIC.
Фаза настройки на PIC должна быть простой:
Make ^DRDY an input
Make ^SS an output, set it HIGH
Make SCK an output, set it LOW
Make MOSI an output, set it LOW
Make MISO an input
Set up SPI using SCK, MOSI, MISO
Каждыйперевод является двунаправленным.Всякий раз, когда вы отправляете данные, вы также получаете данные.Нулевая команда зарезервирована для получения нескольких данных, говорится в техническом описании.Итак, вам нужна только функция, которая отправляет байт и одновременно получает байт:
Function SPITransfer(command):
Make sure at least 0.1ms has passed since the previous transfer.
Do:
Nothing
While (^DRDY is LOW)
Set ^SS LOW
response = Transfer(command)
Set ^SS HIGH
Return response
End Function
Насколько я понимаю, для PIC и правильно инициализированного аппаратного SPI строка response = Transfer(command)
находится в C
SSPBUF = command;
while (!DataRdySPI())
;
response = SSPBUF;
Вы также можете побить его, в этом случае (в псевдокоде):
response = 0
For bit = 7 down to 0, inclusive:
If (command & 128):
Set MOSI high
Else:
Set MOSI low
End If
Set SCK low
Sleep for a half period
command = command / 2
response = response * 2
If MISO high:
response = response + 1
End If
Set SCK high
Sleep for a half period
End For
, но, очевидно, аппаратный подход SPI лучше.
(Когда вы работаете, вы можете использовать аппаратный SPI без цикла ожидания от прерывания по таймеру, что делает связь по существу прозрачной для «основной операции» микроконтроллера PIC. Это требует немного другого подхода, с командой иочереди ответов (из нескольких байтов), но PIC значительно облегчит выполнение реальной работы, за исключением простого сканирования QT1481.)
После сброса вы по сути отправляете 0x0F, пока не получите 0xF0 обратно:
while (SPITransfer(0x0F) != 0xF0)
;
На этом этапе у вас есть шаги, которые необходимо реализовать в C. У OP также есть оборудование (осциллограф), чтобы проверить, работает ли их код.