Правильное использование SPI с ISR
Мой Arduino должен сделать:
- Запустите ISR как можно больше раз/ как можно быстрее.
- Время от времени получаю данные по I2C.
- Вывод данных по SPI в ISR.
Мой вопрос касается SPI и ISR. Документация о SPI, которую я нашел, была довольно скудной.
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
SPI.usingInterrupt(255);
SPI.begin();
void isr_function()
SPI.transfer(data);
pulse_latch();
};
Правильно ли это использовать SPI в моем случае? Может ли это быть быстрее?
@aWiseMan, 👍1
Обсуждение1 ответ
▲ 1
На самом деле довольно легко просто использовать периферийное устройство SPI без использования библиотек arduino. Прикрепленные функции могут быть использованы для отправки нескольких байтов через SPI одним вызовом: (Предполагая, что ATMEGA328)
#include <avr/io.h>
#include <avr/interrupt.h>
static unsigned char spiCnt, *userBufr;
/* Вызовите эту функцию во время настройки */
void SpiInit (void)
{
PPR &= ~0x04; // Убедитесь, что SPI имеет питание
DDRB |= 4; // Убедитесь, что сигнал SS на бите PORTB 2 выведен
SPCR = 0x50; // Включить SPI, максимальная скорость CLK
}
/* Call this function to initiate the multi-byte send */
void SpiWrite (void *data, unsigned char bytCnt)
{
/* Сохранить информацию о месседже вызывающего абонента */
userBufr = data;
spiCnt = bytCnt;
/* Включить устройство SPI, отправить первый байт */
SPCR |= 0x40; // Включить SPI
SPDR = *userBufr++; // Отправить первый байт
SPCR |= 0x80; // Включить прерывания
}
/* Позвоните по этому номеру, чтобы убедиться, что сообщение закончено. */
int SpiIsDone (void)
{
/* Ненулевое значение по завершении операции */
return ( ! (SPCR & 0x80));
}
/* Stay out of this one */
ISR (SPI_STC_vect)
{
/* Проверьте оставшееся количество байтов для отправки. */
if (--spiCnt)
SPDR = *userBufr++; // Отправить следующий байт
/* Операция завершена, отключите SPI */
else
SPCR &= ~0x80; // Отключить прерывания для SPI
}
,
@
Смотрите также:
- Чтение квадратурного энкодера в реальном времени с полным разрешением только с одним прерыванием на ATmega328
- Почему необходимо использовать ключевое слово volatile для глобальных переменных при обработке прерываний в ардуино?
- Какие контакты можно использовать для выбора микросхемы (CS, CC) на Arduino Nano Every?
- Серийное прерывание
- Влияет ли `millis()` на длинные ISR?
- Как прервать функцию цикла и перезапустить ее?
- Более 4 MCP23S17 на 1 шине SPI
- Проблема с NRF24L01
Библиотечная функция SPI;
передача
блокируется. Если вам действительно нужны дополнительные циклы процессора, вы можете отправлять данные между вызовами ISR. Аппаратное обеспечение SPI может отправлять данные, пока процессор делает что-то полезное, вместо того, чтобы ждать завершения передачи SPI. Затем вы должны зафиксировать данные в начале (следующего) ISR., @GerbenPS Вы не можете запустить SPI на частоте 16 МГц на Nano. Максимальная скорость-F_CPU/2, если я правильно помню, что будет 8 МГц, @Gerben
Если вам нужно быстро передать много данных через SPI, гораздо удобнее использовать micro с периферийным устройством SPI, поддерживающим DMA. Скорее всего, ардуино на базе ARM будут соответствовать всем требованиям., @bobflux