Я пытаюсь эмулировать данные с 10-битного поворотного энкодера AEAT-6010 и отправить их на вывод MISO протокола SPI на ATtiny3217. ATtiny действуют как подчиненные устройства и получают сигналы CLK и SS в качестве входных данных для ответа путем вывода данных (значение датчика). Кодер следует протоколу SSI для отправки данных, как показано ниже:
Проблема возникает при попытке отправить 10-битный протокол 8-битного SPI на ATtiny. Мастером протокола SPI является микросхема TMS320F2808, и с нее я получаю 11 тактовых импульсов и сигнал SS. Измеренные сигналы и данные показаны ниже:
Здесь данные, которые я пытаюсь отправить, 0b10
только для тестирования. Я вижу правильные данные в строке MISO, но в середине сигнала есть три дополнительных 1. Это происходит с BUFEN=1
и BUFWR=1
в настройках SPI ATtiny, как видно из конфигурации ниже (без режима буфера три единицы идут на последних 3 битах, а первый бит (MSB) читается как а 1):
int8_t SPI_0_init()
{
SPI0.CTRLA = 0 << SPI_CLK2X_bp /* Enable Double Speed: disabled */
| 0 << SPI_DORD_bp /* Data Order Setting: enabled */
| 1 << SPI_ENABLE_bp /* Enable Module: enabled */
| 0 << SPI_MASTER_bp /* SPI module in slave mode */
| SPI_PRESC_DIV4_gc; /* System Clock / 4 */
SPI0.CTRLB = 1 << SPI_BUFEN_bp /* Buffer Mode Enable: enabled */
| 1 << SPI_BUFWR_bp /* Buffer Write Mode: enabled */
| SPI_MODE_0_gc /* SPI Mode 1 */
| 0 << SPI_SSD_bp; /* Slave Select Disable: disabled */
SPI0.INTCTRL = 0 << SPI_DREIE_bp /* Data Register Empty Interrupt Enable: enabled */
| 1 << SPI_IE_bp /* Interrupt Enable: enabled */
| 0 << SPI_RXCIE_bp /* Receive Complete Interrupt Enable: disabled */
| 0 << SPI_SSIE_bp /* Slave Select Trigger Interrupt Enable: disabled */
| 0 << SPI_TXCIE_bp; /* Transfer Complete Interrupt Enable: disabled */
return 0;
}
Я подтвердил, что данные модуля SPI TMS320F2808 и ATtiny одинаковы (читай по падающему такту). Есть ли что-то, чего мне не хватает в работе буферов SPI или прерываний SPI? Я не уверен, что делать в ISR при разрешении различных прерываний (или, кроме очистки флагов). Это моя основная функция (ISR пока пуст):
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
sei(); // Enable global interrupts
/* Replace with your application code */
while (1) {
SPI_transmit(enc_data_L);
}
Где SPI_transmit()
выглядит следующим образом:
void SPI_transmit(uint16_t enc_data)
{
// Then start the transmission by assigning the data to the SPI data register
SPI0.DATA = enc_data;
//SPI0.DATA = enc_data_H;
// Now wait for the data transmission to complete by periodically checking the SPI status register
//the SPI_IF is the only interrupt flag with a function in non-buffered mode.
while(!(SPI0.INTFLAGS & (SPI_RXCIF_bm)));
SPI0.DATA; //Dummy read to clear flag
}
Я также попытался разделить 16-битные данные, как предложено здесь , но проблема остается и для 8-битных данных. Надеюсь, этого достаточно. Я благодарен за любые идеи!