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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

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

#define led_1 PORTC.5 
#define led_2 PORTC.4
#define led_3 PORTC.3
Docendo discimus
Реклама
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

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

Сообщение DataLife »

pyzh_man, спасибо! Помогло! :beer:
Если не сложно, объясните, когда нужно использовать PIN а когда PORT? А что я что-то запутался. Изначально писал, как вы сказали, потом вспомнил, что меня как-то уже поправляли на PIN ...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Реклама
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

IN PIN считывает из порта, когда тот настроен на ввод. OUT PIN не имеет смысла. OUT PORT подключает/отключает подтягивающие резисторы, если порт настроен на ввод; выводит инфу, если порт настроен на вывод. IN PORT считывает инфу, ранее записанную в порт, настроенный на вывод.
Docendo discimus
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

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

Сообщение DataLife »

Ага, ещё раз спасибо. Кажется понял....
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

Пожалуйста.
И еще. Вместо

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

if... else...else

используйте

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

switch()...case...case

Удобнее и читабельнее.
Да и частоту надо генерировать в прерывании. Но это меня уже понесло...
Docendo discimus
Реклама
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

pyzh_man писал(а):OUT PIN не имеет смысла.
OUT PIN имеет смысл во всех новых AVR. «Новых» -- это где-то так от tiny13, tiny2313, mega48/88/168, ... с любыми буквами -- т.е. практически все, кроме старушки attiny26 да обновленных atmega8A, atmega64A, которые просто совместимы со старыми.
Я на этом форуме уже приводил картинку из документации
Изображение
Вот где есть такой обведенный инвертор, там по сигналу WP (Write PIN) инвертируется триггер PORT.
Очень удобно.

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

    SBI PINB, 2 ; инвертировать PB2
    LDI  R16, 0x88
    OUT PINB, R16 ; инвертировать одновремённо PB3 и PB7
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Реклама
OKF
Это не хвост, это антенна
Сообщения: 1392
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

Мужики, а как в CV с областью видимости глобальных переменных? Видны во всех файлах проекта, без extern... Как то не аккуратненько. Или лыжи не едут?

"Интересно девки пляшут"! Этот фокус демонстрируется на v.1.25.9pro, с 2.04.4а всё как положено - глобальные (не static) не видны в других файлах проекта. Версиезависимость, однако, не солидно!
Последний раз редактировалось OKF Вс сен 11, 2011 10:04:55, всего редактировалось 1 раз.
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

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

Сообщение DataLife »

pyzh_man, тоесть так?
switch(s) // s- переменная прерывателя
{
case '1': *делаем первую программу*; break;
case '2': *вторую*; break;
case '3': *третью*; break;
}


А что за частота, как и зачем оно нужно?
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

Да, так. А частота... Так это то, что вы делаете в

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

while(s== 1)
{
...
}
Docendo discimus
aleksandr88
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Ср июн 08, 2011 11:32:49

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

Сообщение aleksandr88 »

Подскажите почему не работает такой способ установки битов в регистре
TIMSK=(1<<TOIE1)|(1<<TOIE0);
ну и стольные регистры с названием битов .
и ели использовать такой вариант прокатит-будит лит аналогичен первому?
TIMSK=(1<<2)|(1<<0);
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

Подскажите в какой версии CV пропадают глюки инициализации переменных?

Пользую 1.25.5 - при инициализации локальных переменных в строчку или присвоении им значений при инициализации в итоге в них совсем не то, что записывается явно в коде.

НЕ использовать же только глобальные.

ЗЫ Стек 1К, а использую 190 байт...
Valek87
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

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

Сообщение Valek87 »

Помогите пожалуйста. Вот написал программу - мигание светодиода с периодом 1с. Только почему-то у меня идет период не 1с, а 1,675с. МС - atmega324p. Частота - 20 МГц. Светодиод подсоедиен с PD2.

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

/*****************************************************
Chip type           : ATmega324
Clock frequency     : 20,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 512
*****************************************************/

#include <mega324.h>   
#include <delay.h>

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
PORTD.2=~PORTD.2;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Port D initialization
PORTD=0x00;
DDRD=0xff;

// Timer/Counter 1 initialization
TCCR1A=0x00;
TCCR1B=0b00000100;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x98;
OCR1AL=0x96;
OCR1BH=0x00;
OCR1BL=0x00;

TIMSK1=0x01;

#asm("sei")

while (1)
      {
      }
}
Последний раз редактировалось Valek87 Чт сен 22, 2011 14:54:40, всего редактировалось 1 раз.
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

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

Сообщение DataLife »

Подскажите, будет ли так работать антидребезг кнопки?

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

     interrupt [EXT_INT0] void ext_int0_isr(void) //обработка прерываний INT0
     {
        delay_ms(100); // антидребезг <===
        #asm("cli"); //запрещение прерываний на время обработки прерывания
        s=s+1;
        if (s==4) s=1;
        #asm("sei"); //разрешение прерываний
      }


Тоесть, излечиться ли он таким способом или нет?

Просто для того, что бы его не было, после задержки нужно снова проверять состояние кнопки, в этом случае этого нет, если не ошибаюсь..
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

Эти команды:

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

#asm("cli"); //запрещение прерываний на время обработки прерывания
#asm("sei"); //разрешение прерываний

в прерывании не имеют смысла. Железо само заботится о разрешении прерываний здесь.

И работать это не будет, т.к. никакого антидребезга здесь нет. Только задержка. :dont_know: Хотя... почему? Вполне возможно. Ведь за 100 мс состояние кнопки успеет устаканиться. Другое дело, что на нажатие кнопки контролер будет реагировать дважды: первый раз на нажатие кнопки (появление дребезга) и второй при её отпуске (опять дребезг). :)
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

DataLife писал(а):Просто для того, что бы его не было, после задержки нужно снова проверять состояние кнопки, в этом случае этого нет, если не ошибаюсь..
да, именно это важно, а то, что сделано - бесполезно и, скорее всего, приведет к "задваиванию" нажатий и, опять же скорее всего, к реакции на отжатие. Ну и, само собой, к заметным тормозам - с такой-то зедержкой!
IfoR писал(а):в прерывании не имеют смысла. Железо само заботится о разрешении прерываний здесь.
еще как имеют! особенно sei - может таких чудес наделать...
битва с дураками проиграна, победители торжествуют. слава победителям!
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

ТАк что- нико не подскажет с чем может быть связано повреждение локальных переменных в CV ?
Т.е. такой код

void modem_control(void)
{
unsigned char step;
unsigned char conflict;
unsigned char atc_retry_number;
unsigned char repeat;

step=1;
atc_retry_number=3;
repeat=3;
conflict=0;

while (step!=100)
{
/// вывод значения conflict в ком порт.
....

Всё - тут оно становится 0xC0 почемуто. Може настройки компилятора? Такие же фокусы выкидывает в функции main. При этом - это НЕ повторяющийся глюк... В том то и проблема - анализу сложно поддаётся. ЗАИПАЛСЯ. Уже мысли появились слинять с cvavr...
Аватара пользователя
DataLife
Вымогатель припоя
Сообщения: 601
Зарегистрирован: Пт фев 13, 2009 20:58:13
Откуда: Донецк

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

Сообщение DataLife »

IfoR, просто я как думаю:

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

 interrupt [EXT_INT0] void ext_int0_isr(void) //обработка прерываний INT0
     {
        delay_ms(100); // антидребезг <===
        #asm("cli"); //запрещение прерываний на время обработки прерывания
        s=s+1;
        if (s==4) s=1;
        #asm("sei"); //разрешение прерываний
      }


1) кнопка нажата (пошёл некий дребезг)
2) сработало прерывание, но тут задержка, которая не даёт дребезгу несколько раз изменить значение переменной S
3) прошла задержка, дребезг устаканился, переменная увеличилась, как и должна

Просто если бы не задержка сразу увеличивались бы переменная и дребезг мог бы тут подпортить картинку...

На счёт #asm("cli"); и #asm("sei"); - не знаю как правильно, в обучающих статьях по прерываниям я видел, что делают так. У меня так работает, места в прошивке они практически не занимают...
Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

DataLife писал(а):1) кнопка нажата (пошёл некий дребезг)
2) сработало прерывание, но тут задержка, которая не даёт дребезгу несколько раз изменить значение переменной S
3) прошла задержка, дребезг устаканился, переменная увеличилась, как и должна

Просто если бы не задержка сразу увеличивались бы переменная и дребезг мог бы тут подпортить картинку...
на самом деле все будет немного иначе:
1) нажали кнопку, пошел дребезг. по первому импульсу дребезга сработало прерывание. началась задержка.
2) импульсы дребезга устанавливают флаг запроса прерывания, пока длится задержка.
3) после задержки вы запрещаете прерывания - бессмысленно, т.к. в этот момент они и так запрещены. увеличиваете переменную, все путем.
4) разрешаете прерывания. тут, раз флаг запроса уже установлен (см. ранее), буквально ЕЩЕ ДО ВЫХОДА ИЗ ОБРАБОТЧИКА (Си генерирует на "закрывающую фигурную скобку" далеко не одну команду, а больше) снова осуществляется вызов обработчика, т.е. еще из него не вышли, но уже снова в него вошли. если очень не повезет - вы переполните стек, но скорее всего обработчик отработает ЕЩЕ РАЗ, т.е. ваша переменная увеличится на 2, а не на 1.
5) далее все по плану. однако, если кнопку держат нажатой больше 200 мс, то в момент отжатия снова скорее всего сгенерируется прерывание, и процесс повторится.

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

не мудрите, делайте, как положено: опрос-задержка-опрос, если оба опроса дают одинаковые уровни на пине - дребезг кончился, если разные - это надо игнорировать. для подавления дребезга ДОСТАТОЧНО 15-20 мс задержки.
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
Errorkpi
Встал на лапы
Сообщения: 102
Зарегистрирован: Вт мар 22, 2011 22:31:01

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

Сообщение Errorkpi »

Мастер Ломастер писал(а):в лучшем - получите задваивание показаний

не знаю не знаю... может и так. поделюсь своим опытом:

опрос кнопки в основном цикле программы:
если кнопка нажата, ставим флаг игнорировать кнопку и пускаем таймер на 20мс. ПО переполнению таймер сбрасывает флаг. Работал максимум с 4-6 кнопок, поэтому блочил все одновременно, но при желании можно сделать не тупой флаг, а битовую маску и проверять запрет на каждую кнопку.....

думаю в случае с прерыванием имеет смысл вручную сбросить флаг прерывания перед выходом из обработчика......
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

Народ - а сделать програмно фильтр дребезга ?

Простеший способ : запускаете таймер по срабатыванию кнопки на 10-20мкс и по прерыванию таймера опрашиваете её. В прерывании счётчик - если кнопка нажата ( 1 или 0 - в зависимости от реализации) , то к счётчику +1 и перезапускаете опять на 10-20 мкс. После 100 циклов - 1-2 мс - смотрите значение счётчика - если больше 60%( к примеру - в зависимоти от кнопки) - значит ктото её нажимал. Если пустить таймер в цикле, а на каждую кнопку завести свой счётчик - можно паралельно опрашивать целую клавиатуру.
Ответить

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