Как использовать последовательную шину SPI на ATSAMD21G18?

Как следует из названия, у меня есть микроконтроллер ATSAMD21G18, который я хочу связать с LTC6803-4, но я не уверен, как настроить шину SPI на микроконтроллере, а техническое описание оказалось слишком запутанным для меня, чтобы понять.

, 👍0

Обсуждение

SPI.begin()...? Или вы не используете API Arduino?, @Majenko

я даже не так далеко, я не знаю, как их физически соединить, не уверен, какие контакты использовать на ATSAMD21G18, @yanagibashi

Вы подключаете его к контактам PAD[x] для порта SPI, который хотите использовать., @Majenko

TBH выглядит слишком сложным на этом чипе. Я бы выбрал более простой чип. Есть ли конкретная причина, по которой вы хотите использовать именно этот чип?, @Majenko

Я хотел интегрировать BLE, 3 микросхемы LTC6803-4, часы реального времени и устройство чтения/записи microSD на одну плату, и я решил, что возьму за основу Adafruit Feather M0 Bluefruit BLE, но я открыт для рекомендаций по более простые микроконтроллеры, @yanagibashi


1 ответ


Лучший ответ:

2

Используйте SPI API, предоставляемый Arduino (https://www.arduino.cc/en/Tutorial/SPITransaction) и формат команды, который чип хочет, чтобы вы использовали, на основе таблицы данных. Вот небольшой пример кода для транзакции SPI. Хотя это и не проверено, это то, что я понял, прочитав техническое описание. Написано для Adafruit Feather M0 Express (использует микроконтроллер SAMD21G18). Для распиновки см. https ://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/adafruit2-pinouts#logic-pins-2-8.

Также обратите внимание, что Analog Devices предоставляет код Arduino для похожих устройств, таких как LTC6803-2, но не для -4. Тем не менее, вы можете посмотреть, как они реализовали драйвер. См. здесь

#include <Arduino.h>
#include <SPI.h>

/* pin setup */
int chip_select_pin = PIN_A2;
/* Выводы SPI с маркировкой «SCK», «MO», «MI» на экспресс-плате Adafruit Feather M0
* используются неявно.
* PIN_SPI_MISO (22), PIN_SPI_MOSI (23), PIN_SPI_SCK (24),
* */


#define LTC6803_4_MAX_SCLK_FREQ 1000000
#define LTC6803_4_USED_SCLK_FREQ (LTC6803_4_MAX_SCLK_FREQ/2)

SPISettings settings(LTC6803_4_USED_SCLK_FREQ, BitOrder::MSBFIRST, SPI_MODE3);

void start_voltage_adc_conversion(){
    SPI.beginTransaction(settings);
    digitalWrite(chip_select_pin, LOW);
    //СТЦВАД
    //Запуск преобразований АЦП напряжения ячейки и состояния опроса с разрешенным разрядом
    uint8_t tranfer_buf[2] = {
            0x10, //КОД
            0xB0 // ПЭК
    };
    SPI.transfer(tranfer_buf, 2);
    // ждем конвертации, просто статическое время. не менее 12 миллисекунд.
    delay(20);
    digitalWrite(chip_select_pin, HIGH);
    SPI.endTransaction();
}

void read_voltages_1_to_4(){
    // запускаем преобразование напряжения
    start_voltage_adc_conversion();

    SPI.beginTransaction(settings);
    digitalWrite(chip_select_pin, LOW);
    // буфер передачи должен иметь 2 байта для команды
    //и 6 байт на ответ (четыре 12-битных значения АЦП, закодированные в 6 регистрах CVR00..CVR05)
    //плюс 1 байт для PEC от чипа
    //Чтение значений напряжения ячейки 1-4, "RDCVA", стр. 22
    uint8_t tranfer_buf[2 + 6 + 1] = {
            0x06, //КОД
            0xD2 // ПЭК
    };
    SPI.transfer(tranfer_buf, 9);
    digitalWrite(chip_select_pin, HIGH);
    SPI.endTransaction();

    // восстановить значение 12-битного АЦП из C1V[0]..C1V[11] из значений регистров CVR00 и CVR01
    //см. техническое описание на стр. 24
    uint16_t adc_cell_1 = tranfer_buf[2] | ((tranfer_buf[3] & 0B1111) << 8);
    //преобразование значения adc в напряжение согласно стр. 15
    float voltage_cell_1_millivolt = ((int)adc_cell_1 - 512) * 1.5f ;
    Serial.print("Cell voltage 1: ");
    //печать с точностью до 5 цифр
    Serial.print(voltage_cell_1_millivolt, 5);
    Serial.println(" mV");
}

void setup() {
    Serial.begin(115200);
    pinMode(chip_select_pin, OUTPUT);
    SPI.begin();
}

void loop() {
    read_voltages_1_to_4();
    delay(2000);
}
,