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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

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

Сообщение zero648 »

Если че, то АЦП может заниматься несколькими процессами. Еще можно подтяжки менять на ноге и проверять что на входе.
Аватара пользователя
KOTик
Встал на лапы
Сообщения: 148
Зарегистрирован: Пн июн 07, 2010 16:16:57
Контактная информация:

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

Сообщение KOTик »

zero648 писал(а):Если че, то АЦП может заниматься несколькими процессами. Еще можно подтяжки менять на ноге и проверять что на входе.

А можно примерчик? :)
В моем случае, АЦП принимает значение до 1023.
Не представляю, как заставить его принимать (-) и (+)...

И еще вопрос - Как работать с таймером?
Написал примитивный код и все работает, но имеется один баг - кнопка тупит и срабатывает в моем случае 1 раз в 5 сек. :kill:
Это из-за того, что в коде имеется задержка типа:

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

For Count = 0 To 500                                        'считаем до 500
Waitms 10                                                   '10 * 500 = 5 сек

С waitms/wait происходит то же самое.
Даже, если кнопку повесить на прерывание INT0 - и даже тут крах! :shock:
А я почему-то думал, что внешнее прерывание сразу уходит в обработку без всяких задержек и условий.
Не тут-то было! Тоже срабатывает через раз.

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

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

...
Config Timer0 = Timer , Prescale = 64
On Timer0 Button:
...

Do
...
...
Loop

Button:
....
Return
End

И как из этой строки узнать, через сколько мск произойдет прерывание? :shock:
Товарищи коты, помогите примерчиком с комментариями или ссылку для разбора подкиньте.
Буду признателен :beer:

Продолжаю лопатить интернет - все не то... :kill:
servnt
Открыл глаза
Сообщения: 61
Зарегистрирован: Вс фев 14, 2010 11:29:12
Откуда: РФ, Рязань

Не срабатывает прерывание на кнопках

Сообщение servnt »

Подскажите, где может быть ошибка?
Не реагирует на кнопки.

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

$regfile = "m32def.dat"                                     ' specify the used micro
$crystal = 8000000                                          ' used crystal frequency
$baud = 19200                                               ' use baud rate
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 10                                               ' default use 10 for the SW stack
$framesize = 40                                             ' default use 40 for the frame space


'$sim
'===============
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.1 , Rs = Portb.0
Config Lcd = 20 * 4
Config Debounce = 75
Config Int2 = Falling
Config Portc.2 = Input : Portc.2 = 1
Config Portc.3 = Input : Portc.3 = 1
Config Portc.4 = Input : Portc.4 = 1
Config Portc.5 = Input : Portc.5 = 1
Config Portc.6 = Input : Portc.6 = 1
Config Portb.2 = Input : Portc.2 = 1
'====ïåðåìåííûå äëÿ îïðîñà êëàâèàsòóðû
Dim Keycode As Byte
'====îñíîâíîé öèêë================
On Int2 Button
Enable Interrupts
Enable Int2
Cursor Off
Do
   Locate 1 , 1
   Lcd Keycode
   Waitms 500
   Keycode = 0
Loop

Button:
Do
   If Pinc.2 = 0 Then
      Keycode = 1
   End If

   If Pinc.3 = 0 Then
      Keycode = 2
   End If

   If Pinc.4 = 0 Then
      Keycode = 3
   End If

   If Pinc.5 = 0 Then
      Keycode = 4
   End If

   If Pinc.6 = 0 Then
      Keycode = 5
   End If
Loop Until Keycode <> 0
Waitms 10
Gifr = 64
Return

End


Изображение
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Не срабатывает прерывание на кнопках

Сообщение vitalik_1984 »

Для начала можно прогнать кекс в Avr Studio. Тогда будет понятно железо это либо программа. И вообще больше половины написанного только догадываюсь что значит, хотя и Изучал в универе паскаль, а дома баловался с Бейсиком. Это, кстати что за язык?? :dont_know:

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

Do
   If Pinc.2 = 0 Then
      Keycode = 1
   End If

   If Pinc.3 = 0 Then
      Keycode = 2
   End If

   If Pinc.4 = 0 Then
      Keycode = 3
   End If

   If Pinc.5 = 0 Then
      Keycode = 4
   End If

   If Pinc.6 = 0 Then
      Keycode = 5
   End If
Loop Until Keycode <> 0   'возвращаемся к Do пока Keycode не равен нулю

Где тут производятся действия, в результате которых Keycode становится равным 0???
Сдается мне, что при нажатии любой кнопки код тупо зацикливается в этом месте, даже если кнопку отпустили.
Лучше уж тогда проверять (Pinc&MASK) <>0 или в вашем случае 7С
Где MASK это маска используемых кнопок.
Аватара пользователя
amv2000
Опытный кот
Сообщения: 717
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

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

Сообщение amv2000 »

Ниже
Последний раз редактировалось amv2000 Пт дек 06, 2013 11:51:31, всего редактировалось 1 раз.
Аватара пользователя
amv2000
Опытный кот
Сообщения: 717
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

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

Сообщение amv2000 »

amv2000 писал(а):
KOTик писал(а):как из этой строки узнать, через сколько мск произойдет прерывание?

Прерывание произойдет, когда выполнится подпрограмма Button, здесь скорее всего при нажатии кнопки.
А дребезг кнопки можно устранить с помощью Debounce.

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

Debounce Pind.2 , 0 , left_booton , Sub ' проверяем пин на наличие ноля, если условия выполненно - переходим к подпрограмме
Аватара пользователя
serg_svd
Собутыльник Кота
Сообщения: 2560
Зарегистрирован: Ср янв 16, 2008 08:34:04
Откуда: KMV

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

Сообщение serg_svd »

KOTик писал(а):Имеется задачка:
Включать светодиод, замыкая кнопку и на плюс, и на минус.
Т.е. и то, и др. должно включать LED.

А почему обязательно пытаться решать программно?
Можно аппаратно. Организовываете кнопку на минус с подтяжкой резистором как обычно. А сигнал с плюса подаете на тот же пин через инвертор, которым может служить тот же транзистор в ключевом режиме.
Последний раз редактировалось serg_svd Пт дек 06, 2013 15:54:17, всего редактировалось 1 раз.
"Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли
Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Аватара пользователя
KOTик
Встал на лапы
Сообщения: 148
Зарегистрирован: Пн июн 07, 2010 16:16:57
Контактная информация:

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

Сообщение KOTик »

serg_svd писал(а):
KOTик писал(а):Имеется задачка:
Включать светодиод, замыкая кнопку и на плюс, и на минус.
Т.е. и то, и др. должно включать LED.

А почему обязательно пытаться решать программно?
Можно аппаратно. Организовываете кнопку на минус с подтяжкой резистором как обычно. А сигнал с плюса подаете на тот же пин через инвертир, которым может служить тот же транзистор в ключевом режиме.

А это, кстати, идея!
И как сам не додумался
Мррррррррр :)))
Спасибо!
Аватара пользователя
KOTик
Встал на лапы
Сообщения: 148
Зарегистрирован: Пн июн 07, 2010 16:16:57
Контактная информация:

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

Сообщение KOTик »

amv2000 писал(а):Прерывание произойдет, когда выполнится подпрограмма Button, здесь скорее всего при нажатии кнопки.
А дребезг кнопки можно устранить с помощью Debounce.

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

Debounce Pind.2 , 0 , left_booton , Sub ' проверяем пин на наличие ноля, если условия выполненно - переходим к подпрограмме

Спасибо! С дебонсами работаю и все отлично!

А какое событие вызовет прерывание Button:?
Переполнение таймера?

Образно ввиду в курс дела.
Имеются 2 кнопки (прижаты к земле): старт (PINB.2), стоп (PINB.1) и один LED (PORTB.0).
Кнопка "старт" включает светодиод на 10сек. и по истечению этого времени он тухнет - это работает.
А вот кнопка "стоп" нужна для экстренного выключения светодиода, т.е. до 10 сек.
"Стоп" вешал и так, и сяк, и на прерывание INT0 (тинька13) - бестолку :(
Она срабатывает только после 10сек.

Только не бейте :( Задержку в 10 сек. реализовал примитивно, через wait 10 - она и тормозит реакцию кнопки "стоп".
Собственно вопрос: задержку на таймер сажать или как?
И как вообще работать с таймером - просветите, учитель :)
Буду признателен за образец кода с комментариями - это у вас хорошо получается :)
Аватара пользователя
amv2000
Опытный кот
Сообщения: 717
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

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

Сообщение amv2000 »

KOTик писал(а):А какое событие вызовет прерывание Button:?
Переполнение таймера?

Вы немного не понимаете в Вашем коде

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

...
Config Timer0 = Timer , Prescale = 64
On Timer0 Button:
не забываем
Enable Interrupts - Включить прерывания
Enable Timer0
...
Настраиваете таймер 0 на переполнение каждые 2 мс( при условии, что кварц 8 Мгц), т.е. каждые 2 мс проверяете нажата кнопка или нет. А событие которое запускает прерывание,это Ваше нажатие на кнопку.
Вот нашел по моему почти Ваш случай. http://decada.org.ru/project/lessons/bascom_avr/10/

Обратите внимание нашел на этой странице http://habrahabr.ru/post/151544/

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

Работа с прерываниями:
On Int0 Button - Имя подпрограммы
Config Int0 = Low Level - Прерывание по низкому уровню
Enable Interrupts - Включить прерывания
Enable Int0

Button:
  Incr Cntr
Return

 С таймерами:
Config Timer0 = Timer , Prescale = 64 - Настраиваем таймер и предделитель
On Timer0 Pulse: - Имя подпрограммы
Enable Interrupts - Включить прерывания
Enable Timer0

Pulse:
  Incr Cntr
Return
В первом случаем переменная увеличивается при нажатии на кнопку, во втором увеличивается каждые 1 мс.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

amv2000 писал(а):
KOTик писал(а):как из этой строки узнать, через сколько мск произойдет прерывание?

Прерывание произойдет, когда выполнится подпрограмма Button, здесь скорее всего при нажатии кнопки.

Тут не совсем так. Прерывание в Мк Avr произойдет как правило через четыре такта после последней команды.
На картинке в графике справа видно пусть он и не совсем для этого случая.
Изображение
А вот ваша подпрограмма Button вызовется уже в том месте где её вызовут, возможно и в прерывании...
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

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

Сообщение zero648 »

А можно примерчик?
В моем случае, АЦП принимает значение до 1023.
Не представляю, как заставить его принимать (-) и (+)...

Примерчиком помочь не смогу, прогаю только на асме.
По поводу АЦП, ставим на кнопку делитель 1:1 на плюс и минус, например 10кОм + 10кОм и периодически читаем АЦП, будем считать, что в этом состоянии кнопка висит т.к. АЦП =~512, если нажать кнопку на минус, то АЦП уйдет на ноль, если на плюс, то АЦП примет максимум, вот такая вот не сложная технология.
Аватара пользователя
KOTик
Встал на лапы
Сообщения: 148
Зарегистрирован: Пн июн 07, 2010 16:16:57
Контактная информация:

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

Сообщение KOTик »

zero648 писал(а):Примерчиком помочь не смогу, прогаю только на асме.
По поводу АЦП, ставим на кнопку делитель 1:1 на плюс и минус, например 10кОм + 10кОм и периодически читаем АЦП, будем считать, что в этом состоянии кнопка висит т.к. АЦП =~512, если нажать кнопку на минус, то АЦП уйдет на ноль, если на плюс, то АЦП примет максимум, вот такая вот не сложная технология.

И как Я не додумался :)
При том с АЦП очень хорошие отношения :)))
Все гениальное - просто!
Спасибо!

Тааак.
Ща пойду с таймерами разбираться...
SmarTrunk
Друг Кота
Сообщения: 6014
Зарегистрирован: Чт ноя 26, 2009 11:16:50
Откуда: Москва

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

Сообщение SmarTrunk »

Главное, не смочь нажать одновременно обе кнопки, на плюс и на минус.

А вообще, при большом желании, можно и больше кнопок повесить на один вход АЦП.
Аватара пользователя
KOTик
Встал на лапы
Сообщения: 148
Зарегистрирован: Пн июн 07, 2010 16:16:57
Контактная информация:

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

Сообщение KOTик »

SmarTrunk писал(а):Главное, не смочь нажать одновременно обе кнопки, на плюс и на минус.
А вообще, при большом желании, можно и больше кнопок повесить на один вход АЦП.

Да, уже вешал.
И в зависимости от значения АЦП светики загорались :)
Александр 2677
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн фев 22, 2010 11:16:00

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

Сообщение Александр 2677 »

Для Proteus есть модель HC-SR04 ?
Изображение
Аватара пользователя
amv2000
Опытный кот
Сообщения: 717
Зарегистрирован: Вт апр 26, 2011 13:58:36
Откуда: Ростовская область

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

Сообщение amv2000 »

Модели HC-SR04 нет, это народ делает рисунки.
Аватара пользователя
KOTик
Встал на лапы
Сообщения: 148
Зарегистрирован: Пн июн 07, 2010 16:16:57
Контактная информация:

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

Сообщение KOTик »

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

У меня тинька13 ($crystal = 4800000), светодиод (PORTB.0) и настроен TIMER0 (8бит) с предделителем 1024.
Получается 1024/4800000*255 = 0,0544мс - это шаг увеличения значения.
А время переполнения таймера каждые 255*0,0544 = 13,8мс. Значит, за 13,8мс таймер натикает число 255 с шагом 0,0544мс (поправьте, если неправильно посчитал)

А теперь вопрос, что с чем перемножить/разделить, чтобы мерцание светика было, например, 1 раз в секунду.
По какой формуле всё это вычислять?
Аватара пользователя
edm2007
Поставщик валерьянки для Кота
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск
Контактная информация:

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

Сообщение edm2007 »

Привет.

На деле все очень просто. Допустим, 16-ми битный таймер молотит на частоте 4 МГц без предделителя. Счетный регистр увеличивает свое значение с каждым тактом, а значит период таймера (величина, обратная частоте) составит 1 / 4 000 000 = 0,00025 мс. Это один тик таймера. Так как он у нас 16-ти битный, то переполнится при переходе через FFFF (65535). Отсюда:

16-ти битный таймер при тактовой частоте 4 МГц с прескаллером 1 будет переполняться каждые 0,00025 мс * 65536 = 16,384 мс
- // - с прескаллером 8 -16,384 * 8 = 131.072 мс
- // - с прескаллером 64 -16,384 * 64 = 1048.576 мс
- // - с прескаллером 256 - 16,384 * 256 = 4194.304 мс
- // - с прескаллером 1024 - 16,384 * 1024 = 16777.217 мс

Если же нужны четко заданные промежутки времени, то самый простой способ - настроить таймер в режим СТС (сброс по совпадению). В этом режиме таймер будет считать от 0 до заданного значения (записанного в регистр сравнения), после чего обнуляться и начинать счет заново. По переполнению можно будет генерировать прерывание.

Как рассчитать число, которое необходимо записать в регистр сравнения? Да проще некуда. Допустим, нам необходимо чтоб таймер вызывал прерывание каждую секунду. Берем предделитель с заведомо большим временем. Это 64 (1048.576 мс). Если тактовая частота таймера в 64 раза меньше частоты МК, то ее период в 64 раза больше: 0,00025 * 64 = 0,016 мс. Осталось только выяснить, сколько тиков таймера нужно для отсчета 1 секунды: 1000 мс / 0,016 мс = 62500.

Теперь если настроить таймер в режим СТС, соответствующим образом настроить прерывание и записать в регистр сравнения число 62500, МК будет вызывать прерывание по совпадению каждую секунду. При помощи такого нехитрого расчета можно отсчитывать любые временные интервалы. Если диапазона не хватает, то в обработчике можно считать переполнения. :)
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Аватара пользователя
KOTик
Встал на лапы
Сообщения: 148
Зарегистрирован: Пн июн 07, 2010 16:16:57
Контактная информация:

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

Сообщение KOTик »

Что-то совсем запутался :(
А ж голова опухла :dont_know:

edm2007 писал(а):Привет.
На деле все очень просто. Допустим, 16-ми битный таймер молотит на частоте 4 МГц без предделителя. Счетный регистр увеличивает свое значение с каждым тактом, а значит период таймера (величина, обратная частоте) составит 1 / 4 000 000 = 0,00025 мс. Это один тик таймера. Так как он у нас 16-ти битный, то переполнится при переходе через FFFF (65535).

1/4 000 000 = 0,000 000 25
разве нет?

Отсюда:
16-ти битный таймер при тактовой частоте 4 МГц с прескаллером 1 будет переполняться каждые 0,00025 мс * 65536 = 16,384 мс

16-битный таймер переполнится через 65535, а у вас 65536 - почему так?
т.е. должно быть 0,00000025* 65535 = 0,01638375мс.

Если тактовая частота таймера в 64 раза меньше частоты МК, то ее период в 64 раза больше: 0,00025 * 64 = 0,016 мс. Осталось только выяснить, сколько тиков таймера нужно для отсчета 1 секунды: 1000 мс / 0,016 мс = 62500.

и тут тоже, 0,00000025* 64 = 0,000016мс.

Осталось только выяснить, сколько тиков таймера нужно для отсчета 1 секунды: 1000 мс / 0,016 мс = 62500.

Следовательно, 1000мс / 0,000016мс = 62 млн. 500 тысяч! :shock:

Вот, накидал код, где светодиод мерцает с частотой ~1сек.

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

'----------
$regfile = "attiny13.dat"                         'specify the used micro
$crystal = 9600000                                'used crystal frequency
$hwstack = 32                                     'default use 32 for the hardware stack
$swstack = 8                                      'default use 8 for the SW stack
$framesize = 16                                   'default use 40 for the frame space
Config Debounce = 75                              '

'== НАСТРОЙКА ПОРТОВ  =======
Config Portb.0 = Output                           'LED1
Config Pinb.1 = Input                             'KEY1

Dim Count As Integer

Led1 Alias Portb.0                                'LED1 -> PORTB.0
Key1 Alias Pinb.1                                 'KEY1 -> PINB.1
Led1 = 1 ' светодиод выключаем

Config Timer0 = Timer , Prescale = 256
On Timer0 Pulse:
Enable Interrupts
Enable Timer0

'======== ПРОГРАММА ==========

Do

If Count = 72 Then
Led1 = 0
Waitms 50

If Count < 72 Then                                'Waitms 100
Led1 = 1
End If
End If
Loop

Pulse:
Waitms 10
Incr Count
If Count > 72 Then Count = 0                      'Led1 = 1
Return

'----------
End                                               'end program


prescale 256 / 9 600 000*255 (счетный регистр) = 0,0068сек. = 1 тик таймера.
за 1 секунду: 1000*0,0068сек. = 6,8 тиков.
Каждый тик таймера увеличивает переменную Count до 72, после чего загорается светодиод и тухнет.
И так каждую секунду.

Цифру 72 подбирал экспериментально. Точность +/- несколько единиц мс.
Затем проводил вычисления с этими цифрами, чтобы не гадать и сразу вписать необходимую частоту мерцания..
Пока ничего не получается :( Голова опухла.

Если можно, объясните на примере моего кода, с таймером 8-бит, камнем 96 000 000 (тинька13) и прескейл 256
Ответить

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