Есть ли способ использовать прерывания часов на raspberry pi 2 под управлением Windows iot?

Я разрабатываю универсальное приложение javascript генератора сигналов Windows Iot для Raspberry Pi 2.

Я подключил к нему ЦАП MCP4921 через SPI.

То, что я пытаюсь сделать, это генерировать синусоидальную волну с заданной частотой, амплитудой и смещением. У меня уже работает устройство, но когда я пытаюсь создать точную волну, приложение замедляет точную синусоидальную волну даже на 10 Гц.

В настоящее время волна генерируется следующим образом.

var Spi = Windows.Devices.Spi;
var Enumeration = Windows.Devices.Enumeration;

var frequency = 10;
var ts = 1 / frequency;
var updateFreq = ts / 100;
var time = 0;
var offset = 2;
var amplitude = 2;
var resolution = 4095;
var voltage = 5;

var settings = Spi.SpiConnectionSettings(0);
settings.clockFrequency = 2 * Math.pow(10, 7);
settings.mode = Spi.SpiMode.mode0;

var ags = Spi.SpiDevice.getDeviceSelector();


Enumeration.DeviceInformation.findAllAsync(ags, null).done(dis => {
    Spi.SpiDevice.fromIdAsync(dis[0].id, settings).done(device => {
        for (; ;) {
            var value = offset + amplitude * Math.sin(2 * Math.PI * frequency * time);
            var dacValue = parseInt(resolution / voltage * value);
            if (dacValue > resolution) dacValue = resolution;
            time += updateFreq;
            if (time > 1000) time = 0;
            var buffer = new Uint8Array(2);

            buffer[0] = 0x30 | (dacValue >>> 8);
            buffer[1] = 0xFF & dacValue;

            device.write(buffer);
        }
    });
});

Я пытался использовать setInterval, я знаю, что это не очень хорошая практика, он ждет не менее 10 мс, прежде чем снова запустится.

Есть ли способы изменить таймер малины, часы или что-то еще, чтобы запускать пользовательскую функцию прерывания ISR каждые 0,1 мс?

Я уже просмотрел регистры dma в Техническое описание BCM2835 и BCM2836 Техническое описание техническое описание. Я не могу найти решения, как управлять прерываниями часов Raspberry Pi, только при прерываниях контактов.

Я также знаю, как это сделать в Arduino Uno, но мне это не поможет, так как я не знаю, как манипулировать регистрами малины.

Вот изображение сгенерированной синусоиды.

Синусоида

Заранее спасибо.


person EspeH    schedule 28.11.2016    source источник


Ответы (1)


  • #P1# <блочная цитата>
            var value = offset + amplitude * Math.sin(2 * Math.PI * frequency * time);
            var dacValue = parseInt(resolution / voltage * value); 
    
    #P2#
  • Если вы намерены вычислить значение синусоиды, подсчитав прошедшее время, я не думаю, что вам следует использовать

             `time += updateFreq;`
    

    в первую очередь. Таким образом, вы рассчитываете на синхронизацию программного обеспечения, и вы можете получить серьезно искаженные формы сигналов. Я бы посоветовал использовать таймер.

  • Windows IoT не является операционной системой реального времени. Даже при использовании таймера с высоким разрешением он не может повторять операции с чрезвычайно точными интервалами (‹1 мс) из-за неопределенности синхронизации программного обеспечения.

    Я не думаю, что прерывание ISR может решить вашу проблему, потому что оно также реализовано на уровне ОС.

    Как вы упомянули, вы можете попробовать использовать режим DMA SPI. Но, к сожалению, кажется, что нет подходящего драйвера для управления регистрами SPI DMA, связанными с Raspberry, как в ядре Arduino, так и в ядре Windows IoT. Таким образом, вам может понадобиться написать драйвер самостоятельно. Речь идет об разработке драйверов устройств для платформы Microsoft Windows. Pwm — это драйвер BCM2836, использующий DMA в ядре Windows IoT. можно сослаться.

person Rita Han    schedule 29.11.2016