Страница 339 из 421

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

Добавлено: Ср июн 03, 2015 14:07:20
dm211
Включать-выключать мне не надо таймер, хотя можно, но только от внешнего прерывания. Оно неправильно работает,кнопку нажал-генерация кончилась,отжал-тоже выключенный остается, потому что х =1 до выкл-вкл питания.

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

Добавлено: Ср июн 03, 2015 14:12:32
Gudd-Head
Х в глобальные переменные, в прерывании поменять Х с 0 на 1 (или как там у вас) и по этому условию в программе не генерить. Не?

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

Добавлено: Ср июн 03, 2015 14:14:22
ChipKiller
dm211 у Вас "кривой" алгоритм. Можно, конечно, написать

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

while (1)
      {
        x=0;        
      }
}
, но это как-то через жо...

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

Добавлено: Ср июн 03, 2015 14:19:59
dm211
Нет так пробовал-бесполезно, сделал прервание по любому изменению и и заработало однако.

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

Добавлено: Ср июн 03, 2015 14:22:48
dm211
Ещё попутный вопрос- какова скорость действия этого прерывания, т.е. сколько времени пройдет от момента прихода сигнала на INT0 до прекращения генерации, если мк работает на 16 мгц?

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

Добавлено: Ср июн 03, 2015 14:24:14
ChipKiller
просто переключает 0 в 1 и 1 в 0 - в чем смысл?

уже писал раньше - напишите , что хотите получить

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

Добавлено: Ср июн 03, 2015 14:25:49
dm211
Что хочу получить-типа защиты-получил сигнал от датчика и отключил выход.

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

Добавлено: Ср июн 03, 2015 14:26:49
ChipKiller
... какой вопрос - такой ответ.........

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

Добавлено: Сб июн 06, 2015 13:14:49
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);

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

Добавлено: Вс июн 07, 2015 13:11:17
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]];  

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

Добавлено: Вс июн 07, 2015 13:28:28
Аlex
Wolf_X писал(а):Как вывести число в порт не изменяя значение PORTB.4
Сохранить его, затем восстановить. Делать всё через временную переменную, затем переменную после модификации отправлять в порт.

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

Добавлено: Вс июн 07, 2015 14:22:19
Wolf_X
А как ее модифицировать?
unsigned char temp;
temp=digits1[digit_out1[cur_dig1]];
temp=temp & 0b1110 1111, так я только буду тушить PORTB.4 а как его вообще не изменять не могу понять

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

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

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

Добавлено: Вс июн 07, 2015 20:31:59
Wolf_X
Я думал что сохранить и восстановить это и есть модификация, но как это сделать не представляю. Пытаюсь вникнуть полдня, но все никак, оно и хотелось бы самому разобраться но нет никаких идей. Разве только сравнивать в прерывании условие включения реле на четвертом пине, и в зависимости от этого изменять вывод числа в порт но как то это неправильно

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

Добавлено: Вс июн 07, 2015 20:58:28
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 бита

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

Добавлено: Вс июн 07, 2015 22:41:58
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
Спасибо за помощь!

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

Добавлено: Вс июн 07, 2015 23:09:47
А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. Соответственно, достаточно сделать "ИЛИ" с текущим значением.

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

Добавлено: Вс июн 07, 2015 23:50:19
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);

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

Добавлено: Пн июн 08, 2015 00:26:49
А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;
Или вообще, сделайте последовательную установку значений по каждому биту отдельно. Тогда можно будет задефайнить выводы в любом порядке, для быстрой смены их.

Вариантов море. И все они сводятся к одному - проверка неизменяемого бита (сохранение) с дальнейшей его установкой обратно (восстановление).

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

Добавлено: Пн июн 08, 2015 16:38:13
Wolf_X
Аlex писал(а): Даже если это и так, то сделайте "тупо в лоб" :
Спасибо большое, все три варианта рабочие, плюс вариант от WiseLord