Осциллоскоп в Atmel Studio

Тема в разделе "Технологии радиолюбителя", создана пользователем parovoZZ, 11 дек 2018.

  1. parovoZZ

    parovoZZ Гуру

    В чем сила, брат?

    Вот так выглядит АААААААА на частоте оцифровке 15 кГц и с фильтром ФНЧ около 5 кГц и спадом 3 дБ на октаву.
    aaaa.png
    Интересно?
    Тогда запускаем AtmelStudio -> Tools - Data Visualizer. Про всё не расскажу - только про то, чем сам пользуюсь.
    Закрываем все окна. Идем в Configuration -> External Connection -> Serial Port. Появятся стандартные UART настройки, где надо выбрать скорость и прочее =) ( у меня 250 000 бод - для байтов, летящих со скоростью 15 000 раз в секунду - хватает), выбрать Com порт и нажать кнопку Connect. Теперь мы можем в эту тулзу по Com порту гнать данные. Для того, чтобы открыть осциллоскоп, опять идем в Configuration -> Vizualization -> Oscilloscop. Появится окошко, как показано выше. У нас есть четыре канала, каждый из которых можно повесить на любой имеющийся Com порт. Для этого надо ухватить ручку (очень напоминает гранату времен отечественной))) напротив параметра Stop bits и протащить её до такой же ручки в канале осциллоскопа, где и бросить. Ручка приобретет такой вид:
    aaaa1.png
    Если поток данных по UART уже идет, то жмем Run/Stop и переводим триггер в Auto. Вуаля )
    Как выгнать данные со своего устройства? Либо тупо подавать на UART, а затем через USB - COM конвертер. Для вывода данных с интерфейса SPI я использую плату arduino nano со следующим кодом:
    main.c
    Код (C++):
    /*
    * UART_SPI.c
    *
    * Created: 14.06.2018 23:01:23
    * Author : Andrey
    */



    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdint.h>


    #include "spi.h"
    #include "uart.h"



    #define F_CPU        16000000UL

    // ... Определение скорости работы UART
    #define baud        250000
    #define ubrr        F_CPU/16/baud - 1


    //volatile uint8_t Buffer[256];            // Кольцевой буфер
    volatile uint8_t node_in;            // Указатель на входные данные в кольцевом буфере


    ISR (SPI_STC_vect)
    {
        node_in = 1;
    }

    ISR (USART_UDRE_vect)
    {
       
    }

    int main(void)
    {

        SPI_Init();
        UART_Init(ubrr);

        UART_Transmit(100);
        UART_Transmit(0);
       

        sei();
     
        while (1)
        {
            if (node_in)
            {
                UART_Transmit(SPI_ReadByte());
                node_in = 0;
            }
        }
    }
    uart.c
    Код (C++):
    /*
    * uart.c
    *
    * Created: 15.06.2018 23:04:07
    *  Author: Andrey
    */



    #include <avr/io.h>

    #include "uart.h"




    void UART_Init (uint16_t ubrr)
    {
        UBRR0H = (uint8_t) (ubrr >> 8);
        UBRR0L = (uint8_t) ubrr;

        UCSR0B = (0 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (1 << RXEN0) | (1 << TXEN0);

        UCSR0C = (3 << UCSZ00);        // 1-stop bit, 8 bit data
    }

    void UART_Transmit (uint8_t data)
    {
        while (!(UCSR0A & (1 << UDRE0)))
        ;
        UDR0 = data;
    }

    uint8_t UART_Receive (void)
    {
        while (!(UCSR0A & (1 << RXC0)))
        ;
        return UDR0;
    }
    spi.c
    Код (C++):
    #include <avr/io.h>

    #include "spi.h"
    #include "bits_macros.h"
    #include "pins.h"



        // ... Инициализация SPI
    void SPI_Init(void)
    {
        SPI_DDR &= ~((1 << SS) | (1 << SCK) | (1 << MOSI));
        SPI_DDR |= (1 << MISO);

        SPI_PORT |= (1 << SS);

        SPCR = (1 << SPE) | (1 << SPIE);
    }

    /*отослать байт данных по SPI*/
    void SPI_WriteByte(uint8_t data)
    {
       SPDR = data;
       while(!(SPSR & (1<<SPIF)));
    }


        // ... Получить байт данных по SPI
    uint8_t SPI_ReadByte(void)
    {
        return SPDR;
    }

    /*отправить несколько байт данных по SPI*/
    void SPI_WriteArray(uint8_t cmd, uint8_t num, uint8_t *data)
    {
        SPDR = cmd;

        while (!(SPSR & (1 << SPIF)));

        while(num--)
        {
            SPDR = *data++;
            while(!(SPSR & (1<<SPIF)));
        }
    }

    /*отправить и получить несколько байт данных по SPI*/
    void SPI_ReadArray(uint8_t num, uint8_t *data)
    {
       while(num--){
          SPDR = *data;
          while(!(SPSR & (1<<SPIF)));
          *data++ = SPDR;
       }
    }
    Преобразование идет только в одну сторону SPI -> UART. Nano выступает в роли Slave SPI устройства. Почему NANO? Не знаю как в UNO, но у нее пин SS выведен наружу, что позволяет оперативно включать/выключать преобразователь. У других плат SS занят светодиодом, и подлезать к нему с нулевым проводом не очень удобно. Программно этот пин тоже не переключить - как только он становится выходом, он отключается от блока SPI.
    На этом всЁ.
     
    Daniil нравится это.
  2. AlexU

    AlexU Гуру

    То, что пытаешься зафиксировать свой опыт -- это очень хорошо.
    Но есть один совет (хотя можешь пропустить его мимо ушей): что бы текст был полезен, как себе самому, так и другим, научись свой труд читать "чужими глазами", т.е. глазами потенциального читателя, который понятия не имеет об окружении, в контексте которого был написан текст.
    Можешь потренироваться на этой своей статье. Показателем того, что научился читать "чужими словами", будет несколько возникших вопросов после окончания чтения, например: "А о чём здесь вообще говорится, если автор в начале статьи завёл речь о программном осциллоскопе из состава Atmel Studio, а потом вдруг привёл какие-то исходники?", "Наверно это исходники для какого-то устройства, которое каким-то образом (скорее всего через USART) передаёт данные в IDE?", "И похоже, что устройство общается через SPI с АЦП, или нет?" и т.п.
     
  3. b707

    b707 Гуру

    У меня инстинкт - статьи, написанные рекламным стилем, с характерным началом "заинтересованы?" - я обычно тут же закрываю :)
    Вот и тут не смог себя заставить прочитать далее второго предложения :)
    Паравоз - а ты продаешь или покупаешь?
     
  4. parovoZZ

    parovoZZ Гуру

    что хочешь? Давай продам))