69ka

AVR32 SPI прием и передача, Одновременный прием и передача

1 сообщение в этой теме

69ka    0

Добрый день, столкнулся с проблемой на микроконтроллере AVR32UC3C0512, мне необходимо передать сообщение по SPI на микросхему TLE6208-6G и одновременно с этой передачей считать ответ. Разница в передаче и ответе на диаграмме:
 

thumb.png

при передаче с кодом:

spi_select_device(&AVR32_SPI0, &SPI_MVK_CS1);
spi_write(&AVR32_SPI0, data_buff);
while((AVR32_SPI0.cr & AVR32_SPI_SR_TXEMPTY_MASK) != 0) {};

spi_read(&AVR32_SPI0, &result);
spi_set_chipselect_delay_bct(&AVR32_SPI0, &SPI_MVK_CS1, CONFIG_SPI_MASTER_DELAY_BCT);
spi_deselect_device(&AVR32_SPI0, &SPI_MVK_CS1);

код функции spi_write:

spi_status_t spi_write(volatile avr32_spi_t *spi, uint16_t data)
{
    uint32_t timeout = SPI_TIMEOUT;

    while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
        if (!timeout--) {
            return SPI_ERROR_TIMEOUT;
            //return 0xFFFF;
        }
    }

    spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET;

    return SPI_OK;
}

код функции spi_read:

spi_status_t spi_read(volatile avr32_spi_t *spi, uint16_t *data)
{unsigned int timeout = SPI_TIMEOUT;

   while ((spi->sr &
         (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) !=
         (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) {
      if (!timeout--) {
         return SPI_ERROR_TIMEOUT;
         //return 0xFFFF;
      }
   }

   *data = (spi->rdr & 0x0000FFFF) >> AVR32_SPI_RDR_RD_OFFSET;

   return SPI_OK;
}

в result 0. хотя отправляю не 0 и плата отрабатывает верно (необходимые светодиоды светятся). Посылка осуществляется в цикле. На осциллографе я вижу все эти пакеты, даже ответ, но мне нужно его прочитать, что не получается сделать.  Что может быть не так? Как получить верный ответ, пробовал даже оставлять от кода только строчки отправки и сразу чтение из регистра без задержек но ничего не помогло..

Пробовал также закольцевать SPI без изменения кода программы. ответ вижу передается через UART.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: aske12345
      Здравствуйте! Прошу помощи ! Столкнулся со следующей проблемой пытаюсь подключить к контроллеру по spi память FRAM FM25CL64 ,компилятор keil , пытаюсь записать одно число и его же считать, а осциллографом вижу, что считывается не то, что записывал. Пытался в разные ячейки памяти разные числа - считываются разные числа, но не те. Пишу 0x2F считывается 0x1С,  пишу 0xFF считывается 0xFE, пишу 0x99 считывается 0x20 - ерунда какая то. 
      Куски кода привел ниже:

      int main(void) {          SystemCoreClockUpdate();     SysTick_Config(SystemCoreClock/1000);//1ms     LEDs_ini();     Button_ini();     SPI3_FRAM_ini();         delay_ms(50);     //проверим FRAM начало запись 1 байта        CS_FRAM_ON();//        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};        SPI_I2S_SendData(SPI3, 0x06);//Set Write Enable Latch 6        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};        while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется        CS_FRAM_OFF();        delay_us(3);    //на самом деле задержка выходит около 500нс                CS_FRAM_ON();         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};     SPI_I2S_SendData(SPI3, 0x02);// Write              while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется     SPI_I2S_SendData(SPI3, 0x10);// 13 битный адрес         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется         SPI_I2S_SendData(SPI3, 0x00);// 13 битный адрес         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется     SPI_I2S_SendData(SPI3, 0x2F);// данные          while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется              CS_FRAM_OFF();         delay_us(3);//на самом деле задержка выходит около 500нс         //проверим FRAM конец запись  1 байта         //проверим FRAM начало чтение 1 байта         CS_FRAM_ON();//         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};     SPI_I2S_SendData(SPI3, 0x03);// Read              while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется     SPI_I2S_SendData(SPI3, 0x10);// 13 битный адрес         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется         SPI_I2S_SendData(SPI3, 0x00);// 13 битный адрес         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется     SPI_I2S_SendData(SPI3, 0x00);// пишем 0 для считывания         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)== RESET){};         while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY)== SET){};//ждем пока запишется         CS_FRAM_OFF(); //проверим FRAM конец чтение 1 байта              //LED1_OFF;          while(1)     {
      настройки spi:

      SPI_Init_user3.SPI_Direction = SPI_Direction_2Lines_FullDuplex;     SPI_Init_user3.SPI_Mode = SPI_Mode_Master;     SPI_Init_user3.SPI_DataSize = SPI_DataSize_8b;     SPI_Init_user3.SPI_CPOL = SPI_CPOL_High;//SPI_CPOL_Low     SPI_Init_user3.SPI_CPHA = SPI_CPHA_2Edge;     SPI_Init_user3.SPI_NSS = SPI_NSS_Soft;     SPI_Init_user3.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//4     SPI_Init_user3.SPI_FirstBit = SPI_FirstBit_MSB;         SPI_Init_user3.SPI_CRCPolynomial = 7;          SPI_Init(SPI3, &SPI_Init_user3);
      контакты вроде все пересмотрел, думал провода может длинноваты,  клок spi настраивал на разную частоту уменьшал до 1МГц - не влияет,  пробовал делать паузу между командой WREN и командой записи 15мс, а записью и считыванием 20мс, всё то же самое не помогло..
      приложил осциллограммы:
      Осциллограмма всех посылок  WREN, WITE, READ  (тактовый сигнал ch1 и miso FRAM ch2) (синий луч отношения к делу не имеет)
      Осциллограмма  команды WREN (тактовый сигнал ch1 и miso FRAM ch2)(синий луч отношения к делу не имеет)
      Осциллограмма  команды WITE (тактовый сигнал ch1 и miso FRAM ch2)
      Осциллограмма  считанного значения записывал 0x2F, считал 0x1C (тактовый сигнал ch1 и mosi FRAM ch2)
       




    • Автор: User_1
      Доброго времени суток!
      Вкратце: нужно после того, как я записал байт данных в SPI1->DR, отменить передачу этого байта и вместо него отправить 0х00
      Подробно: Смысл вот в чём: некий контроллер, с которым я пытаюсь наладить общение по SPI, запрашивает произвольный участок массива байт и считывает их сплошным потоком. Ну примерно как считывается микросхема EEPROM: задаёшь начальный адрес, а потом просто шлёшь сплошные 0xFF, а она сама инкрементирует адрес и прямо непрерывным потоком байт выдаёт содержимое памяти. Только тут в роли этой микросхемы мой stm32f030 и мне нужно следующий байт отправлять в SPI1->DR сразу после отправки предыдущего. Но когда поток заканчивается (а он каждый раз разной длины и длина эта заранее неизвестна), один байт остаётся не переданным и отправится первым при следующем запросе. А мне нужно, чтобы первым байтом всегда отправлялся 0х00
      Пином (ну то есть битом) NSS управляю программно, его выставление в единичку и снова в ноль, очевидно, не помогает вообще никак. Пока решил проблему так: деинициализирую модуль SPI и выключаю его тактирование, затем включаю тактирование и снова инициализирую. Работает, скорости хватает. Но должно же быть менее костыльное решение?)
      Может кто сталкивался с такой проблемой?
      Курение даташита, reference manual и результатов поиска в гугле, не особо помогло.
    • Автор: Sattva
      Тема: Реверс-инжиниринг: необходимо декодировать протокол связи контроллера пром. насоса и дисплея
      Общая цель: сделать управление кондиционером, вести мониторинг его работы.
      Время на работу: около 12 часов (2 дня).
      Задание для исполнителя:
      1. Выполнить обратное декодирование протокола связи контроллера промышленного
      кондиционера и его дисплея с сенсорными кнопками.
      2. Запаять ATMega 328P или ATMega 2560. Вероятно, придется резать дорожки,
      допаять резисторы в разрыв.
      3. Совместно с заказчиком написать короткий код ввода/вывода данных для Arduino (C++).
      Могут понадобиться функции передачи данных на второй контроллер ATMega 2560 по UART.
      4. Совместно с заказчиком составить простое описание.
      5. Работа дисплея, состояние контроллера кондиционера и мониторинг на Arduino
      должны быть синхронны.
      Программировать микроконтроллер и отправлять данные на вебсервер по
      Ethernet (W5500) умею. Паять умею. Работать с микроконтроллером на уровне
      регистров процессора не умею, потому и ставлю задание.

      Протокол: неизвестен
      Шина: неизвестна
      Чип дисплея: Holtek HT1621B
      Контроллер "пульта управления": Holtek BS84B08A-3
      Фото прилагается.
      Вероятно, применяется шина SPI или I2C, что должно облегчить задачу.

      Имеется пример подобного дисплея 2009 года с выполненной
      работой. У предыдущего исполнителя ушло около 2 часов на разбор
      команд и еще столько же на написание кода, *когда поняли, как
      разбирать команды*.

      Фото с реализацией задания прилагается, но на дисплее другого типа.



      Метод выполненной работы в прошлый раз:
      1. Для получения данных с Holtek-HT46F49E по 8-ми битной шине данных использован Arduino Pro Mini 328P.
      2. Подключение: 5 дорожек перерезано и допаяно 5 резисторов по 1 кОм. Так же использовано еще 3 линии (reset и данные).
      3. Для удаленного управления использована Arduino Mega 2560 + Ethernet Shield W5100.
      4. Общение между 328P и 2560 идет по UART.
       
      Наилучший вариант, если кто-то откликнется из Киева, чтобы можно было вместе
      встретиться и поработать. Но если в Киеве никого нет, то куплю недорогой логический
      анализатор уровней и будем общаться удаленно. Готов к любому варианту.
    • Автор: Max Kondor
      Доброго времени суток. Изучаю STM32, пользуюсь библиотекой SPL. При изучении SPI возникла проблема. Вся иницилизация проходит успешно, ну когда я пытаюсь прочитать даные с акселерометра, регистр Where_am_i, мне либо ничего не приходит, либо приходит 0xFF. Настраивал все по многим туториалам, результат один и тот же. У людей получается, а у меня нет.
    • Автор: Skyluck
      Здраствуйте, пожалуста подскажите за SPI.  Как там дрыгать ногой софтварно? У меня на выходе NSS у меня 1.4 вольта когда SPI выкл а должно быть 3.3 вроди.