Внешнее прерывание INT
29.12.2016, 20:34
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.03.2010
Сообщений: 2,896
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: Внешнее прерывание INT
Сообщение от vavan1983
|
|
У кого какие подходы к такой ситуации?
|
vavan1983, Поставьте задачу корректно.
Для чего обработка кнопок именно в прерывании? Это бывает нужно в двух случаях: когда контроллер спит, и по этому прерыванию просыпается, или когда нужно "мгновенное" время реакции на нажатие кнопки, независимо от состояния контроллера (даже если программа зациклилась))).
Во всех остальных случаях обработку кнопок в прерывание ставить не надо. Цикл опроса даже с периодом 20 мс делает реакцию на нажатие кнопок вполне приемлемой.
ЗЫ с трубачом (STM32) не ругайтесь, пики-то руки у него до сих пор помнят, может, в отличие от других ситуаций и по делу подсказать))
|
|
|
|
Сказали "Спасибо" AR_Favorit
|
|
|
30.12.2016, 01:55
|
|
|
Вид на жительство
Регистрация: 27.11.2007
Сообщений: 434
Сказал спасибо: 20
Сказали Спасибо 40 раз(а) в 30 сообщении(ях)
|
Re: Внешнее прерывание INT
Блин,а так все хорошо начиналось.
Сообщение от vavan1983
|
|
вижу маетись вы но не могу не чем помочь к сожалению.
|
А я думал это мы тут помогаем.
В общем еще один троль.
vavan1983,
у Вас не один раз срашивали про конкретную задачу, а Вы морозитесь.
|
|
|
|
Сказали "Спасибо" sat_art
|
|
|
30.12.2016, 12:55
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 26.12.2007
Сообщений: 1,198
Сказал спасибо: 70
Сказали Спасибо 80 раз(а) в 69 сообщении(ях)
|
Re: Внешнее прерывание INT
ПРИЛОЖЕНИЯ.rarsat_art, описывать много очень могу только выложить это.
|
|
|
|
30.12.2016, 14:00
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.03.2010
Сообщений: 2,896
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: Внешнее прерывание INT
Ну вот и незачем там использовать прерывание. Прямо в main выполняйте постоянный опрос входов и вывод нужных сигналов на выходы.
|
|
|
|
30.12.2016, 17:29
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 26.12.2007
Сообщений: 1,198
Сказал спасибо: 70
Сказали Спасибо 80 раз(а) в 69 сообщении(ях)
|
Re: Внешнее прерывание INT
AR_Favorit, выполнял так
Нажмите, чтобы открыть спойлер
|
Код:
|
unsigned short key[8]={1,1,1,1,1,1,1,1},cout=0;
void main()
{
OPTION_REG=0b01111111;
TRISA=0;
PORTA.RA2=1;
TRISB=0XFF;
TRISC=0;
PORTC=0;
ADCON1=0b00000110;
PORTA.RA0=1;
while(1)
{
cout++;
if(cout›5)
{
cout=0;
PORTA.RA1=~PORTA.RA1;
PORTA.RA2=~PORTA.RA2;
}
if(Button(&PORTB, 0, 10, 0)&&key[0])
{
key[0]=0;
Delay_ms(101);
PORTC.RC7=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC7=0;
}
if(Button(&PORTB, 0, 10, 1)&&!key[0])
{
key[0]=1;
}
//================================================== ============================
if(Button(&PORTB, 1, 10, 0)&&key[1])
{
key[1]=0;
Delay_ms(101);
PORTC.RC6=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC6=0;
}
if(Button(&PORTB, 1, 10, 1)&&!key[1])
{
key[1]=1;
}
//================================================== ============================
if(Button(&PORTB, 2, 10, 0)&&key[2])
{
key[2]=0;
Delay_ms(101);
PORTC.RC5=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC5=0;
}
if(Button(&PORTB, 2, 10, 1)&&!key[2])
{
key[2]=1;
}
//================================================== ============================
if(Button(&PORTB, 3, 10, 0)&&key[3])
{
key[3]=0;
Delay_ms(101);
PORTC.RC4=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC4=0;
}
if(Button(&PORTB, 3, 10, 1)&&!key[3])
{
key[3]=1;
}
//================================================== ============================
if(Button(&PORTB, 4, 10, 0)&&key[4])
{
key[4]=0;
Delay_ms(101);
PORTC.RC3=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC3=0;
}
if(Button(&PORTB, 4, 10, 1)&&!key[4])
{
key[4]=1;
}
//================================================== ============================
if(Button(&PORTB, 5, 10, 0)&&key[5])
{
key[5]=0;
Delay_ms(101);
PORTC.RC2=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC2=0;
}
if(Button(&PORTB, 5, 10, 1)&&!key[5])
{
key[5]=1;
}
//================================================== ============================
if(Button(&PORTB, 6, 10, 0)&&key[6])
{
key[6]=0;
Delay_ms(101);
PORTC.RC1=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC1=0;
}
if(Button(&PORTB, 6, 10, 1)&&!key[6])
{
key[6]=1;
}
//================================================== ============================
if(Button(&PORTB, 7, 10, 0)&&key[7])
{
key[7]=0;
Delay_ms(101);
PORTC.RC0=1;
Delay_ms(5);
PORTA.RA0=0;
Delay_ms(100);
PORTA.RA0=1;
PORTC.RC0=0;
}
if(Button(&PORTB, 7, 10, 1)&&!key[7])
{
key[7]=1;
}
//================================================== ============================
}
} |
только при нажатии на кнопу время реакции очень разное
|
|
|
|
30.12.2016, 18:01
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 26.12.2007
Сообщений: 1,198
Сказал спасибо: 70
Сказали Спасибо 80 раз(а) в 69 сообщении(ях)
|
Re: Внешнее прерывание INT
Это конечно код но такой убоготопорный. Конечно всё это работает и по сей день но как то коряво вот и удумал немного заобгрейдеть.
|
|
|
|
30.12.2016, 21:51
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 13.03.2010
Сообщений: 2,896
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: Внешнее прерывание INT
Разумеется, пока выполняются задержки для обработки вывода одной из кнопок - на остальные кнопки нет реакции.
Надо delay-и выкинуть, а сделать, к примеру, так:
1) организовать выполнение основного цикла с периодичностью 1 мс по флагу (настроить прерывание таймера так, чтобы этот флаг устанавливался в нем раз в миллисекунду), в основном цикле проверять этот флаг, и при его появлении выполнять собственно тело основного цикла, в котором помимо прочего этот флаг очищается.
2) значения в ячейках массива key[] используем одновременно и как признак занятости канала, и как текущее значение отсчитываемой задержки для канала, если он занят.
В основном цикле (раз в миллисекунду)последовател� �но проверяем каждое значение.
Если оно 0 - значит канал свободен, тогда проверяем состояние входа на порте В этого канала, если кнопка нажата - заносим в текущую ячейку key[] суммарное значение задержки (206).
Нажмите, чтобы открыть спойлер
Состояние входа проверяем не той функцией, что у вас использована (как я понимаю, в ней тоже своя задержка для подавления дребезга), а просто считыванием состояния нужной ножки порта. Дребезг (если он длится менее 200мс,) все равно не повлияет на логику работы в даном случае. А если надо защиту от кратковременных помех - вводим дополнительный массив счетчиков, если считанное состояние "кнопка не нажата" - счетчик для данного канала обнуляется, если считанное состояние "кнопка нажата" - он инкрементируется, а установка в key[] суммарного значения задержки выполняется только после накопления счетчиком данного канала определенной величины (например, 10, что означает, что вход активен уже в течение 10мс)
Если же значение в key[] для текущего канала не нулевое - декрементируем его на единицу и смотрим результат. Если получилось 105 (с момента нажатия кнопки прошло 101 мс) - включаем соответствующую ногу в порте С. Иначе если получилось 100 (прошло 101 и еще 5 мс) - включаем соответствующую ногу в порте А. Если получилось 0 - выключаем соответствующие ноги в портах А и С. Все остальные значения игнорируем.
То есть основной цикл ждет 1 мс и затем быстро выполняет проверку и смену состояний для всех 8 каналов.
Последний раз редактировалось AR_Favorit; 30.12.2016 в 22:08.
|
|
|
|
31.12.2016, 06:52
|
|
|
Заблокирован
Регистрация: 19.02.2007
Адрес: Барановичи
Сообщений: 255
Сказал спасибо: 3
Сказали Спасибо 51 раз(а) в 39 сообщении(ях)
|
Re: Внешнее прерывание INT
[QUOTE=vavan1983;1083293]Всем привет.
При нажатии на любу кнопку на любом порту PORTB значения принятой лог.отображается на PORTC проблема в том что если нажать одновременно на комбинацию RB0 и любую другую RB то RB0 не передаётся.
У кого какие подходы к такой ситуации?/QUOTE]
vavan1983, Вован Вы вроде не маленький, а всё пытаетесь дрочить чужими руками. Т.Е некий СИ-шник написал код (не сам, - ему в любом случае помог асм-овщик, который вложил свои бредовые идеи в некую оболочку как макрос, а все как макаки (абызяны) побежали это всё повторять... И вот эти все остальные - свои мозги потеряли при быстром беге за тем крутым СИ-шником, наверное ?!!
Вы в любом случае порт на свою говенную клаву изгадили, так начните сначала - пару ножек съэкономите... К примеру, ножки RB7...RB5 делаете выходами, а RB4..RB2 делаете входами, и к примеру через резисторы на 2... 5 кОм подтягиваете к минусу - получаете клаву 3Х3, т.е. ДЕВЯТЬ______ , RB1, и RB0 оставляете на случай если "пакакать" резко напрёт (это на счёт внешнего прерывания по RB0)!
Теперь дальше: У Вас в программе есть некие тайминги - отсчёты неких интервалов времени, и надеюсь эти тайминги Вы делали не командами , наподобие "DelayXXX", потому как эти отсчёты времени даже ХХХХХХХ битный проц делают бесполезным. А скорее всего Вы организовали интервалы оттсчёта неких промежутков с помощью таймера (любого из встроенного в проц, но т.к. в Пиках 16 (старой) серии таймер №0 никогда не останавливается, то чтобы бесполезно его не тратить, то отсчёты времени ВЫ организовали конечно на нём!
И вот этот таймер тикает, делает , к примерц, в Вашей программе 100 прерываний в секунду, ВЫ там конечно подсчитываете некие данные...
И вот по приходу в это прерывание, Вы выставляете на ножке (к примеру) RB7 лог. единицу, а через энный промежуток времени (если это будет 100 раз в секунду, то через каждые 10 мсек), Вы приходите в следующее прерывание, и опрашиваете три ножки (RB4..RB2), после ножку RB7 устанавливете в ноль, а ножку RB6 в единицу, а через 10 мс опять опрашиваете, потом тоже с ножкой RB5, и дальше по кругу... Пару таких кругов (в зависимости от количества прерываний в секунду) - и сравнение единиц и нулей на ножках - даст импровизированный антидребезг контактов кнопок, что в свою очередь - даст Вашему устройству более чёткое, и безпроблемное переключение по страницам меню, и т.п. ( в отличие от макросов, которые вы можете "потянуть" из разных оболочек, даже заводских).
А что вам в конечном итоге нужно - чтобы ваше устройство в течение полугода поносили разными словами (до тех пор пока на мусорку не вынесут), или что бы оно работало, и на новый год вас вспоминали добрым словом?!?
|
|
|
|
Сказали "Спасибо" ALEKS1102X
|
|
|
31.12.2016, 14:39
|
|
|
Заблокирован
Регистрация: 19.02.2007
Адрес: Барановичи
Сообщений: 255
Сказал спасибо: 3
Сказали Спасибо 51 раз(а) в 39 сообщении(ях)
|
Re: Внешнее прерывание INT

Вот как-то так...
Ну а если хочется всё-таки через "INT", то и работайте по Вашей схеме.
По прерыванию "INT" опросите порт, если нажата только кнопка RB0, то получите B'11111110', а если совместно с другими, то получите B'ххххххх0'.
Единственно, чего не получится сделать - это совместное нажатие кнопки RB0 с другими, а совместное нажатие RB1, RB2, и RB3, к примеру, зафиксируете без проблем...
|
|
|
|
31.12.2016, 14:47
|
|
|
Заблокирован
Регистрация: 19.02.2007
Адрес: Барановичи
Сообщений: 255
Сказал спасибо: 3
Сказали Спасибо 51 раз(а) в 39 сообщении(ях)
|
Re: Внешнее прерывание INT
Диоды не той стороной нарисовал, чего-то не получается правкой обновлённый файл "xx.png" закинуть...
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 20:52.
|
|