(?) Небольшой вопрос по С

Обсуждаем контроллеры компании Atmel.
Johnson
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25
Контактная информация:

(?) Небольшой вопрос по С

Сообщение Johnson »

Здравствуйте, уважаемые коты!

Простите за вопрос не совсем по теме контроллеров, но по близкой...

Скажите, почему не работает следующий код:

Код: Выделить всё


PORTD = 0b11000011;
tmp=0;

while(1){
  tmp++;
  if (tmp>3)tmp=0;
  PORTD = PORTD & (0b11000011 | (1<<(2+tmp)) );
}
В теории это должно вызвать "бегущий огонь" диодов, подключенных к portd.2-portd.5, не трогая остальные выводы...
На практике творится что попало.

Либо, подскажите другой способ, пожалуйста.
Только просьба, тупой перебор битов порта не предлагать. Нужно именно по формуле, смещая огонек в зависимости от значения tmp...

PS: Компилятор CVAVR
PPS: Не знаю, важно ли это, но PORTD = PORTD & (0b11000011 | (1<<(2+tmp)) ); вызывается из прерывания таймера.
Реклама
Аватара пользователя
romazan
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Чт май 21, 2009 13:54:07
Откуда: Москва
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение romazan »

Код: Выделить всё

int main()
{
  unsigned char tmp=0;
  DDRD = 0b00111100;
  while(1)
  {
    tmp++;
    if (tmp>3)tmp=0;
    PORTD = 0b00111100 ^ (1<<(2+tmp));
    _delay_ms(1000);
  }
}
Вот. Как-то так.
Последний раз редактировалось romazan Ср авг 01, 2012 14:50:39, всего редактировалось 1 раз.
Реклама
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение pyzhman »

2romazan:
Тогда уж

Код: Выделить всё

PORTD = 0b00111100 ^ (1<<(2+tmp));
Docendo discimus
Аватара пользователя
romazan
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Чт май 21, 2009 13:54:07
Откуда: Москва
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение romazan »

согласен, забыл :kill: :))
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Goldsmith »

Johnson писал(а):Либо, подскажите другой способ, пожалуйста.
Попробуйте что-то вроде:

Код: Выделить всё

...
unsigned char mask;
...
for (;;)
  for (mask = 0b00000100; mask <= 0b00100000; mask <<= 1)
  {
    PORTD |= mask; // включить
    pause(); // сделать паузу, чтобы зафиксировать текущую позицию
    PORTD &= ~mask; // погасить
  }
Функцию pause() реализуйте по собственному вкусу. Само собой, задержка не должна находиться в обработчике прерывания таймера.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Реклама
Johnson
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Johnson »

PORTD = 0b00111100 ^ (1<<(2+tmp));
Не пойдет по одному из требований - необходимо, чтоб ноги 0,1,6,7 не изменили текущего состояния.

PORTD &= ~mask;
А вот над этим уже можно подумать, спасибо!

PS: мне не нужен конкретно бегущий огонь, паузы и всё такое.
Просто в своем примере я упростил код для понимания.
Мне нужно управлять ногами 2-5 в зависимости от значения переменной (сдвигать бит на значение переменной, но относительно второго бита порта, но не больше 5-го бита включительно).
В схеме даже диодов нет...
Реклама
Johnson
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Johnson »

Всё, разобрался... Вопрос отменяется, спасибо большое всем, кто откликнулся!

Код: Выделить всё

PORTD = (PORTD & 0b11000011) | (1<<2+tmp2);
Затупил в логике, нудо было сначала обнулить нужные биты, а потом уже ИЛИ по маске производить.
А я производил И по маске, ничтоже сумнящийся, что в порте будут лог1 на нужных битах :)

PS: Можно даже подправить так на всякий случай, чтоб эта единица за пределы не вышла по ошибке...:
PORTD = (PORTD & 0b11000011) | ((1<<2+tmp2) & 0b00111100);
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Goldsmith »

Johnson писал(а):Мне нужно управлять ногами 2-5 в зависимости от значения переменной (сдвигать бит на значение переменной, но относительно второго бита порта, но не больше 5-го бита включительно).
Тогда такой небольшой джентльменский набор:

Код: Выделить всё

static uint8_t mask(uint8_t n)
{
  return ((1 << (n+2)) & 0b00111100);
}

void bit_set(uint8_t n)
{
  PORTD |= mask(n);
}

void bit_clear(uint8_t n)
{
  PORTD &= ~mask(n);
}
Тип uint8_t определить самостоятельно, если не поддерживается вашим компилятором.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Johnson
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Johnson »

Спасибо большое, пригодится!

Да, это переменная в CVAVR значится как unsigned char X;
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение BCluster »

В кодвижне есть фича можно непосредственно к битам порта обращаться: PORTD.1 PORTD.2 и т.д.
Устанавливать и снимать бит просто PORTD.1 = 1; PORTD.1 = 0;
Учтите что это костыли, в стандарте такого нет, а в кодвижне есть )
Успехов
clawham
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение clawham »

А почему это костыль обращение к битам??????

а что же такое тогда асмовая комманда

из даташита

Код: Выделить всё

SBI P,b Set Bit in I/O Register I/O(P,b) ← 1 None 2
CBI P,b Clear Bit in I/O Register I/O(P,b) ← 0
а интерпретатор или эту команду ставит или просто логик если нет аткого в ядре..но помоему даж в тине 13 есть

Код: Выделить всё

All ATmega8 I/Os and peripherals are placed in the I/O space. The I/O locations are accessed
by the IN and OUT instructions, transferring data between the 32 general purpose working registers
and the I/O space. I/O Registers within the address range 0x00 - 0x1F are directly bitaccessible
using the SBI and CBI instructions. In these registers, the value of single bits can be
checked by using the SBIS and SBIC instructions.
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Johnson
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Johnson »

BCluster, не понимаю, к чему Вы...
Вы мои посты и примеры кода не читали вообще?

Во-первых, проблема уже решена логикой, а не костылями.
Во-вторых, я писал, что меня не устроит решение на побитном обращении...
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение BCluster »

clawham писал(а):А почему это костыль обращение к битам??????

а что же такое тогда асмовая комманда
Ничего не имею против асмовой команды ) Я говорю к тому, что данное обращение не является стандартным и непереносимо, вот и все :)
Johnson писал(а):Во-первых, проблема уже решена логикой, а не костылями.
Решена и решена, а кому-то может пригодится то о чем я написал. Вы свой ответ уже получили - чего злитесь? :)))
Johnson
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Johnson »

Решил не создавать новую тему...

Скажите, пожалуйста, как можно число (int) преобразовать в строку?

И ещё...
Может быть, у кого-нибудь есть готовый код, который позволит число из переменной вывести большими цифрами на LCD дисплее в нужном месте?
Дисплей WG12232, 122*32, по горизонтали разделен на 4 страницы (строки).
Нужен вывод цифры (а точнее двухзначного числа) на высоту всего дисплея.
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Goldsmith »

Johnson писал(а):Скажите, пожалуйста, как можно число (int) преобразовать в строку?
Нестандартная, но широко распространенная функция:

Код: Выделить всё

void* itoa(int input, char *buffer, int radix)
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Johnson
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Johnson »

А пример использования можно?
Не очень представляю, как нужно организовать буфер, и что есть 3й аргумент...
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Goldsmith »

Вот здесь достаточно подробно, и вроде на первый взгляд ошибок не заметил.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение BCluster »

А есче можно printf() иcпользовать... или sprintf(). Жрет память программ.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение BCluster »

3 аргумент это вроде как база системы счисления... И если я правильно помню он не во всех реализациях есть вообще.
буфер можете сразу по разрядности числа сделать.
Скажем если 2 разряда то

Код: Выделить всё

#define BASE  10
unsigned char buf[3];
unsigned char digit;
itoa ( digit, buf, BASE );
Последний раз редактировалось BCluster Пт авг 03, 2012 08:50:59, всего редактировалось 1 раз.
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: (?) Небольшой вопрос по С

Сообщение Goldsmith »

BCluster писал(а):Скажем если 2 разряда то

Код: Выделить всё

...
unsigned char buf[2];
...
itoa ( digit, buf, BASE );
Классическая реализация от Кернигана/Ритчи дописывает в конец строки еще и '\0'. Вполне вероятно, что остальные делают то же самое (хотя для нестандартной функции наверняка ничего утверждать нельзя). Поэтому для 2-разрядного числа лучше все же заложить буфер длиной не меньше 3 байт, чтобы не наступить на одни из наиболее популярных "сишных" граблей.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Ответить

Вернуться в «AVR»