В Баскоме есть команда
B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 1)
Раз'ясните, пожалуйста:
- переменная В, для чего она и куда её засунуть?
- wait (0 или 1) не пойму, что определяет?
Спасибо за терпение!
Команда Encoder в Баскоме-вопрос
Сообщений 1 страница 30 из 51
Поделиться12010-11-18 16:38:31
Поделиться22010-11-18 22:15:21
B - число щелчков, а вызываемые п/п должны как-то указывать или сообщать направление вращения. Возьми тестовую программу и проверь в "железе". Думаю она не понравится.
Вообще, это совершенно бесполезная функция. Энкодер обычно применяется с сложных системах и поэтому должен работать в фоновом режиме, т.к. реальная программа не может бесконечно сидеть на его опросе. Кроме того, энкодер
может вращаться и медленно и очень быстро - до 1 кГц, и тогда его будет очень затруднительно
обрабатывать по опросу без пропусков щелчков.
Применив прерывания, можно построить очень простую программу обработки вращения енкодера.
Программа прерываний должна сообщать число вращений вправо и влево с момента взятия предыдущего отсчета.
Для статических энкодеров (такой нарисован в примере - это и все оптические) необходимо использовать прерывания
по каждому изменению уровня на обоих линиях. Т.е. можно использовать до четырех обычных прерываний,
например, INT0 \_, INT1 \_, INT2 _/, INT3 _/, соединив входы попарно - я делаю именно так. Зато в программе обработки
получается проще определить направление вращения. Можно использовать два прерывания по любому изменению уровня.
Или только одно по изменению уровня в порту. Но в последнем случае сложнее выделять направление ведь еще нужно
подавлять дребезг.
Для динамических енкодеров, такие делает BOURNS (ECW1J-B24-..., достаточно одного прерывания по спаду.
Аппаратно, для подавления дребезга обязательно нужно применить
RC-цепочку 10k+0.1mkF и 100 ом последовательно с замыкающим контактом :
10 k
+5V <----====----------> Port
/ 100 | |
|---/ ----====--- === 0.1 мкФ
|
__
Будут вопросы - выложу текст программы.
Поделиться32010-11-18 22:23:18
Я делаю так:
$regfile = "m16def.dat" 'подключаем файл заголовков для контроллера ATbanned6
$crystal = 8000000 'частота кварцевого генератора
$baud = 9600 'настройка скорости передачи RS-232
$hwstack = 32 'аппаратный стек
$swstack = 10 'програмный стек
$framesize = 40 'размер фрейма
'настраиваем ЖКИ
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
Config Lcd = 16 * 2 'ЖКИ 2 строки по 16 символов
Cursor Off 'выключить курсор
'VALCODER________________________ выводы енкодера(валкодера)
Config Pind.3 = Input 'Valcoder A INT1
Valcod_a Alias Pind.3
Config Pina.4 = Input 'Valcoder B
Valcod_b Alias Pina.4
Set Portd.3
Set Porta.4
'объявляем переменные
Dim Valcod_param As Byte
Dim Valcod_cange As Bit
Config Int1 = Falling 'настраиваем внешнее прерывание INT1 на срабатывание при изменении из "1" в "0"
On Int1 Valcoder_change 'подпрограмма обработка прерывания Valcoder_change
Enable Int1 'разрешаем работу прерывания INT1
Enable Interrupts 'разрешаем глобальные прерывания
Cls 'очищаем экран ЖКИ
Locate 1 , 10 'задаем позицию курсора
Lcd "Enc=" ; Valcod_param 'выводим переменную изменения значения енкодера(валкодера)
Do 'начало цикла
If Valcod_cange = 1 Then 'если битовая переменна Valcod_cange = 1 (крутили енкодер(валкодер)
Locate 1 , 14 'то задаем позицию курсора
Lcd Valcod_param ; " " 'выводим переменную изменения значения енкодера(валкодера)
Reset Valcod_cange 'сбрасываем битовую переменную Valcod_cange
Sound Buzer , 10 , 500 'генерим звук
End If
Loop 'замыкаем цикл
Valcoder_change: 'подпрограмма обработки прерывания INT1
'*******************************************************************************
If Valcod_b = 1 Then 'если на линии B лог "1"
If Valcod_param <> 255 Then Incr Valcod_param 'то если переменная Valcod_param не достигла значения 255 увеличиваем ее на 1
Else 'если на линии B лог "0"
If Valcod_param <> 0 Then Decr Valcod_param 'то если переменная Valcod_param не достигла значения 0 уменьшаем ее на 1
End If
Set Valcod_cange 'выставляем битовую переменную Valcod_cange
Return 'возврат из подпрогрммы
End 'конец программыПоделиться42010-11-19 11:15:01
Я пробовал в железе обрабатывать энкодер через Debounce. Принцип тот же, что и в Вашем коде. Работает ужасно. Наверное, потому что использовались два таймера в программе(часы и индикация LED)
А вот как раз Encoder работал стабильно. Через прерывания пока не пробывал. Так как в наше время приходится сначала разводить ПП, а потом под неё прошивку писать.(мега8, портD индикация)
Проверял я хелповский пример в железе. Ошибок- одна из пятнадцати. Переменная В меняется 1-3-2.
На количество щелчков не похоже. И что-же всётаки определяет "wait"? (Ну ни как этот англицкий не понять 
Поделиться52010-11-22 21:24:02
'----------------------------------------------------------------------------------
' демонстрационная программа применения энкодера
' расчитана на простые меги (только с Int0) и улучшенные с прерыванием по любом ножке
'----------------------------------------------------------------------------------
$map
'$regfile = "m8def.dat"
$regfile = "m168def.dat"
'$noramclear 'не чистить память
$hwstack = 64 'размер аппаратного стека
$swstack = 32 'размер программного стека
$framesize = 32 'размер области используемой для преобразований и временного хранения данных
'Byte - 4 bytes, Integer - 7 bytes, Longs - 16 bytes, single - 24 bytes
'String - длина слиния (монтажа) строк
'Плюс локальные LOCAL переменные, плюс временные VALUE (BYVAL)
'----------------------------------------------
Dim Edat As Byte 'признак "Есть новые данные енкодера"
Dim Ndat As Byte 'признак "Есть новые данные для исполнения"
Dim R_cdec As Byte 'СЧЕТЧИК ЩЕЛЧКОВ ВЛЕВО
Dim R_cinc As Byte 'СЧЕТЧИК ЩЕЛЧКОВ ВПРАВО
Dim Tmpb As Byte 'временные байтовые данные
Dim Ua As Single 'временное значение
Dim Ub As Single 'временное значение
Dim Bufa As String * 20 'строка
Dim Bufb As String * 20 'строка
Dim Bufz As String * 16 'строка
'---------------------
' назначение векторов прерывания.
'On Int0 Int0_int Nosave 'вектор внешнего прерывания 0
On Pcint0 Int0_int Nosave 'вектор внешнего прерывания 0
'---------------------
' инициализация оборудования.
'---------------------
$crystal = 20000000 'кварц 20 МГц
'---------------------
Config Lcdpin = Pin , Db4 = Portc.1 , Db5 = Portc.2 , Db6 = Portc.3 , Db7 = Portc.4 , E = Portd.1 , Rs = Portd.0 'для индикатора M88
Config Lcd = 16 * 2 'определить конфигурацию индикатора
'---------------------
' СТОРОЖЕВОЙ ТАЙМЕР
'---------------------
$asm
Wdr 'Reset Watchdog Timer
$end Asm
Mcusr = 0 'сбросить WDRF в MCUSR и все остальное (m88)
Wdtcsr = &H1F 'ЧТОБЫ ЗАПРЕТИТЬ WDT ТРЕБУЕТСЯ ВНАЧАЛЕ РАЗРЕШИТЬ (m88)
Wdtcsr = &H17 'А ЗАТЕМ ЗАПРЕТИТЬ (m88)
'---------------------
Clkpr = &H80 : Clkpr = &H00 'коэффициент деления кварца: 1 Fкв = 20 МГц
'---------------------
'Smcr = &H01 'разрешить режим Idle
'---------------------
'ATMEGA88,168
'Eicra = &B00000010 'INT0 - по спаду
'Eimsk = &B00000001 'INT0 - разрешить
Pcicr = &B00000001 'разрешить прерывание по изменению уровня линий портов PCI0...PCI7
Pcmsk0 = &B00000100 'а конкретно PBI2
Sei 'разрешить прерывания
'---------------------
'ATMEGA8
'Mcucr = &B10000010 'IDLE - разрешить, INT0 - по спаду
'Gicr = &B01000000 'INT0 - разрешить
'Sei 'разрешить прерывания
'---------------------
' ПОРТЫ
'---------------------
Ddrb = &B00000000 'направление линий порта B: 1 - на вывод
Portb = &B11111100 'исходное состояние линий B: hhhhhhhh
'---------------------
Ddrc = &B00011110 'направление линий порта C: 1 - на вывод
Portc = &B00000000 'исходное состояние линий C: zzz1111zb
'---------------------
Ddrd = &B11111111 'направление линий порта D: 1 - на вывод
Portd = &B00000000 'исходное состояние линий D: 00000000
'----------------------------------------------
' определение изображения дополнительных символов ЖКИ
Deflcdchar 0 , 31 , 31 , 31 , 31 , 31 , 31 , 31 , 31 'блок
Deflcdchar 1 , 4 , 4 , 10 , 10 , 17 , 17 , 31 , 32 'дельта
Deflcdchar 3 , 4 , 32 , 4 , 32 , 4 , 32 , 4 , 32 'вертикальный разделитель
Deflcdchar 6 , 2 , 6 , 15 , 31 , 15 , 6 , 2 , 32 'стрелка влево
Deflcdchar 7 , 8 , 12 , 30 , 31 , 30 , 12 , 8 , 32 'стрелка вправо
Cls 'обязательная операция.
Cursor Off Noblink 'сделать курсор невидимым
'---------------------
'время и дату компиляции записать в строку в европейском формате - DD-MM-YYYY hh:nn:ss
Bufa = Version(1) 'дата версии
Bufa = Left(bufa , 10)
Bufb = " v01:" + Bufa 'номер версии и дата
'1234567890123456
Bufa = " Encoder_Tester " 'стартовый заголовок
Gosub Lcdbufs 'все вывести
'---------------------
Wait 2 'будем отображать 2 с
Ub = 5 'установим начальное значение
Edat = 0 : Ndat = 255 'и назначим отбображение текущего значения регулируемого параметра
Cls 'очистить
'---------------------
'главный цикл - ждем событий
Mc:
If Ndat <> 0 Then 'Есть новые данные для исполнения?
Ndat = 0 : Goto N_dat
End If
If Edat <> 0 Then 'Есть новые данные енкодера?
Edat = 0 : Gosub W_rot
End If
Waitms 200 'задержка, чтобы индикатор не дергался слишком часто
Goto Mc
'---------------------
' ----------------
' | Adjusted Value:|
' | +XX.XX |
' ----------------
N_dat:
'первая строка
Bufa = " Adjusted Value:"
'-----
'вторая строка
Ua = Abs(ub) 'делаем положительным, чтобы знак минус при форматировании не выскакивал впереди
If Ua > 99.995 Then 'предотвратим переполнение шкалы
Cls : Lcd " OVER_LOAD!" : Goto Mc
End If
Bufb = Fusing(ua , "##.##") 'форматируем по маске
Bufz = Format(bufb , "00000") 'забиваем лидирующие нули, чтобы отображаемое значение было неподвижно на индикаторе
If Ub < 0 Then 'добавляем знак полярности
Bufb = " -" + Bufz
Else
Bufb = " +" + Bufz
End If
Gosub Lcdbufs 'вывод в индикатор сформированного изображения
Goto Mc
'----------------------------------------------
Const Onetik = 0.01 'значение одного щелчка енкодера
'ОБРАБОТКА ЕНКОДЕРА
W_rot:
Tmpb = 0 'ОЧИСТИМ И СЧИТАЕМ КОД
Swap Tmpb , R_cinc
If Tmpb <> 0 Then 'ПРОВЕРИМ СЧЕТЧИК ЩЕЛЧКОВ ВПРАВО
Goto Wrotr 'ЕСЛИ НЕ РАВЕН НУЛЮ - НА ОБРАБОТКУ
End If
Swap Tmpb , R_cdec
If Tmpb <> 0 Then 'АНАЛОГИЧНО СЧЕТЧИК ЩЕЛЧКОВ ВЛЕВО
Goto Wrotl
End If
Return
'--------
'ВРАЩЕНИЕ ЕНКОДЕРА ВЛЕВО
Wrotl:
Ua = Tmpb 'ПРЕОБРАЗОВАТЬ В ЧИСЛО С ПЛАВАЮЩЕЙ ТОЧКОЙ
Ua = 0 - Ua 'ОТРИЦАТЕЛЬНАЯ ПОЛЯРНОСТЬ
Goto Wrot1
'--------
'ВРАЩЕНИЕ ЕНКОДЕРА ВПРАВО
Wrotr:
Ua = Tmpb 'ПРЕОБРАЗОВАТЬ В ЧИСЛО С ПЛАВАЮЩЕЙ ТОЧКОЙ
Wrot1:
Ua = Ua * Onetik 'вычисление приращения с учетом значения одного щелчка
Ub = Ub + Ua 'вычисление нового значения регулируемого параметра
Ndat = 255 'установить признак "Есть новые данные"
Return
'------------------------------------------
'вывод строковых буферов в индикатор
Lcdbufs:
Gosub Lcd_bufa
Lcd_bufb:
Locate 2 , 1 : Lcd Bufb : Return
'------------------------------------------
Lcd_bufa:
Locate 1 , 1 : Lcd Bufa : Return
'----------------------------------------------------------------------------------
'ОБРАБОТКА ВНЕШНЕГО ПРЕРЫВАНИЯ 0 - ОТ ДВУХФАЗНОГО ИМПУЛЬСНОГО ЕНКОДЕРА
'ПРЕРЫВАНИЕ ПРОИСХОДИТ ПО СПАДУ НА ВХОДЕ P_CHA. ЗАТЕМ ПРОГРАММА ИНТЕГРИРУЕТ
' (ФИЛЬТРУЕТ) ЭТОТ УРОВЕНЬ, ДОЖИДАЯСЬ НАДЕЖНОГО УСТАНОВЛЕНИЯ "0". В МОМЕНТ
'ФИКСАЦИИ "0" НА ЛИНИИ P_cha РЕГИСТРИРУЕТСЯ УРОВЕНЬ P_chb , ПО КОТОРОМУ И
'ОПРЕДЕЛЯЕТСЯ НАПРАВЛЕНИЕ ВРАЩЕНИЯ. П/П РАБОТАЕТ ТАКЖЕ ПРИ ИСПОЛЬЗОВАНИИ
'ПРЕРЫВАНИЯ ОТ ЛЮБОГО ИЗМЕНЕНИЯ УРОВНЯ. НА СПАД СРАБАТЫВАЕТ, ФРОНТ ИГНОРИРУЕТ
'-------------------------------------------
P_cha Alias Pinb , 2 'ОПРЕДЕЛЕНИЕ ПОРТОВ ВВОДА КОДА ЦИФРОВОЙ РУЧКИ,
P_chb Alias Pinb , 3 'НО В АССЕМБЛЕРНОЙ ВСТАВКЕ ОНО НЕ РАБОТАЕТ
'-------------------------------------------
Const Con_irt = 30 'КОНСТАНТА ИНТЕГРИРОВАНИЯ УРОВНЯ НА ВХОДЕ
Const Conirt1 = Con_irt * 1.5 'ПОЛТОРЫ КОНСТАНТЫ ИНТЕГРИРОВАНИЯ
Const Conirt2 = Con_irt * 2 'ДВЕ КОНСТАНТЫ ИНТЕГРИРОВАНИЯ
'---------
$asm
Int0_0:
Inc R31 'УРОВЕНЬ ВЫСОКИЙ - ОТКАТ СЧЕТЧИКА
Cpi R31 , Conirt1 'это Con_irt*1.5
Brne Int0_1 'ЕСЛИ ЖДЕМ СЛИШКОМ ДОЛГО - ВЫХОД
Rjmp Int0_e
'---------
'ВНЕШНЕЕ ПРЕРЫВАНИЕ ОТ ЦИФРОВОЙ РУЧКИ
Int0_int:
Push R31 'сохраним регистры
In R31 , Sreg
Push R31
'-----
'ИНТЕГРИРУЮЩИЙ ФИЛЬТР (ФНЧ) ВХОДНОГО УРОВНЯ
Ldi R31 , Con_irt 'ПОСТОЯНАЯ ИНТЕГРИРОВАНИЯ В СЧЕТЧИК
Int0_1:
Sbic PINb,2 'ПРОВЕРИМ УРОВЕНЬ НА ВЫВОДЕ
Rjmp Int0_15 'ЕСЛИ НА НОЖКЕ "1" - ПЕРЕХОД
Dec R31 'ПОКА НЕ ОБНУЛИЛСЯ СЧЕТЧИК ЖДЕМ
Brne Int0_1 'МНОГОКРАТНОГО ПОДТВЕРЖДЕНИЯ НИЗКОГО УРОВНЯ
Rjmp Int0_2
'-----
'ЕСЛИ УРОВНЬ ВЫСОКИЙ
Int0_15:
Inc R31 'УВЕЛИЧИВАЕМ СЧЕТЧИК
Cpi R31 , Conirt2 'ЕСЛИ НА "1" УСТАНОВЛЕНА СЛИШКОМ ДОЛГО
Brne Int0_e 'НА ВЫХОД
Rjmp Int0_1
'---------------------------------------------
'ПРОГРАММА РАСЧИТАНА НА КОДОВЫЙ ПЕРЕКЛЮЧАТЕЛЬ
'С НОРМАЛЬНО РАЗОМКНУТЫМИ КОНТАКТАМИ, ЗАМЫКАЮЩИМИСЯ
'ТОЛЬКО В МОМЕНТ ЩЕЛЧКА. ЭТО ОЧЕНЬ УПРОЩАЕТ ЗАДАЧУ
'---------------------------------------------
' |<----- ВРАЩЕНИЕ ВЛЕВО (ИЛИ НАОБОРОТ, В ЗАВИСИМОСТИ ОТ МОНТАЖА)
'chA--- --------- ------ ОПРЕДЕЛЕНИЕ НАПРАВЛЕНИЯ
' ¦ ¦ chA ¦ ¦ ВРАЩЕНИЯ ЦИФРОВОГО КОДЕРА
' --- --- ОСНОВАНО НА АНАЛИЗЕ СОСТОЯНИЯ
'chB----- | --------- ---- КАНАЛА "B" В МОМЕНТ ЗАМЫКАНИЯ
' | ¦ | ¦ chB ¦ ¦ (ЩЕЛЧКА) В КАНАЛЕ "A"
' | --- ---
' | |<------ ВРАЩЕНИЕ ВПРАВО
'---------------------------------------------
Int0_2:
'ОБРАБОТКА ИЗМЕНЕНИЯ УРОВНЯ
'---------
Sbis PINb,3
Rjmp Int0_3 'ОПРЕДЕЛИМ НАПРАВЛЕНИЕ ВРАЩЕНИЯ
'---------
'ВРАЩЕНИЯ ВЛЕВО (УМЕНЬШЕНИЕ)
Lds R31 , {r_cdec} 'УВЕЛИЧИМ СЧЕТЧИК ЩЕЛЧКОВ ВЛЕВО
Inc R31
Sts {r_cdec} , R31
Rjmp Int0_4
'---------
Int0_3:
'ВРАЩЕНИЯ ВПРАВО (УВЕЛИЧЕНИЕ)
Lds R31 , {r_cinc} 'УВЕЛИЧИМ СЧЕТЧИК ЩЕЛЧКОВ ВПРАВО
Inc R31
Sts {r_cinc} , R31
Int0_4:
Ldi R31 , &HFF
Sts {edat} , R31 'поставить признак "НОВЫЕ ДАННЫЕ ЕНКОДЕРА"
'---------
Int0_e:
Pop R31
Out Sreg , R31
Pop R31
Reti
$end Asm
Return
'----------------------------------------------------------------------------------
Поделиться62010-11-23 13:58:38
На редкость информативно, спасибо!
Асм только немного расстраивает, но подробное описание вселяет надежду (это я о себе)
Ещё раз спасибо, буду изучать.
Поделиться72010-11-23 23:15:52
ПОПРОБУЙ В ЖЕЛЕЗЕ. ПЕРЕДЕЛАТЬ ЕНКОДЕР НА ДРУГИЕ ЛИНИИ ПОРТОВ ОЧЕНЬ ПРОСТО -
НЕПОСРЕДСТВЕННОЕ УПОМИНАНИЕ ПОДКЛЮЧЕНИЯ ВСЕГО В ЧЕТЫРЕХ МЕСТАХ ПРОГРАММЫ.
НУ, И КОНЕЧНО ПОДКЛЮЧЕНИЕ ИНДИКАТОРА. ОЧЕНЬ РЕКОМЕНДУЮ ПРИМЕНИТЬ СХЕМУ
ПОДКЛЮЧЕНИЯ С RC-ЦЕПОЧКАМИ.
' --------- + 5v
' ¦ ¦ -------
' - - ¦ AVR ¦
' | |10k | |10k ¦ ¦
' - - ¦ ¦
' 100n ¦ ¦ ¦ ¦
' |-||--+-------------¦PB2 ¦
' ¦ 100n ¦ ¦ ¦
' ¦ |-||--+-----¦PB3 ¦
' - - ¦ ¦
' | | | | ¦ ¦
' - 100 - 100 -------
' ¦ ¦
' / /
' / ChA / ChB
' ¦ ¦
' --- ----
Поделиться82012-02-06 17:43:53
А если не вешать энкодер на ногу внешнего прерывания? Я попытался использовать команду "Encoder", она работает, но криво, перескакивает то по 2, то по 3 значения(чаще по 3). вот код, удалил все, что ненужно в данный момент. оставил только энкодер и индикацию :
$regfile = "m8def.dat"
$crystal = 8000000
'----------------------------Псевдонимы---------------------------------------
Enc_1 Alias Pind.5 'Энкодер вниз
Enc_2 Alias Pind.6 'Энкодер вверх
'-------------------Конфигурирование портов-------------------------------------
Config Portc = Output 'Индикаторы
Config Enc_1 = Input 'Энкодер вниз
Config Enc_2 = Input 'Энкодер вверх
'---------------------Конфигурирование таймеров---------------------------------
Config Timer0 = Timer , Prescale = 256
On Timer0 Din_indik
'----------------------Разрешаем прерывания-------------------------------------
Enable Interrupts
Enable Timer0
Start Timer0
Dim Tdes As Byte 'для десятичной части
Dim Tcel As Byte 'для целой части
Dim T1 As Single
Dim T2 As Byte
'-------------переменные для преобразования исходного числа---------------------
Dim N1 As Byte
Dim N2 As Byte
Dim N3 As Byte
Dim N4 As Byte
Dim N5 As Byte
Dim N6 As Byte
Dim N7 As Byte
Dim M1 As Long
Dim M2 As Long
Dim M3 As Long
Dim M4 As Long
Dim M5 As Long
Dim M6 As Long
Dim M7 As Long
'-------------------------------------------------------------------------------
Dim R As Byte 'для значений отправляемых в регистр
'-----------------Начало основного цикла----------------------------------------
Tcel = 50
Do
S = Encoder(pind.6 , Pind.5 , Enc_low , Enc_hi , 0)
Loop
End 'конец программы
'массив с кодами для семисегментника
'--------------Определения 7-ми сегментника (общ. аннод)----------------------
'
Numbers:
' FBGCdpDEA (в цифры полсе сегмента это разряд порта)
Data &B00101000 '0 ***A0***
Data &B10101111 '1 * *
Data &B10011000 '2 F7 B6
Data &B10001010 '3 * *
Data &B00001111 '4 ***G5***
Data &B01001010 '5 * *
Data &B01001000 '6 E1 C4
Data &B10101110 '7 * *
Data &B00001000 '8 ***D2***
Data &B00001010 '9 dp3
Data &B11110111 'точка
Data &B01011000 'E
Data &B11011101 'r
Data &B00011100 'P
Data &B00001101 'H
Data &B01111101 'I
'подпрограмма отправки данных в регистр
Registr:
Shiftout Portc.0 , Portc.2 , R , 1 'задвигаем данные
Pulseout Portc , 1 , 5 'защелкиваем регистр
Waitus 700 'задержка переключений разрядов
Return
'подпрограмма работы с регистром переключающим аноды
Anod:
Shiftout Portc.3 , Portc.5 , R , 1
Pulseout Portc , 4 , 5
Return
Din_indik:
'раскладываем число на составляющие
M1 = Tcel
M2 = M1
'M3 = M1
M4 = M
M5 = M4
M6 = S
M7 = M6
M1 = M1 Mod 100
M1 = M1 / 10
N1 = Abs(m1)
M2 = M2 Mod 10
N2 = Abs(m2)
N3 = Tdes
M4 = M4 Mod 100
M4 = M4 / 10
N4 = Abs(m4)
M5 = M5 Mod 10
N5 = Abs(m5)
M6 = M6 Mod 100
M6 = M6 / 10
N6 = Abs(m6)
M7 = M7 Mod 10
N7 = Abs(m7)
R = &B00000001 ' первая цифра термометра
Gosub Anod
R = Lookup(n1 , Numbers)
Gosub Registr
R = &B00000010 ' вторая цифра термометра
Gosub Anod
R = Lookup(n2 , Numbers)
Gosub Registr
R = Lookup(10 , Numbers)
Gosub Registr
R = &B00000100 ' третья цифра термометра
Gosub Anod
R = Lookup(n3 , Numbers)
Gosub Registr
R = &B00001000 ' первая цифра таймера
Gosub Anod
R = Lookup(n4 , Numbers)
Gosub Registr
R = &B00010000 ' вторая цифра таймера
Gosub Anod
R = Lookup(n5 , Numbers)
Gosub Registr
R = &B00100000 ' третья цифра таймера
Gosub Anod
R = Lookup(n6 , Numbers)
Gosub Registr
R = &B01000000 ' четвертая цифра таймера
Gosub Anod
R = Lookup(n7 , Numbers)
Gosub Registr
Gifr = 128
Return
Enc_low:
Decr Tcel
'Waitms 5
Return
Enc_hi:
Incr Tcel
'Waitms 5
ReturnПоделиться92012-02-06 21:27:55
- wait (0 или 1) не пойму, что определяет?
При Wait = 0 будет постоянно проверять наличие импульсов (этакий бесконечный опрос), при Wait = 1 программа остановится и будет ждать пока пока энкодер не будет повернут в ту или иную сторону, т.е. если его не крутить, то программа остановится.
LefLabel - это имя метки, которая будет вызвана при вращении влево, Соответственно RightLabel метка для правого поворота.
Еще условия:
· П/п, которая вызывается кодером должна заканчиваться оператором Return.
· Вывод, куда подключен энкодер должен работать в режиме ввода.
· Необходимо включить подтягивающие резисторы.
Отредактировано sva-don (2012-02-06 21:38:50)
Поделиться102014-10-05 16:12:27
Хрень честно говоря этот ENCODER. Он не может работать в подпрограммах, а это БОЛЬШОЙ минус....
Поделиться112014-10-05 17:03:41
Попробуйте так:
$regfile = "m32def.dat" 'определяем контроллер $crystal = 8000000 'определяем частоту кварца/внутреннего генератора Config Pind.3 = Input 'настройка пина d3 на вход(вывод A энкодера) Valcod_a Alias Pind.3 'присваиваем пину d3 имя Valcod_a Set Portd.3 'включить внутренний подтягивающий резистор Config Pind.4 = Input 'настройка пина d4 на вход(вывод B энкодера) Valcod_b Alias Pind.4 'присваиваем пину d4 имя Valcod_b Set Portd.4 'включить внутренний подтягивающий резистор Config Int1 = Falling 'настраиваем внешнее прерывание INT1 на срабатывание при изменении из "1" в "0" On Int1 Valcoder 'подпрограмма обработки прерывания Valcoder Enable Int1 'разрешаем работу прерывания INT1 Enable Interrupts 'разрешаем глобальные прерывания Valcoder: 'подпрограмма обработки прерывания INT1 '******************************************************************************* Select Case Menu Case 1 : If Valcod_b = 1 Then 'если на линии B лог "1" Else 'если на линии B лог "0" End If Case 2 : If Valcod_b = 1 Then 'если на линии B лог "1" Else 'если на линии B лог "0" End If Case 3 : If Valcod_b = 1 Then 'если на линии B лог "1" Else 'если на линии B лог "0" End If Case 4 : If Valcod_b = 1 Then 'если на линии B лог "1" Else 'если на линии B лог "0" End If Case 5 : If Valcod_b = 1 Then 'если на линии B лог "1" Else 'если на линии B лог "0" End If End Select Return
Отредактировано max (2014-10-05 17:04:34)
Поделиться122014-10-05 18:03:51
Спасибо большое) Но я уже придумал как сделать. Просто можно обойтись без подпрограмм для меню. Поскольку энкодер вызывает и так подпрограммы, там в зависимости от условий можно без проблем указать что делать программе)
Поделиться132014-10-06 08:51:15
Config Int1 = Falling 'настраиваем внешнее прерывание INT1 на срабатывание при изменении из "1" в "0"
По идеи, у такого подхода есть один минус, энкодер не будет срабатывать при стартовом состоянии (чёт/нечет, если он замрет в положении "0" в "1"). Т.е. при первом шаге не будет отклика, если точность при старте не нужна, то - идеально.
Поделиться142014-10-21 00:07:04
Я решил свою проблему со своим энкодером (E40s6-2048-6-L-5) не используя прерываний int вот таким способом прерыванием по таймеру
в прерывании таймера опрашиваю состояния пинов и сравниваю их с предыдущим
$regfile = "m128def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 32
$baud = 38400
Dim Conl As Byte
Dim Con As Byte
Dim I As Dword
Dim Con_n As Dword
Config Portb.6 = Input : Config Portb.7 = Input
Config Timer0 = Timer , Prescale = 8
On Timer0 Tim0:
Enable Timer0
Enable Interrupts
Do
If I <> Con_n Then Print Con_n
I = Con_n
Loop
Tim0:
If Pinb.6 = 0 And Pinb.7 = 0 Then : Conl = 0 : End If
If Pinb.6 = 1 And Pinb.7 = 0 Then : Conl = 1 : End If
If Pinb.6 = 1 And Pinb.7 = 1 Then : Conl = 2 : End If
If Pinb.6 = 0 And Pinb.7 = 1 Then : Conl = 3 : End If
If Con = 0 And Conl = 1 Then : Incr Con_n : End If
If Con = 1 And Conl = 2 Then : Incr Con_n : End If
If Con = 2 And Conl = 3 Then : Incr Con_n : End If
If Con = 3 And Conl = 0 Then : Incr Con_n : End If
If Con = 0 And Conl = 3 Then : Decr Con_n : End If
If Con = 1 And Conl = 0 Then : Decr Con_n : End If
If Con = 2 And Conl = 1 Then : Decr Con_n : End If
If Con = 3 And Conl = 2 Then : Decr Con_n : End If
Con = Conl
Return
Отредактировано uh9cae (2014-10-21 00:08:44)
Поделиться152014-10-21 11:25:37
Лучше бы сделали по прерываниям от Int. Потому что 7812 прерываний в секунду от таймера, это уже перебор. Зря только тратятся ресурсы МК.
Кроме того, антидребезга нет.
Поделиться162014-10-21 16:15:56
int все заняты, это оптический энкодер в нём нет дребезга и этот энкодер даёт 4096 импульсов на оборот
Отредактировано uh9cae (2014-10-21 18:00:39)
Поделиться172014-12-06 19:11:49
Я вот понять не могу. B = Encoder(pinb.0 , Pinb.1 , Links , Rechts , 0) Использовал вот эту функцию. Выводы МК int0 int1. Мне не понятно почему энкодер так отвратно работает? Просто слов нет. Он можно сказать и не работает, только если ооооочень медленно вращать. Надо ли разрешать аппаратные или программные прерывания для этой функции? В чем может быть причина?
Поделиться182014-12-08 03:18:23
Запустить эту функцию с пристойной работой энкодера наверное маловероятно.
Поделиться192014-12-08 17:29:49
Вот так сюрприз. Может посоветуете как сделать лучше всего? Какой нибудь пример если не сложно покажите. Был бы очень благодарен)
Поделиться202014-12-08 19:52:52
$regfile = "m8adef.dat" $crystal = 8000000 Encoder1 Alias Pinb.1 Encoder2 Alias Pinb.2 Knopka Alias Pinb.0 Config Int0 = Falling Enable Int0 Enable Interrupts On Int0 Radiost Делал настройку частоты в приемничке(надо было вращать энкодер шустрей): это в основном цикле If Encoder1 = 0 And Encoder2 = 1 Then Waitms 50 Frequenz = Frequenz + 0.1 End If If Encoder1 = 1 And Encoder2 = 0 Then Waitms 50 Frequenz = Frequenz - 0.1 End If это переключение настроенных радиостанций(здесь быстро вращать энкодер не понадобилось) Radiost: If B = 2 And Encoder1 = 0 And Encoder2 = 1 Then Set Portb.7 Start Timer0 Waitms 100 Sound , Portb.6 , 75 , 300 A = A + 1 End If If B = 2 And Encoder1 = 1 And Encoder2 = 0 Then Set Portb.7 Start Timer0 Sound , Portb.6 , 75 , 300 Waitms 100 A = A - 1 End If
может пригодится.
Отредактировано Sergik07 (2014-12-08 19:53:57)
Поделиться212014-12-08 22:24:55
Даже и не знаю, но у меня работает нормально. Правда висит одна нога на прерывании. И ни каких секретов нет. И без прерывания, тоже нормално работает 
Поделиться222014-12-10 03:26:17
Sergik07 спасибо! Будем пробовать))))
Поделиться232014-12-10 03:27:28
kip я так понимаю у тебя код не большой совсем. Тогда да, будет работать корректно. Но если код большой, то обязательно начнутся проблемы.
Поделиться242014-12-10 21:44:47
У меня часы на меге8 на асинхронном таймере со светодиодным индикатором. Задействованы все таймеры ( индикация + яркость) и sound. Точнее - это кухонный таймер с функцией часов. При повороте энкодера включается установка таймера, и далее он запускается. Энкодер выдрал с автомагнитолы. Кроме того, код у меня попросил один человек(?) через мыло. И у него не пошёл энкодер. Выяснилось, что много шелчков у него. Я переделал прошивку, и при включении он настраивал энкодер под себя. Я просто добавил делитель. К сожалению быстрый поиск на компьютере не дал результатов. Попробую получше поискать. А таймер работает до сих пор. Могу видео заснять. Уверяю Вас, использовал "баскомовскую" команду
Поделиться252014-12-11 12:56:37
Ну не знаю. Может быть что то не так сделал. Но вроде все как в примере. Ладно попробую, там видно будет. Отпишу тогда.
Пичаль что нет нормального энкодера для протеуса. Приходиться кнопки ставить обычные. А сам модэли еще не умею делать.
Отредактировано Atmel (2014-12-11 12:59:39)
Поделиться262014-12-11 14:41:36
Блин. Не работает. Точнее работает, но гораздо хуже чем было О_о. Надо разбираться в коде. Что то тут не так...
Поделиться272014-12-11 18:48:32
В протеусе есть двигатель с энкодером. Я его использовал и включал в нужную сторону
Поделиться282014-12-15 19:24:48
Спасибо, но про движок знаю. Жудко неудобная хреновина))))
Поделиться292015-01-07 17:06:53
обрабатываю импульсы от оптического энкодера ЛИР-158 (1000 импульсов на оборот)
$regfile = "m8def.dat"
$crystal = 12000000
$hwstack = 32
$swstack = 32
$framesize = 32
$baud = 57600
Dim I As Word
Dim W As Word
Dim N As Word
Config Pind.5 = Input
Config Pind.6 = Input
Config Pind.7 = Input
Config Portc.4 = Output
Config Timer0 = Timer , Prescale = 8
On Timer0 Tim0:
Enable Timer0
Config Int0 = Falling ' прерывание INT0 по нисходящему фронту (c + на -)
On Int0 Encod
Enable Interrupts
Enable Int0
Do
If I <> W Then Print W
I = W
Loop
Encod: ' тут узнаем в каком направлении вращают ручку энкодера
' ждем пока утихнет дребезг контактов
If Pind.6 = 0 Then ' если на ноге единица (импульс не пришел) тогда
Incr W ' инкременируем переменную (увеличиваем на 1)
N = W
If N = 1000 Then W = 0
Else ' в обратном случае
Decr W ' декрементируем переменную (уменьшаем на 1)
N = W
If N = 0 Then W = 1000
End If
Gifr = 64
Return
Tim0:
If Pind.5 = 0 Then W = 0
If Pind.5 = 0 Then Print W
Returnдевайс цепляется через переходник USB-UART к компу и в LabView считываются импульсы.
В чем проблема: не смог к коду привязать кнопку сброса счетчиков импульсов (переменная W), кнопка сидит на Pind.5. как сейчас происходит-при вращени по часовой,значение переменной увеличивается от 0 до 1000,нажимаешь на кнопку,переменная сбрасывается в 0, если дальше вращать по часовой, то все ОК, а вот если против (после нажатия кнопки) то переменная становится =65535 (Word) и далее уменьшается.
как решить?сильно не пинайте...
Поделиться302015-01-09 09:20:10
Спасибо, sasha_1973, теперь все так как надо работает!
