Що трохи бити


26

Я новачок у програмуванні мікроконтролерів. Я використовую контролер ATmega32-A та компілятор CodeVisionAVR. Я використовую генератор сигналів (AD9833) для генерації синусоїдального сигналу за допомогою SPI-зв'язку. Я здатний генерувати синусоїду успішно. Тепер я передаю цей сигнал датчику. Вихід датчика вибирається через мультиплексор і надсилається в АЦП. Тепер я хочу прочитати значення АЦП, використовуючи зв'язок SPI. Я багато намагався налаштувати регістри АЦП. Досі це не працює. Щоб побачити Код зв'язку SPI, перегляньте налаштування моїх попередніх повідомлень ADC-регістрів за допомогою спільного зв'язку . Я використовую зв'язок USART (RS232) для друку значень на ПК (PuTTY).

Хтось порадив мені використовувати біт-банг. Я новачок у цій концепції. Чи може хто-небудь надати мені приклад коду бітового удару SPI-зв'язку. Як розпочати цю процедуру? Чи може хтось надати мені хороший матеріал. Чи потрібно мені зовнішнє обладнання?

Я написав це, включаючи контактні з'єднання:

#define ADC_CS PORTB.3
#define MOSI PORTB.5
#define MISO PINB.6
#define SCK PORTB.7

void send_8bit_serial_data(unsigned char data)
{
    int i;  
    ADC_CS=0;
    for (i = 0; i < 8; i++)
    {
        // consider leftmost bit
        // set line high if bit is 1, low if bit is 0
        if (data & 0x80)
            output_high(PORTB.5);
        else
            output_low(PORTB.5);

        // pulse clock to indicate that bit value should be read
        output_low(PORTB.7);
        output_high(PORTB.7);

        // shift byte left so next bit will be leftmost
        data <<= 1;
    }

    // deselect device
    ADC_CS=1;
}


Ваш код виглядає нормально, окрім того, що низький вихідний сигнал повинен бути перед налаштуванням біт та затримкою. Вам потрібно кілька затримок, щоб виправити час (так що годинник низький / високий приблизно однаковий період) Погляньте на код Стівена ще раз. Якщо ви хочете прочитати також, вам доведеться додати код і для цього.
Олі Глазер

@ OliGlaser Чи можу я використовувати цей код безпосередньо замість звичайного SPI-коду, який налаштовує регістри.
верендра

@verendra - не впевнений, що ти маєш на увазі під "звичайним кодом SPI". Якщо ви маєте на увазі замість апаратної SPI, то АЦП не хвилює, як формуються імпульси, якщо вони узгоджуються з протоколом та термінами.
Олі Глазер

Відповіді:


25

Розбиття бітів - це створення всієї серії імпульсів у програмному забезпеченні, а не покладання на апаратне забезпечення всередині мікроконтролера.

У багатьох мікроконтролерах є апаратний SPI, і тоді все, що вам потрібно зробити, - це написати байт у вихідний регістр, і контролер SPI перемістить дані, і в той же час отримає дані від підлеглого. Ви можете отримати переривання, коли передача завершена, а потім прочитати отримані дані.

Але деякі мікроконтролери не мають на борту апаратного забезпечення SPI, і тоді вам доведеться моделювати його, роблячи все вручну. SPI має кілька різних режимів, я буду використовувати цю імпульсну діаграму як приклад:

введіть тут опис зображення

Тож, якщо спеціалізований контролер SPI піклується про всі імпульси, зміну даних та час, під час біт-ударів вам слід самостійно вживати всіх дій:

Make Slave Select low  
Short delay
Do 8 times
  Make the SCK (Serial Clock) pin low 
  Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data  
  Add brief delay  
  Make the SCK output high
  Read MISO (Master-In-Slave-Out) pin
  Shift received data left, and shift the bit just read in as bit 0   
  Add brief delay  
  Shift the data byte 1 bit left
Make Slave Select high again  

SPI біт-бафінгу відносно простий, код для біт-бафінгу I2C, наприклад, буде складнішим, і вам потрібен таймер якось, якщо ви хочете розрядити протокол UART.


2
Чи можете ви надати зразок коду с.
верендра

1
@verendra - Я додав приклад псевдокоду, який ви зможете легко перекласти на C.
stevenvh

Я успішно генерую Wavefrom за допомогою SPI-зв'язку. У мене проблеми з читанням значень АЦП, використовуючи лише SPI. Мені доводиться використовувати біт-стук для обох або просто лише для читання значень АЦП. Ви можете подивитися на мій код, щоб надіслати 8 біт, це написати. але я плутаю, як це використовувати. Чи можу я розмістити цей код безпосередньо замість свого SPI-коду для встановлення регістра.
верендра

@Steven - діаграма, яку ви показуєте, першою є MSB, тому вам потрібно зсунути ліворуч з 7, а зсув ліворуч від 0. Я знаю, що немає стандарту, тому він може бути LSB спочатку, але я думаю, що більшість периферійних пристроїв SPI роблять це так .
Олі Глазер

2
@ Олі - хороший момент, я це пропустив. Я це виправлю, дякую за відгуки. Причина відсутності стандарту полягає в тому, що це не має значення, поки кількість переданих бітів дорівнює довжині регістра зсуву. Останнім часом деякі мікроконтролери (наприклад, NXP Cortec-M3) мають регістр зсуву змінної довжини, і тоді напрямок може мати значення. IIRC в AVR ви можете вибрати MSB спочатку або LSB спочатку.
stevenvh

6

Біт-удар - це концепція того, що сигнали, які виходять із пристрою або надходять у пристрій, генеруються / відбираються за допомогою програмного, а не апаратного забезпечення. Очевидно, що потрібне деяке обладнання, але при використанні біт-ударів єдиним обладнанням для кожного виводу є засувка, яку можна явно встановити або очистити програмним забезпеченням, і єдине обладнання для кожного входу - це інтерфейс, що дозволяє програмному забезпеченню перевірити, чи це високий або низький (і зазвичай виконують умовну гілку для одного стану, але не для іншого).

Максимальна швидкість, яка може бути досягнута за допомогою розбиття бітів, як правило, є частиною тієї, яку можна досягти за допомогою спеціального обладнання, але поза межами обмежень, накладених швидкістю процесора, біт-стукінг набагато більш універсальний і може бути використаний в обставинах де обладнання загального призначення не зовсім підходить, а апаратне забезпечення спеціального призначення не було б рентабельним.

Наприклад, багато контролерів мають порт "SPI-стилю", який поводиться по суті так: коли байт записується в певний реєстр, апаратне забезпечення буде генерувати деяку кількість тактових імпульсів (як правило, вісім), тактируючи біт даних на передній край кожного тактового імпульсу та вибірки вхідного біта даних на кінцевій кромці. Як правило, порти в стилі SPI контролерів дозволять налаштувати різні функції, але в деяких випадках може знадобитися інтерфейс процесора з пристроєм, який робить щось незвичне. Пристрій може вимагати, щоб біти даних оброблялися у кількох, відмінних від восьми, або може знадобитися, щоб дані були як вихідними, так і вибірковими на одній і тій самій грані годинника, або це може мати якусь іншу незвичну вимогу. Якщо конкретне обладнання на контролері, який використовується, може підтримувати точні вимоги, чудово (деякі надають настроювану кількість бітів, окремо налаштовуються таймінги передачі та прийому тощо). Якщо ні, може бути корисним розрив бітів. Залежно від контролера, розрядний інтерфейс SPI-ish часто займе 2–10 разів, ніж дозволити апаратному поводженню з ним, але якщо вимоги не відповідають вимогам обладнання, обмін даними повільніше може бути кращим, ніж взагалі не в змозі це зробити.

Одне важливе, що слід відзначити при розбитому дизайні, - це те, що вони є найпростішими та надійними в тих випадках, коли або пристрої, з якими спілкуються, чекають на контролері розбиття бітів, щоб генерувати весь час, або там, де контролеру буде дозволено зачекайте, не відволікаючись, на приїзд події, і де вона зможе зробити все, що потрібно зробити з цією подією до того, як настане будь-яка інша подія, на яку вона повинна діяти. Вони набагато менш надійні в тих випадках, коли пристрою потрібно буде реагувати на зовнішні подразники протягом відносно короткого проміжку часу, але він не може на 100% використовувати свою енергію для спостереження за такими подразниками.

Наприклад, припустимо, що хочете, щоб процесор послідовно передавав дані у стилі UART зі швидкістю, що є дуже високою щодо його тактової частоти (наприклад, PIC, який виконує 8192 інструкцій в секунду, бажає виводити дані зі швидкістю 1200 bps). Якщо не вмикаються переривання, така передача не є складною (тактовуйте один біт кожні сім циклів інструкцій). Якщо PIC нічого не робив, окрім очікування вхідного байта даних 1200bps, він міг виконати 3-цикльний цикл, очікуючи на початковий біт, а потім перейти до обліку даних через семициклічні інтервали. Дійсно, якщо PIC мав байт даних, готовий відправити, коли надходить вхідний байт даних, сім циклів на біт буде достатньо часу, щоб PIC надіслав свій байт даних одночасно з читанням вхідного байта. Так само,якщо така відповідь мала б фіксований термін відносно вихідної передачі . З іншого боку, не було б можливості для PIC, які швидко обробляли бит-удари, таким чином, щоб будь-якому пристрою було дозволено передавати в будь-який момент, коли він вважає за потрібне (на відміну від одного пристрою, який міг би передавати, коли побачив підходити і робити все, що йому сподобалось, коли не передавати, і один пристрій, який повинен витратити більшу частину часу, не роблячи нічого, крім чекання передач від першого пристрою).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.