CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Re: CodeVision AVR в вопросах и ответах

Сообщение dm211 »

Включать-выключать мне не надо таймер, хотя можно, но только от внешнего прерывания. Оно неправильно работает,кнопку нажал-генерация кончилась,отжал-тоже выключенный остается, потому что х =1 до выкл-вкл питания.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20091
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: CodeVision AVR в вопросах и ответах

Сообщение Gudd-Head »

Х в глобальные переменные, в прерывании поменять Х с 0 на 1 (или как там у вас) и по этому условию в программе не генерить. Не?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: CodeVision AVR в вопросах и ответах

Сообщение ChipKiller »

dm211 у Вас "кривой" алгоритм. Можно, конечно, написать

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

while (1)
      {
        x=0;       
      }
}
, но это как-то через жо...
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Re: CodeVision AVR в вопросах и ответах

Сообщение dm211 »

Нет так пробовал-бесполезно, сделал прервание по любому изменению и и заработало однако.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Re: CodeVision AVR в вопросах и ответах

Сообщение dm211 »

Ещё попутный вопрос- какова скорость действия этого прерывания, т.е. сколько времени пройдет от момента прихода сигнала на INT0 до прекращения генерации, если мк работает на 16 мгц?
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: CodeVision AVR в вопросах и ответах

Сообщение ChipKiller »

просто переключает 0 в 1 и 1 в 0 - в чем смысл?

уже писал раньше - напишите , что хотите получить
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Re: CodeVision AVR в вопросах и ответах

Сообщение dm211 »

Что хочу получить-типа защиты-получил сигнал от датчика и отключил выход.
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: CodeVision AVR в вопросах и ответах

Сообщение ChipKiller »

... какой вопрос - такой ответ.........
gis
Родился
Сообщения: 16
Зарегистрирован: Пт ноя 07, 2014 20:34:56

Re: CodeVision AVR в вопросах и ответах

Сообщение gis »

Подскажите можно ли следующую конструкцию записать короче?

PORTB.2 = b [a] & 1 ;
PORTB.0 = b [a] & (1<<1);
PORTB.3 = b [a] & (1<<2);
PORTB.5 = b [a] & (1<<3);
PORTB.4 = b [a] & (1<<4);
PORTB.1= b [a] & (1<<5);
PORTD.1 = b [a] & (1<<6);
Аватара пользователя
Wolf_X
Открыл глаза
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Re: CodeVision AVR в вопросах и ответах

Сообщение Wolf_X »

Помогите с проблемой: На семисегментник с порта В выводится температура. Были задействованы выводы кроме 4, так как была отломана ножка. Теперь понадобился вывод под управление реле, подпаялся к отломаной. Но на нем программно висит 1 и не меняется. Как вывести число в порт не изменяя значение PORTB.4

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

#define At   1
#define Bt   2
#define Ct   4
#define Dt   8 
//Пропущен вывод PORTB.4
#define Et   32
#define Ft   64
#define Gt   128

static flash unsigned char digits1[] = {
        ~(At+Ft+Bt+Ct+Dt+Et), // 0
        ~(Bt+Ct),   // 1
        ~(At+Bt+Dt+Et+Gt),   // 2
        ~(At+Bt+Ct+Dt+Gt),   // 3
        ~(Ft+Bt+Ct+Gt),   // 4
        ~(At+Ft+Ct+Dt+Gt), // 5
        ~(At+Ft+Ct+Dt+Et+Gt), // 6
        ~(At+Bt+Ct),   // 7
        ~(At+Ft+Bt+Ct+Dt+Et+Gt), // 8
        ~(At+Ft+Bt+Ct+Dt+Gt), // 9
        ~(At+Ft+Bt+Ct+Et+Gt), // A - 10
        ~(Ft+Ct+Dt+Et+Gt),   // b - 11
        ~(At+Ft+Dt+Et), // C - 12
        ~(Bt+Ct+Dt+Et+Gt),   // d - 13
        ~(At+Ft+Dt+Et+Gt), // E - 14
        ~(At+Ft+Et+Gt), // F - 15
        ~(Gt),   // 16 - знак минус
        ~(At+Ft+Bt+Gt), // 17 - символ градус цельсия
};

А так выводится в прерывании
PORTB= digits1[digit_out1[cur_dig1]]; 
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

Wolf_X писал(а):Как вывести число в порт не изменяя значение PORTB.4
Сохранить его, затем восстановить. Делать всё через временную переменную, затем переменную после модификации отправлять в порт.
Аватара пользователя
Wolf_X
Открыл глаза
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Re: CodeVision AVR в вопросах и ответах

Сообщение Wolf_X »

А как ее модифицировать?
unsigned char temp;
temp=digits1[digit_out1[cur_dig1]];
temp=temp & 0b1110 1111, так я только буду тушить PORTB.4 а как его вообще не изменять не могу понять
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

Wolf_X писал(а):А как ее модифицировать?
А на словах "сохранить" и "восстановить" Вы не заострили внимание ? Только слово "модифицировать" понравилось ? :)
Отсюда и возникают повторные вопросы, типа :
а как его вообще не изменять не могу понять

Вникните в слова : "Сохранить и восстановить".
Аватара пользователя
Wolf_X
Открыл глаза
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Re: CodeVision AVR в вопросах и ответах

Сообщение Wolf_X »

Я думал что сохранить и восстановить это и есть модификация, но как это сделать не представляю. Пытаюсь вникнуть полдня, но все никак, оно и хотелось бы самому разобраться но нет никаких идей. Разве только сравнивать в прерывании условие включения реле на четвертом пине, и в зависимости от этого изменять вывод числа в порт но как то это неправильно
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

True-way работы с битами

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

uint8_t temp = PORTB;
temp |= (1<<4);
temp &= ~(1<<5);
PORTB = temp;

Non-true (CodeVision) way работы с битами:

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

PORTB.4 == 1;
PORTB.5 = 0;

Отсюда очевидно, что задача записи в порт, не трогая какой-то (четвёртый) его бит:

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

uint8_t temp = PORTB;
temp &= ~(1<<4); // очищаем все биты, кроме 4
temp |= data & ~(1<<4); // записываем в temp нужные данные, не затрагивая 4 бит
PORTB = temp; возвращаем значение в порт

В принципе, можно обойтись и двумя действиями напрямую с портом, не трогая переменные:

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

PORTB &= ~(1<<4); очищаем порт, кроме 4 бита
PORTB |= data & ~(1<<4); пишем туда данные, не трогая 4 бит

Но этот вариант чреват кратковременным появлением в порту нулей везде, кроме 4 бита. Да и быстрее этот вариант не будет, наверное.

P.S. Опечатался.
Нужно

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

temp &= (1<<4); // очищаем все биты, кроме 4
PORTB &= ~(1<<4); очищаем порт, кроме 4 бита
Последний раз редактировалось WiseLord Пн июн 08, 2015 06:05:35, всего редактировалось 1 раз.
Аватара пользователя
Wolf_X
Открыл глаза
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Re: CodeVision AVR в вопросах и ответах

Сообщение Wolf_X »

WiseLord писал(а):Отсюда очевидно, что задача записи в порт, не трогая какой-то (четвёртый) его бит:

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

uint8_t temp = PORTB;
temp &= ~(1<<4); // очищаем все биты, кроме 4
temp |= data & ~(1<<4); // записываем в temp нужные данные, не затрагивая 4 бит
PORTB = temp; возвращаем значение в порт



ЗАработало, только нужно так temp &= (~((1<<7)|(1<<6)|(1<<5)|(1<<3)|(1<<2)|(1<<1)|(1<<0))); // очищаем все биты, кроме 4
Спасибо за помощь!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

Wolf_X писал(а):только нужно так temp &= (~((1<<7)|(1<<6)|(1<<5)|(1<<3)|(1<<2)|(1<<1)|(1<<0))); // очищаем все биты, кроме 4
Вообще, это не очистка всех бит кроме 4-ого, а наоборот :)

Ещё вариант :

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

PORTB = digits1[digit_out1[cur_dig1]] | (PORTB.4 << 4) ;


ЗЫ: Зачем очищать все биты, если ненужные итак в массиве очищены ? Там установлены только те, сегменты которых нужно зажечь. Т.е. нужно просто копировать из массива в порт, а 4-ый в каждом элементе = 0. Соответственно, достаточно сделать "ИЛИ" с текущим значением.
Аватара пользователя
Wolf_X
Открыл глаза
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Re: CodeVision AVR в вопросах и ответах

Сообщение Wolf_X »

Аlex писал(а):
Ещё вариант :

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

PORTB = digits1[digit_out1[cur_dig1]] | (PORTB.4 << 4) ;


ЗЫ: Зачем очищать все биты, если ненужные итак в массиве очищены ? Там установлены только те, сегменты которых нужно зажечь. Т.е. нужно просто копировать из массива в порт, а 4-ый в каждом элементе = 0. Соответственно, достаточно сделать "ИЛИ" с текущим значением.

У меня ненужный бит в массиве установлен, там инверсия для общего анода

И по поводу битовых операций разбирался на разных сайтах:
Обнулить несколько битов можно так

temp = temp & (~((1<<6)|(1<<3)|(1<<1))); //обнуляем 6, 3 и 1 биты

Здесь сначала выполняются операции сдвига, потом операции поразрядного ИЛИ, затем инверсия, поразрядное И, присвоение результата переменной temp.

Используя составной оператор присваивания &= ,можно записать выражение более компактно

temp &= (~((1<<6)|(1<<3)|(1<<1)));

Сброс седьмого бита в регистре SREG будет выглядеть так:


SREG = SREG & (~ (1<<7)); или кратко: SREG &= ~ (1<<7);
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

Wolf_X писал(а):У меня ненужный бит в массиве установлен, там инверсия для общего анода
Не вижу по таблице никакой инверсии и 1-цы в 4-ом разряде.
Даже если это и так, то сделайте "тупо в лоб" :

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

if(PORTB.4)
  PORTB = digits1[digit_out1[cur_dig1]] | (1<<4);
else
  PORTB = digits1[digit_out1[cur_dig1]] & ~(1<<4);
или так (если нужно только сбрасывать бит) :

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

PORTB = digits1[digit_out1[cur_dig1]] & (PORTB.4 ? 0xFF : ~(1<<4));
или так (если, также, нужно только сбрасывать бит):

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

char temp = digits1[digit_out1[cur_dig1]];
if(!PORTB.4) temp &=~(1<<4);
PORTB = temp;
Или вообще, сделайте последовательную установку значений по каждому биту отдельно. Тогда можно будет задефайнить выводы в любом порядке, для быстрой смены их.

Вариантов море. И все они сводятся к одному - проверка неизменяемого бита (сохранение) с дальнейшей его установкой обратно (восстановление).
Аватара пользователя
Wolf_X
Открыл глаза
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Re: CodeVision AVR в вопросах и ответах

Сообщение Wolf_X »

Аlex писал(а):Даже если это и так, то сделайте "тупо в лоб" :

Спасибо большое, все три варианта рабочие, плюс вариант от WiseLord
Ответить

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