Страница 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 у Вас "кривой" алгоритм. Можно, конечно, написать
, но это как-то через жо...
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 работы с битами:
Отсюда очевидно, что задача записи в порт, не трогая какой-то (четвёртый) его бит:
Код: Выделить всё
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