| счетчик импульсов Bascom-AVR | 
| 
				
			 | 
| 
| leshui | Дата: Воскресенье, 09.08.2015, 15:26 | Сообщение # 1 |  |   Группа: Пользователи Сообщений: 3 
 Статус: Offline | Товарищи! С этого сайта взял за основу исходник: http://avrproject.ru/publ....er=desc
 Подпилил под себя и многое не понятно.
 Вообщем хочу собрать счетчик для магнитофона, там будут стоять фото-светодиод, заодно и управление ЛПМ(ленто протяж. механизм) будет. под ЛПМ кусок я написал, осталось только со счетчиком разобраться.
 У меня считает имп. справа на лево, если обратно 999-998-997 и т.д через 0
 
 1. У меня положительные имп. заведены на прерывание INT1 (PIND.3)
 Не понятно какая команда отвечает за запись имп в переменную W порта PIND.3, почему не PIND.4?
 2. Я ни как не могу придумать как сделать чтобы каждые  10 имп менялась переменная W
 3. При подаче питании загорается на индикаторе 001, а должно 000,
 и куда бы я не втыкал W=0 все равно 001 или вообще не считает имп.
 4. для чего нужна команда GIFR=64?
 
 Дальше будут еще вопросы, помогите пока с этим разобраться
 
 
 Код 'счетчик импульсов от валкодера с индикацией на 3-х разр. семисегмент. 'в минус 999-998-997 и т.д. в плюс 001-002-003 и т.д
 
 $regfile = "2313def.dat"
 $crystal = 8000000
 $hwstack = 40
 $swstack = 16
 $framesize = 32
 '$sim
 
 Config Portb = Output                   'порт В выход для семисегмент
 
 Ddrd = &B11000111                       '1=выход 0=вход  назначаем входы\выходы
 Portd = &B00111000                      'подтяжка входов внутренними резисторами
 '1=резистор подтянут 0=резистора нет
 
 Dim W As Word
 Dim N1 As Byte
 Dim N2 As Byte
 Dim N3 As Byte
 Dim Imp As Byte
 
 Dim M1 As Integer
 Dim M2 As Integer
 Dim M3 As Integer
 
 Config Int1 = Falling                   ' прерывание INT1 по нисходящему фронту (c + на -)
 On Int1 Encod                           ' если прерывание идем на метку encod
 
 Enable Interrupts                       'включаем прерывания
 Enable Int1                             'вкл прерывание на INT1
 
 Do                    ' в главном цикле отображаем количество импульсов
 
 Portd = &B1111011
 
 Select Case N1
 Case 0 : Portb = &B11000000
 Case 1 : Portb = &B11111001
 Case 2 : Portb = &B10100100
 Case 3 : Portb = &B10110000
 Case 4 : Portb = &B10011001
 Case 5 : Portb = &B10010010
 Case 6 : Portb = &B10000010
 Case 7 : Portb = &B11111000
 Case 8 : Portb = &B10000000
 Case 9 : Portb = &B10010000
 End Select
 
 Waitms 4
 
 Portd = &B1111110
 
 Select Case N2
 Case 0 : Portb = &B11000000
 Case 1 : Portb = &B11111001
 Case 2 : Portb = &B10100100
 Case 3 : Portb = &B10110000
 Case 4 : Portb = &B10011001
 Case 5 : Portb = &B10010010
 Case 6 : Portb = &B10000010
 Case 7 : Portb = &B11111000
 Case 8 : Portb = &B10000000
 Case 9 : Portb = &B10010000
 End Select
 
 Waitms 4
 
 Portd = &B1111101
 
 Select Case N3
 Case 0 : Portb = &B11000000
 Case 1 : Portb = &B11111001
 Case 2 : Portb = &B10100100
 Case 3 : Portb = &B10110000
 Case 4 : Portb = &B10011001
 Case 5 : Portb = &B10010010
 Case 6 : Portb = &B10000010
 Case 7 : Portb = &B11111000
 Case 8 : Portb = &B10000000
 Case 9 : Portb = &B10010000
 End Select
 
 Waitms 4
 
 Loop
 End
 
 Encod:                    ' тут узнаем в каком направлении вращают ручку энкодера
 
 Waitms 4                    ' ждем пока утихнет дребезг контактов
 If Pind.5 = 1 Then                     ' если на ноге единица (импульс не пришел) тогда
 Incr W                    ' инкременируем переменную (увеличиваем на 1)
 If W > 1000 Then                       'если крутим в + и переменная больше 1000(три разряда потому 1000)
 W = 0                    'то сбрасываем переменную 0
 End If
 Else                    ' в обратном случае
 Decr W
 If W > 1000 Then
 W = 999
 End If                    ' декрементируем переменную (уменьшаем на 1)
 End If
 
 Gifr = 64                    ' сбрасываем регистр хранения прерывания INT0
 
 ' а тут готовим переменную к выводу на дисплей
 
 M3 = W
 M2 = M3
 M1 = M3
 
 M1 = M1 / 100                           ' обработка первого разряда
 N1 = Abs(m1)
 
 M2 = M2 Mod 100                         ' обработка второго разряда
 M2 = M2 / 10
 N2 = Abs(m2)
 
 M3 = M3 Mod 10                          ' обработка третьего разряда
 N3 = Abs(m3)
 
 Return
 End
 
 
 
 Сообщение отредактировал leshui - Воскресенье, 09.08.2015, 15:29 |  
 |  |  |  | 
| 
| GSV | Дата: Воскресенье, 09.08.2015, 20:11 | Сообщение # 2 |  | Группа: Друзья Сообщений: 38 
 Статус: Offline | Я сам не супер спец,но думаю так: 1.Если у вас положительные импульсы приходят на INT1,а INT1 сконфигурирован так:
 
 то надо переделать прерывание с - на + ,а сам INT1 подтянуть к земле: Если импульс заведен на ногу PIND.3,то как этот импульс может приходить на ногу PIND.4?Код Config Int1 = Falling                   ' прерывание INT1 по нисходящему фронту (c + на -)В переменную W происходит запись,когда случается прерывание по приходу на ногу PIND.3 того самого импульса.Как только импульс пришел программа переходит в обработчик прерывания:
 
 Чтобы по приходу импульса менялась переменная в обработчике прерываний я бы сделал так:Код On Int1 Encod                           ' если прерывание идем на метку encod
 Код Encod:   If Pind.3 = 1 Then                    'Если на  Pind.3 пришла единица
 Waitms 5
 W = W + 1                    'увеличиваем переменную W на единицу
 End If
 
 Return
2.Надо завести ещё одну переменную,например Ww и в обработчике прерываний прибавлять к ней по единице 10 раз и как только она изменится в десятый раз,прибавлять к переменной W  единицу,а переменную Ww сбрасывать в ноль:
 
 3.Может при подаче питания сразу вызывается прерывание и счетчик прибавляет единицу. По вашему коду  прерывание сидит на единице и ждет ноль,а при включении питания он этот ноль сразу и получает.Код Encod:  If Pind.3 = 1 Then                    'Если на  Pind.3 пришла единица
 Waitms 5
 Ww = Ww + 1
 If Ww = 10 Then
 W = W + 1                    'увеличиваем переменную W на единицу
 Ww = 0
 End If
 End If
 
 Return
4.GIFR=64 - это сброс флага прерывания INT0,но у 2313,по даташиту,регистр флагов прерываний называется EIFR
 
 Вот сюда положил даташит на 2313 на русском-https://yadi.sk/i/xLHOg65AiMRrD.Увлекательное чтиво ))
 
 
 |  
 |  |  |  | 
| 
| leshui | Дата: Воскресенье, 09.08.2015, 20:35 | Сообщение # 3 |  |   Группа: Пользователи Сообщений: 3 
 Статус: Offline | спасибо, щась буду думать. Все таки мне не понятно, где здесь команда которая указывает что с прерывания нужно результат занести в переменную W.
 И при вкл. питания какое в переменной W все-таки число? Отладчик Bascom ответ на это не дал.
 
 
 |  
 |  |  |  | 
| 
| leshui | Дата: Воскресенье, 09.08.2015, 20:59 | Сообщение # 4 |  |   Группа: Пользователи Сообщений: 3 
 Статус: Offline |  А можно это сделать внутренним резистором?Цитата то надо переделать прерывание с - на + ,а сам INT1 подтянуть к земле:
 
 |  
 |  |  |  | 
| 
| GSV | Дата: Воскресенье, 09.08.2015, 21:29 | Сообщение # 5 |  | Группа: Друзья Сообщений: 38 
 Статус: Offline | Прерывание отсылает программу в обработчик прерывания Encod и там мы делаем все,что нам нужно,например,меняем значение переменной W,прибавляя к ней единицу.Цитата leshui (  ) где здесь команда которая указывает что с прерывания нужно результат занести в переменную W
 Знаю,что внутренними можно подтянуть к единице,но всегда пользуюсь обычными резисторами,мне кажется так надежней.Цитата leshui (  ) А можно это сделать внутренним резистором?
 При включении в переменных должен быть ноль.Цитата leshui (  ) И при вкл. питания какое в переменной W все-таки число?
 
 |  
 |  |  |  | 
| 
| a5020k | Дата: Пятница, 14.08.2015, 14:04 | Сообщение # 6 |  |   Группа: Свой человек Сообщений: 43 
 Статус: Offline | leshui магнитофон видимо катушечный? Может вы не правильный импульс подаете на порт?
 Схема считывания какая до входа в порт какая?
 
 
 |  
 |  |  |  |