Чтение цифровых выводов и вывод на целые порты

Я новичок в программировании, поэтому, пожалуйста, не допрашивайте меня.

Я работаю над научным проектом, в котором использую NI-DAQ для цифрового запуска МОП-транзисторов для запуска импульсов длительностью 300 мкс - 3 мс на двух мощных светодиодных матрицах. Я намерен использовать Arduino UNO для передачи одного цифрового выхода на множество. По-прежнему важно использовать NI-DAQ, поскольку импульсы зависят от видеосигналов и других выходов, иначе импульсы будут генерироваться исключительно Arduino.

Для этого я решил использовать вывод Port Port reg, поскольку он имеет наибольшую временную точность, но мне очень сложно получить один вывод для запуска порта. Буду очень признателен за помощь.

Мой код сейчас выглядит так:

int inpin = 2; //вход указан как контакт 2
int x = 0; // переменная для хранения прочитанного значения


void setup() {
pinMode(inpin, INPUT); //устанавливает цифровой вывод 13 в качестве входа
DDRD=B11111111; //контакты 8-13 находятся в режиме вывода
DDRC=B11111111; //пин A0-5 назначен выходу
}

void loop() {
x = digitalRead(inpin); //читаем входной контакт
if (inpin = HIGH) PORTB=B11111111; // если на цифровом входе высокий уровень, все порты Bport имеют высокий уровень
if (inpin = HIGH) PORTC=B11111111; // если на цифровом входе высокий уровень, все Cport имеют высокий уровень
if (inpin != HIGH) PORTB=B00000000; // если на цифровом входе низкий уровень, все порты Bport имеют низкий уровень
if (inpin != HIGH) PORTC=B00000000; // если на цифровом входе низкий уровень, все Cport имеют низкий уровень

}

В настоящий момент кажется, что плата считывает входные данные, но неправильно передает выходные данные: PORTB постоянно выключен, а PORTC постоянно включен. Любая помощь будет здорово!

, 👍1

Обсуждение

Если ваша цель — просто повторить ввод, почему бы не использовать микросхему, предназначенную для этой задачи. Их обычно называют буферами., @ratchet freak

Проверьте распиновку Arduino. Казалось бы, вы перепутали порты B и D., @Edgar Bonet

Спасибо, Эдгар, я исправил опечатку в области настройки. Теперь оба B и C горят постоянно., @JTS

Согласен с Рэтчетом. Если вы просто хотите повторить цифровой ввод, используйте буферный корабль. Они реагируют за однозначные наносекунды, без необходимости программирования. Чипы Arduino относительно медленны., @Duncan C


2 ответа


Лучший ответ:

2

У вас есть ошибки в кодировании. Вероятно, вы хотели написать что-то вроде:

void loop() {
  x = digitalRead(inpin); //читаем входной контакт
  if (x == HIGH) PORTB=B11111111; // если на цифровом входе высокий уровень, все порты Bport имеют высокий уровень
  if (x == HIGH) PORTC=B11111111; // если на цифровом входе высокий уровень, все Cport имеют высокий уровень
  if (x != HIGH) PORTB=B00000000; // если на цифровом входе низкий уровень, все порты Bport имеют низкий уровень
  if (x != HIGH) PORTC=B00000000; // если на цифровом входе низкий уровень, все Cport имеют низкий уровень
}

Это можно упростить до:

void loop() {
if (digitalRead(inpin) == HIGH)
{
  PORTB=B11111111; // если на цифровом входе высокий уровень, все порты Bport имеют высокий уровень
  PORTC=B11111111; // если на цифровом входе высокий уровень, все Cport имеют высокий уровень
}
else
{
  PORTB=B00000000; // если на цифровом входе низкий уровень, все порты Bport имеют низкий уровень
  PORTC=B00000000; // если на цифровом входе низкий уровень, все Cport имеют низкий уровень
}
}
,

Удивительный! Спасибо, я некоторое время боролся с этим. Я думал, что оператор else будет уместен, но не знал как! Ваше здоровье, @JTS


0

Если вы выполняете такого рода низкоуровневые манипуляции с портами, я предлагаю вам откажитесь от ядра Arduino и идите по пути avr-libc:

#include <avr/io.h>

int main(void)
{
    DDRB = 0xff;  // весь порт B как выход
    DDRC = 0xff;  // весь порт C как выход
    DDRD = 0;     // весь порт D как вход
    for (;;) {
        if (bit_is_set(PIND, PD2)) {  // если PD2 читает HIGH
            PORTB = 0xff;  // весь порт B переходит в ВЫСОКИЙ уровень
            PORTC = 0xff;  // то же самое для порта C
        } else {
            PORTB = 0;     // весь порт B переходит в НИЗКИЙ уровень
            PORTC = 0;     // то же самое для порта C
        }
    }
}

В результате компилируется очень эффективный код, который требует максимум 7 процессоров. циклов на итерацию цикла. Напротив, вызов digitalRead() может занимают сотни циклов, что значительно увеличивает задержку программы.

Очевидно, что буфер все равно будет намного лучше с точки зрения задержки, поскольку отметил в комментарии храповик.

,

Я тоже рассмотрю этот вариант. Хотя задержка важна. В моем проекте наиболее важно, чтобы каждый вывод в порту синхронизировался с остальными выводами в том же порту. Я считаю, что этого подхода, аналогичного буферному, будет достаточно. Спасибо, @JTS