Вывод переменной в два порта
- Войдите на сайт для отправки комментариев
Вс, 18/02/2018 - 15:11
Что то я совсем затупил.
Есть Нано у которой на выходах D5 - D12 собран простой ЦАП на резисторах.
Эти выходы относятся к PORTB и PORTD.
Есть байтовая переменная которую надо вывести в ЦАП.
Если разбить переменную на биты и побитно выводить их в соответствующие разряды портов то все работает. А вот при попытке вывести переменную или в порт пишется не то что должно, или вообще не пишется. Пробовал по разному, но вот такой, к примеру, вариант вроде бы правильный и не работает как надо.
// младший разряд ЦАП в D5 Nano // старший разряд ЦАП в D12 Nano // порты настроены на выход byte out1 PORTB = (PORTB & B11100000) | out1>>3; // D5-D7 PORTD = (PORTD & B00011111) | out1<<5; //D8-D12
Что не так?
Что не так?
Не так поставлена задача.
1.
Напишите законченный код строк на 10 (больше тут и не надо), который можно запустить. Код должен выводить в порты значение, затем читать уровни на пинах digitaRead'ом (ему плевать, что они "на выход"), и печатать их в монитор порта.
2.
Приведите полный код и копипасту с монитора порта.
3.
Напишите, что Вы ожидали увидеть на пинах и чем это отличается от того, что мы видим в мониторе порта.
Кстати, не удивлюсь, если при выполнении п.п. 2 и 3 Вы сами всё поймёте и снимете вопрос.
В том виде, как Вы написали абсолютно невозможно понять что у Вас не так, т.к. мы не знаем что Вы хотите получить на выходе.
Не надо out сдвигать. Он и так чудно помещается на своиместа без сдвига.
volatile byte U_now; void setup() { // Запуск АЦП в непрерывном режиме с прерываниями по готовности результата ADCSRB=0; // Постоянное преобразование (Free Running mode) ADMUX=B01100000; // +5В ИОН, 8-битный результат в регистре ADCH, чтение с пина A0 ADCSRA=B11101011; // АЦП включить, преобразование разрешить, автоматический режим, прерывания разрешить, предделитель 8 (9мкс на преобразование) Serial.begin(9600); } void loop() { unsigned long Timer_1 = millis()%1000; if ( !Timer_1 ) { Serial.print(" U_now "); Serial.println(U_now, BIN); PORTB = (PORTB & B11100000) | U_now>>3; PORTD = (PORTD & B00011111) | U_now<<5; Serial.print(" PORTB "); Serial.println(PORTB, BIN); Serial.print(" PORTD "); Serial.println(PORTD, BIN); Serial.println(); } } ISR(ADC_vect) { U_now = ADCH; }АЦП добавлен чтобы создать нагрузку как то приближенную к реальной.
Значения в портах не соответствуют выводимым в них.
На реальном устройстве монитор порта включить не могу, там эти выводы заняты и монитор нарушит работу схемы. Но по напряжению на выходе ЦАП и уровням на его пинах видно что там не то что должно быть.
Давайте Вы уберёте ADC, а своё u_now будете, например, из того же монитора порта вводить? Ну или хотя бы прерывания запретите перед строкой 17 и до строки 20.
А то сейчас, никто не может гарантировать, что, например, между строками 17 и 18 (или 18 и 19) Ваше U_now не поменяетеся. Понимаете проблему? Очень весело получится. напечатали в строке 17 одно, а работаем с другим. Или в строке 18 часть битов взяли от одного числа, а в строке 19 - уже от другого.
volatile byte U_now; void setup() { // Запуск АЦП в непрерывном режиме с прерываниями по готовности результата ADCSRB=0; // Постоянное преобразование (Free Running mode) ADMUX=B01100000; // +5В ИОН, 8-битный результат в регистре ADCH, чтение с пина A0 ADCSRA=B11101011; // АЦП включить, преобразование разрешить, автоматический режим, прерывания разрешить, предделитель 8 (9мкс на преобразование) Serial.begin(9600); } void loop() { unsigned long Timer_1 = millis()%1000; if ( !Timer_1 ) { byte dumb = U_now; Serial.print(" U_now "); Serial.println(dumb, BIN); PORTB = (PORTB & B11100000) | dumb<<5; PORTD = (PORTD & B00011111) | dumb>>3; Serial.print(" PORTB "); Serial.println(PORTB, BIN); Serial.print(" PORTD "); Serial.println(PORTD, BIN); Serial.println(); } } ISR(ADC_vect) { U_now = ADCH; }На счет того, что U_now может изменяться пока выполняется вывод в порты я уже тоже подумал. Это и было причиной. В этом варианте оно фиксируется в переменной, а уже она потом выводится. И теперь стало работать правильно.
Спасибо!
Не за что.
Помните, я Вам говорил: "не удивлюсь, если при выполнении п.п. 2 и 3 Вы сами всё поймёте и снимете вопрос" - тот самый случай.
Это, кстати, общий подход - вычленить "чистую / рафинированную" проблему, отбросив всё лишнее. Пока это делаешь, часто проблема-то и исчезает. Ну и для вопроса на форуме это лучше сделать (выделить читстую проблему). А уж тогда задавать вопрос, если проблема не исчезла. Потому что очень часто, если проблему не выделать, то это значит заставлять заниматься выделением того, кто решил помочь.
Бывает что взгляд со стороны сразу видит то что уже замыленный проблемой глаз пропускает. Поэтому на форуме тоже полезно спросить.