UART(Serial) и ATtiny2313

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Использую Arduino библиотеки при программировании возникла такая проблема. При получении "1" с Serial, необходимо инвертировать байт. Ну этого не получается

Вот мой код

//int incomingByte = 0;   // переменная для хранения полученного байта
//#define pinw 4
int main() {
  Serial.begin(9600); // устанавливаем последовательное соединение
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  while (1) {
    int a = Serial.read();
    if (a = 1) {
      PORTB |= (1 << 5);
    }
    if (a = 2) {
      PORTB |= (1 << 4);
    }
  }
  return 0;
}

Где может быть проблема?

T.Rook
Онлайн
Зарегистрирован: 05.03.2016

При получении "1" с Serial, Вы устанавливаете пятый бит порта В в "1" (12 строка кода). О каком инвертировании какого байта  Вы говорите?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Apocalyps пишет:

Использую Arduino библиотеки при программировании возникла такая проблема. При получении "1" с Serial, необходимо инвертировать байт. Ну этого не получается

Какой байт Вы собираетесь инвертировать? В каком месте? Пока я вижу, что Вы собираетесь при получении 1 выставить пятый бит порта B (если у Вас UNO, то это цифровой пин 13) в HIGH. А при получении 2 - четвёртый бит (цифровой пин 12)

И кстати, Вы именно 1 шлёте из сериала? Или символ 1 с клавиатуры вводите? Если символ, то и сравнивайте с символом

if (a = '1')

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Вообщем беда всё такая же. Уже вроде и в правильную сторону двигаюсь. Но все равно

int main() {
  int a = 0;
  Serial.begin(9600); // устанавливаем последовательное соединение
  DDRB |= (1 << 4);     // устанавливаем вывод PB4 как выход
  DDRB |= (1 << 5);     // устанавливаем вывод PB5 как выход
  PORTB |= (1 << 5);  // устанавливаем высокий уровень на выводе PB5
  PORTB |= (1 << 4);  // устанавливаем высокий уровень на выводе PB4
  while (1) {
    if (Serial.available() > 0) {
      a = Serial.read();
      if (a = '1') {
        PORTB = ~(1 << 5); //инверсия пятого байта
      }
      if (a = '2') {
        PORTB = ~(1 << 4); //инверсия четвёртого байта

      }
    }
  }
  return 0;
}

 

xDriver
xDriver аватар
Онлайн
Зарегистрирован: 14.08.2015

Пытаемся уйти от языка Wiring используя прямую запись в регистры, а бит от байта не отличаем.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

xDriver пишет:

Пытаемся уйти от языка Wiring используя прямую запись в регистры, а бит от байта не отличаем.

 я вас понял, нашел косяк в комментариях

xDriver
xDriver аватар
Онлайн
Зарегистрирован: 14.08.2015

ну а по делу, с чем вы производите действие  ~(1 << 5);

мне кажется с пустотой.

__Alexander
Offline
Зарегистрирован: 24.10.2012

по делу сравнение с двумя =

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Почему пустота? Вроде с пятым битом порта B произвожу операции. Нарыл мануалы на побитовые операции, вроде я всё верно делаю

xDriver
xDriver аватар
Онлайн
Зарегистрирован: 14.08.2015

Первый вариант был правильный но операция не верная, всегда будет единица в пятом бите т.к. иоспользуете ИЛИ.

И да про сравнение правильно подметили, я как то пропустил.

Jeka_M
Jeka_M аватар
Онлайн
Зарегистрирован: 06.07.2014

А если так: PORTB ^= (1 << 5); //инвертируем пятый бит

http://chipenable.ru/index.php/programming-avr/item/4-uchebnyy-kurs-kak-...

Ну и про сравнение выше написали: if (a == '1')

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Apocalyps,

Есть несколько вариантов как сбросить один бит из байта. Выучите наизусть хотя бы один :-)

PORTB&=B11101111;
PORTB&=~(1<<PB5);
PORTB&=~bit(PB5);
PORTB&=~_BV(PB5);
bitClear(PORTB,PB5);
bitWrite(PORTB,PB5,0);

 

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Вроде уже по всем канонам, но что-то опять не ладится

int main() {
  int a;
  Serial.begin(9600); // устанавливаем последовательное соединение
  DDRB |= (1 << 4);     // устанавливаем вывод PB4 как выход
  DDRB |= (1 << 5);     // устанавливаем вывод PB5 как выход
  PORTB |= (1 << 5);  // устанавливаем высокий уровень на выводе PB5
  PORTB |= (1 << 4);  // устанавливаем высокий уровень на выводе PB4
  while (1) {
    a = Serial.read();
    if (a == '1') {
      PORTB &= ~(1 << 5); //инверсия пятого бита
    }
    if (a == '2') {
      PORTB &= ~(1 << 4); //инверсия четвёртого бита
    }
  }
  return 0;
}

 

xDriver
xDriver аватар
Онлайн
Зарегистрирован: 14.08.2015

ну вам написали уже

ДЛЯ ИНВЕРСИИ БИТА 

PORTB ^= (1 << 5); //инвертируем пятый бит

Jeka_M
Jeka_M аватар
Онлайн
Зарегистрирован: 06.07.2014

dimax пишет:

Есть несколько вариантов как сбросить один бит из байта. Выучите наизусть хотя бы один :-)

Дык ему не сбросить надо, а инвертировать. Не путайте человека :-)

Jeka_M
Jeka_M аватар
Онлайн
Зарегистрирован: 06.07.2014

У меня нубский вопрос: если мы символы получаем, тип переменной разве не char должен быть?

xDriver
xDriver аватар
Онлайн
Зарегистрирован: 14.08.2015

Нет.

Serial.read возвращает int, а нужен int только для того что бы вернуть -1, если там ничего нет.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Короче я так понимаю, не у кого идей нет, почему оно не хочет работать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Apocalyps пишет:

Короче я так понимаю, не у кого идей нет, почему оно не хочет работать?

Блин, так Вам же сказали! Вы не читаете?

Текущий скечт из поста №12? Так?

Ну, Вам же объяснили, что в строках 11 и 14 вовсе не инверсия, а установка в LOW.

Сделайте нормальную инверсию. И если не поможет:

1. Опубликуйте текущий скетч

2. Скажите, наконец, а как оно работает - что происходит.

 

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Вот текущий скетч

int main() {
  int a;
  Serial.begin(9600); // устанавливаем последовательное соединение
  DDRB |= (1 << 4);     // устанавливаем вывод PB4 как выход
  DDRB |= (1 << 5);     // устанавливаем вывод PB5 как выход
  PORTB |= (1 << 5);  // устанавливаем высокий уровень на выводе PB5
  PORTB |= (1 << 4);  // устанавливаем высокий уровень на выводе PB4
  while (1) {
    a = Serial.read();
    if (a == '1') {
      PORTB ^= ~(1 << 5); //инверсия пятого бита
    }
    if (a == '2') {
      PORTB ^= ~(1 << 4); //инверсия четвёртого бита
    }
  }
  return 0;
}

Собственно когда приходят 1 и 2 на RXD, ничего вообще не происходит. Я начинаю подозревать, что что-то именно с UART

nevkon
Онлайн
Зарегистрирован: 20.01.2015

Очень рассмешили. Вам компилятор такое позволяет? Перевожу дословно:

Если ЧИСЛО а = СИМВОЛУ '1'

Уже помираю - исправьте.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nevkon пишет:

Очень рассмешили. Вам компилятор такое позволяет? Перевожу дословно:

Если ЧИСЛО а = СИМВОЛУ '1'

Уже помираю - исправьте.

Не помирайте! Срочно дуйте в реанимацию! Абсолютно нормальная конструкция. Читате Кернигана и Ритчи.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Apocalyps пишет:

Вот текущий скетч

int main() {
  int a;
  Serial.begin(9600); // устанавливаем последовательное соединение
  DDRB |= (1 << 4);     // устанавливаем вывод PB4 как выход
  DDRB |= (1 << 5);     // устанавливаем вывод PB5 как выход
  PORTB |= (1 << 5);  // устанавливаем высокий уровень на выводе PB5
  PORTB |= (1 << 4);  // устанавливаем высокий уровень на выводе PB4
  while (1) {
    a = Serial.read();
    if (a == '1') {
      PORTB ^= ~(1 << 5); //инверсия ВСЕХ БИТОВ, КРОМЕ пятого
    }
    if (a == '2') {
      PORTB ^= ~(1 << 4); //инверсия ВСЕХ БИТОВ, КРОМЕ четвёртого 
    }
  }
  return 0;
}

Собственно когда приходят 1 и 2 на RXD, ничего вообще не происходит. Я начинаю подозревать, что что-то именно с UART

Я поправил комментарии в Вашем коде - посмотрите. Так они больше соответсвуют действительности :)

Сделайте, наконец, правильно, как Вам написал коллега в посте №10

Вам всё правильно написали, Вы же почему-то этого не делаете и жалуетесь, что никто не помогает.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

а я пробовал, тоже не работает

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Apocalyps пишет:

а я пробовал, тоже не работает

Что Вы пробовали? Нормальную инверсию? Так зачем поменяли? Методом тыка отлаживаемся? 

Хорошо, что у Вас за Ардуина?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Apocalyps пишет:

Собственно когда приходят 1 и 2 на RXD, ничего вообще не происходит. Я начинаю подозревать, что что-то именно с UART

А с чего будет что-то происходить? У вас ни одной функции для обработки Serial не подключено.. И в инверсии кстати опять ошибка.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Эм...вроде всё по мануалам делал. На отправку UART работал, а вот на приём неизвестно работает или нет

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Apocalyps, ну сделайте хотя бы по-ардуиновски, с секциями setup и loop, тогда если стоит поддержка ядра tiny2313 нужные библы точно подтянутся. Вот так на обычной дуне работает:

void setup() {
Serial.begin(9600); // устанавливаем последовательное соединение
DDRB |= (1 << 4);     // устанавливаем вывод PB4 как выход
DDRB |= (1 << 5);     // устанавливаем вывод PB5 как выход
PORTB |= (1 << 5);  // устанавливаем высокий уровень на выводе PB5
PORTB |= (1 << 4);  // устанавливаем высокий уровень на выводе PB4
}

void loop() {
  if (Serial.available() > 0) {  
     uint8_t a = Serial.read();
     if (a == '1') { PORTB ^= 1 << 5; //инверсия пятого бита
     }
     if (a == '2') { PORTB ^= 1 << 4; //инверсия четвёртого бита
     }
   } //конец если сериал доступен..
 } // конец луп

 

Apocalyps
Offline
Зарегистрирован: 26.07.2015

не работает =( Проверяю правда в протеусе, но тут вроде специфического кода нет, чтоб оно не работало

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Apocalyps, в протеусе не работает под какой МК ? Тот, что я дал точно работает под UNO, для tiny2313 нужно имплантировать ядро с поддержкой этого МК.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Ядро стоит. 2313,4313 и *5 поддерживаются в нём. А за протеус, я имеел ввиду что прошивка должна в нём работать

nevkon
Онлайн
Зарегистрирован: 20.01.2015

Я бы понял если бы это был тип byte или char. int будет нерационально, тем более в условиях малой памяти.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

памяти там ещё хватает

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nevkon пишет:

Я бы понял если бы это был тип byte или char. int будет нерационально, тем более в условиях малой памяти.

Выжил? Ну и славно. Расслабься уж. Иногда лучше жевать, ...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Apocalyps,

я спросил у Вас, что у Вас за устройство. Вы игнорируете.

Вопрос остаётся в силе, но добавляется ещё один: Откуда в сериале берутся 1 и 2. Вывводите руками из монитора порта или программа какая шлёт?

Ответьте на оба вопроса

И пожалуйста, поправьте код инвертирования.

Или Вы делаете, что Вам говорят и отвечаете на вопросы или помогайте себе сами.

Apocalyps
Offline
Зарегистрирован: 26.07.2015

Устройство для коммутирования двух нагрузок. 1 и 2 приходит по UART с attiny13. Код инвертирования менял, ничего толком не дало

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Apocalyps пишет:

Устройство для коммутирования двух нагрузок. 1 и 2 приходит по UART с attiny13.

Так, мой вопрос "что у Вас за Ардуина?" проигнорирован?

Apocalyps, я действительно хочу Вам помочь. Но это невозможно, если Вы не отвечаете на вопросы и не делаете то, что Вам говорят. Давайте, так, я соберу все вопросы в кучу, а Вы уж сами решайте. работаем мы дальше или нет - если не будет ответов на все - решайте свои проблемы самостоятельно.

1. Что у Вас за Ардуино? Могу переформулировать, у Вас есть ещё один сериал, куда Вы можете что-нибудь напечатать Serial.print'ом и посмотреть монитором порта или нет?

2. Так, с attiny13. Хорошо. Код отправки приведите пожалуйста (вопрос связан с тем, что я, например, не знаю, шлёт ли она число 1 или символ 1, и потому не знаю с чем правильно сравнивать с 1 или с '1').

Apocalyps пишет:

Код инвертирования менял, ничего толком не дало

Если это не единственная ошибка, это ещё не значит, что её не надо исправлять. Сейчас у Вас написан бред. Просто напишите правильный код. Чтобы при дальнейших экспериментах я был уверен, что здесь всё правильно. А то так, как сейчас, Вы не один бит инверитуруете, а "все, кроме него". И кстати,

3. выложите исправленный скетч, чтобы я был уверен, что с инвертированием  всё нормально.

 
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Отпишу тут, ибо на форуме "личка отсутствует как класс".

ЕвгенийП, вы писали про ошибку в строке 26 файла tsc.h .. там нет никакой ошибки, там дефайном определен множитель перевода миллисекунд в тики. Так и надо было в этом месте. :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Arhat109-2 пишет:

ЕвгенийП, вы писали про ошибку в строке 26 файла tsc.h .. там нет никакой ошибки, там дефайном определен множитель перевода миллисекунд в тики. Так и надо было в этом месте. :)

Не разочаровывайте меня. Я думал, что это случайный просмотр на уровне опечатки, а теперь начинаю думать, что Вы гораздо менее грамотны, чем кажетесь. Ваш множитель, определённый как

#define TSC_PERIOD      (1000/1024) 

попросту равен нулю в силу специфики целочисленной арифметики. Уверен, что не "так и надо было", а если "так и надо было", то почему не написали просто 0?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

:) Он не равен 0 даже в целочисленной арифметике. Это макропродстановка и в нормальном выражении он будет выглядеть так:

int time = 100*TSC_PERIOD; что после разворачивания макроса даст

int time = 100*(1000/1024); что после предвычисления компилятором константы даст 97,65625 что после преобразования компилятором к целой константе даст 97, что и требовалось. :)

Это пересчетный множитель когда лень вручную переводить миллисекунды в тики для константных вычислений на этапе компиляции. :)

Предполагалась его дальнейшая прямая связь с дефайнами настроки таймера времени .. оно не всегда может быть таким коэффициентом и вот в таком разе - очень даже полезно. Не досовмещал оба файла.. не понадобилось.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Arhat109-2 пишет:

:) Он не равен 0 даже в целочисленной арифметике. Это макропродстановка и в нормальном выражении он будет выглядеть так:

int time = 100*TSC_PERIOD; что после разворачивания макроса даст

int time = 100*(1000/1024); что после предвычисления компилятором константы даст 97,65625 что после преобразования компилятором к целой константе даст 97, что и требовалось. :)

А теперь делаем 1-2-3

1. вставили весь этот бред в код и проверили.

2. Получили 0

3. После этого можете разглагольствовать на тему о том, что компилятор кривой и что ещё весной, когда Вы читали стандарт языка, Вы отметили в нём много несуразностей (язык тоже кривой).

К сожалению,

ЕвгенийП пишет:
Вы гораздо менее грамотны, чем кажетесь. 
 
Кстати, писать надо было в той теме, в которой разговор начался, а не засорять эту.
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

странно, у меня вроде как работало .. :) Не нашел "ту тему".

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Arhat109-2 пишет:

странно, у меня вроде как работало .. :) Не нашел "ту тему".

Никогда это не работало и работать не могло. Попробуйте сейчас, чтобы убедиться, хотя, кажется, Вы уже попробовали.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ха, нашел тот код которым тогда тестировал!

#define TSC_PERIOD 1000/1024

#define pinHeart        pin4    // нога со светодиодом для плавного управления яркостью
#define WAIT_STEP       30*TSC_PERIOD      // тиков, 30 миллисекунд на 1 шаг изменения яркости
#define WAIT_CYCLE      160*TSC_PERIOD     // .., 160 миллисекунд паузы между повторением
#define WAIT_ON         100*TSC_PERIOD      // .., 100 мсек интервал включение контрольного светодиода (pinLed = 13)
#define WAIT_OFF        900*TSC_PERIOD     // .., 900 мсек интервал выключения контрольного светодиода

Есть таки небольшая "разница". Да, со скобками - не компиляется как надо. Похоже "улучшил" макрос когда переносил в файл. Пасибки.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Arhat109-2 пишет:

Ха, нашел тот код которым тогда тестировал!

#define TSC_PERIOD 1000/1024

#define pinHeart        pin4    // нога со светодиодом для плавного управления яркостью
#define WAIT_STEP       30*TSC_PERIOD      // тиков, 30 миллисекунд на 1 шаг изменения яркости
#define WAIT_CYCLE      160*TSC_PERIOD     // .., 160 миллисекунд паузы между повторением
#define WAIT_ON         100*TSC_PERIOD      // .., 100 мсек интервал включение контрольного светодиода (pinLed = 13)
#define WAIT_OFF        900*TSC_PERIOD     // .., 900 мсек интервал выключения контрольного светодиода

Есть таки небольшая "разница". Да, со скобками - не компиляется как надо. Похоже "улучшил" макрос когда переносил в файл. Пасибки.

До чего ж всё запущено-то! А если, не дай Бог, написать не

#define WAIT_CYCLE      160*TSC_PERIOD  

а

#define WAIT_CYCLE      TSC_PERIOD*160

опять ведь беда будет!

Да, я конечно понимаю, что прогер он прогер и есть, но настолько не знать языка на котором работаешь - это надо быть суперпрогером.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

:) Вы мне нравитесь. :)

Эта либа (автоматное программирование tsc.h, tsc.c) в целом писалась исключительно как пример оформления автоматного кода не силами макросов everyMillis, everyOVF .. и только (был тут срач прошлым летом)

Как оказалось, полезное применение (у меня) нашлось ровно одно: замер интервалов времени, подсчет энкодеров по прерываниям PCINT0..2. Все остальное оказалось вполне можно упихать в макросы автоматного программирования .. а эту часть tsc.h давно НАДО переписать под С++ .. вот там да, можно сделать все как полгается.. а так, лезть и что-то менять - влом. Не пользуйтесь этой фигней. На 90% потребностей закрывается файлом arhat.h :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Arhat109-2 пишет:

:) Вы мне нравитесь. :)

Взаимно

Arhat109-2 пишет:
Не пользуйтесь этой фигней.

Боже, упаси! Я, знаете ли, вообще никогда не пользуюсь ни либами, ни прогами. Мне вполне хватает библиотек и программ.

Arhat109-2 пишет:
НАДО переписать под С++ .. вот там да

Знаете, до Вашего поста №39 я был уверен, что это случайная ошибка уровня опечатки, которую не Вы заметили из-за свойственного всем прогерам небрежного тестирования. Но этот пост, к сожалению, развеял все мои сомнения в уровне Ваших знаний языка. Причём самых элементарных его конструкций. Так что, если Вы возьмётесь писать что-то с использованием шаблонов и енумераторов, ... в общем, успехов Вам!