Страница 1 из 2
8051. Прерывание на кнопке, жесть.
Добавлено: Ср янв 20, 2021 21:47:17
Shuspano
Что нибудь можно сделать, чтоб избавится от дребезга? Пытаюсь сбрасывать бит IE0 в регистре PCON, на 12-тактовых это более-менее работает, на 1-тактовом (STC11F04E) это не работает никак, видимо слишком шустрый. Пытался внедрять задержки в подпрограмме, тоже не катит совсем. Кнопка на #INT0 работает кошмарно. Что в таких случаях обычно делается?
Код: Выделить всё
ledpin bit P3.7
org 0000h
jmp main
org 0003h
jmp ledchange
org 000Bh
main:
setb EX0
setb IT0
setb EA
loop:
mov PCON, #00000001B
jmp loop
ledchange:
clr EA
clr IE0
cpl ledpin
setb EA
reti
end
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Ср янв 20, 2021 22:13:37
Ser60
В сети куча информации по борьбе с дребезгом. См, например, здесь:
https://radioprog.ru/post/251
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 00:05:00
Shuspano
[uquote="Ser60",url="/forum/viewtopic.php?p=3964094#p3964094"]В сети куча информации по борьбе с дребезгом. См, например, здесь:
https://radioprog.ru/post/251[/uquote]
Не спорю, но про то как это сделать в прерывании у 8051-го - чё-то небогато.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 00:31:30
Аlex
Потому что никто так не делает. Разве что, из всяких слипов выходить.
К чему такая молниеносная реакция на нажатие кнопки ?
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 00:33:44
Ser60
Вот мой старый проект часов на асме для С8051. Анти-дребезг реализован в соответствии с алгоритмом в листинге 1 на стр. 20 в приложенной PDF.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 00:53:33
Shuspano
[uquote="Аlex",url="/forum/viewtopic.php?p=3964154#p3964154"]Потому что никто так не делает. Разве что, из всяких слипов выходить.
К чему такая молниеносная реакция на нажатие кнопки ?[/uquote]
молниеносная реакция мне не нужна. На самом деле пока не смог придумать как сделать кнопки на МК по-другому.
Хочется читать штук 8, сразу. Захожу в прерывание, читаю порт с кнопками, кладу в регистр, выхожу из прерывания (МК при этом снимается с IDLE), Прерывание по нажатию любой кнопки, через диодное лог. "ИЛИ" на вход инта. Вроде все классно.
Но пока решил попробовать с одной, и получается не очень.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 07:47:33
tonyk
Сканировать по таймеру каждые 20-50мс не пробовал?
Так-то классика жанра, которую ТС не знает. Ха-ха... С IDLE можешь выходить по прерыванию таймера, что, обычно, позволяли все МК на ядре MCS-51, с которыми я когда-то работал. И не нужно ни каких "монтажных И". Для считывания 8 кнопок хватит 6 ног МК. Если ног не хватает, то добавляется сдвиговый регистр, который уменьшит число потребных ног до трёх.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 09:12:03
Zhuk72
https://m.radiokot.ru/forum/viewtopic.php?f=61&t=79801
Там буквально на первых страницах описан принцип, Alex даже приводил пример на Си. По тому же принципу и действуйте на асме.
Для начала заведите таймер на 1 мс. На него и заведите все процессы: чтение кнопок, отображение информации, считайте датчики и пр.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 10:15:14
otest
В схеме диоды нужно переставить в цепь R1,R3.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 10:37:00
BOB51

Px.0-Px.2 настроены как входы с подтягивающим резистором.
Собственно там больше мороки с режимом прерывания - вход в обработчик по прерыванию, затем в теле обработчика запрет прерывания по INT, замена адреса возврата на адрес подпрограммы антидребезгового анализатора (при резервировании адреса возврата в точку вызова INT) и reti.
Далее выполняем антидребезг, захват комбинации и по завершении ret в точку вызова INT с последующим разрешением самого INT.
Это на случай, если в системе критичны прерывания более низкого уровня.
Собственно сам антидребезг классика - последовательное чтение комбинации ЛВК при сравнении с предыдущим прочитанным.
старт
читать данные с Px.n - Px.m
совпали с буфером?
если совпало - установить флаг "данные готовы" и выход
если нет - перезапись значения буфера текущим считанным, задержка в N интервал и повторять от старт

Ну и ессно смотрим чтобы выход на исполнение был не ранее "полного отпускания" ВСЕХ кнопок (или смены стабильной комбинации, если таковое возможно для программы). Иначе сразу по выходу снова в прерывание вскочим.
Там вариаций море - все зависит от фантазии автора.

Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 12:52:53
Shuspano
Вот только как все это сделать, блин. Примеры на "С" (а других в общем, нет) мне непонятны, я его почти не знаю, в больших программах на асме тоже сложно разобраться.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 14:05:47
BOB51
Вечерком чегось поднашкрябаю для примера...
Именно под вариант прерывания - но только для базовой классики (AT89C51 за основу).
Для STC там надо "привести в соответствие" - влазить в доки чуток влом.

Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 14:20:09
Zhuk72
Таймер с прерыванием в 1 мс настроить сможете?
Заведите переменную, скажем counter = 20.
В прерывании по таймеру делаете декремент counter, затем проверяете на 0.
Если counter == 0, выставляете какой-то флаг, read_keys = 1.
В основном цикле программы постоянно сканируете этот флаг на равенство 1.
Как только поймали, делаете read_keys = 0, counter = 20, call scan_keys.
В scan_keys считываете весь порт в переменную keys в инверсном виде (вам же 8 кнопок нужно было?)
Если keys не равен 0 проверяете его на равнство keys_old (предыдущее значение). Если не равны, то keys_old = keys и на выход.
Если равны, значит в текущее значение равно считанному 20 мс назад - это ваш антидребезг. По значению переменной keys оперируете кнопками. При выходе обнуляете keys_old = keys = 0, но и тут возможны варианты, если планируете обрабатывать длительные нажатия.
Все это на ассемблере.
А вообще, переходите на Си. Чтобы начать писать на нем, совсем необязательно знать все возможности.
Начните с базовых операций, а остальное изучите по ходу дела.
Добавлено after 6 minutes 11 seconds:
[uquote="BOB51",url="/forum/viewtopic.php?p=3964353#p3964353"]... для базовой классики (AT89C51 за основу)[/uquote]
STC11F04E, кстати, имеет совместимую с AT89C2051 цоколевку.
Отличаться может только вторым режимом таймера.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 14:47:17
BOB51
Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...
Мне его готовить влом... имеется в наличии для STCшек только под stc15f204ea...
Да так пока и лежит без дела (несмотря что есть подопытный МК).

Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 14:49:48
Zhuk72
[uquote="Zhuk72",url="/forum/viewtopic.php?p=3964359#p3964359"]Таймер с прерыванием в 1 мс настроить сможете?[/uquote]
Вспомнил, что в программе для прошивки встроены различные полезные утилиты для генерации готового кода, например, настройка таймера, а также множество демо-кодов (правда, описание на китайском, да еще и шрифт левый). Причем все это и на Си, и на асме. В даташите на семейство тоже хватает примеров использования.
Добавлено after 2 minutes 11 seconds:
[uquote="BOB51",url="/forum/viewtopic.php?p=3964377#p3964377"]Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...[/uquote]
В прошивальщике все это есть:
Спойлер
Код: Выделить всё
#ifndef __STC12C5A60S2_H_
#define __STC12C5A60S2_H_
/////////////////////////////////////////////////
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъДЪєЛМШК⹦ДЬјДґжЖч C51 Core SFRs
// 7 6 5 4 3 2 1 0 Reset Value
sfr ACC = 0xE0; //Accumulator 0000,0000
sfr B = 0xF0; //B Register 0000,0000
sfr PSW = 0xD0; //Program Status Word CY AC F0 RS1 RS0 OV F1 P 0000,0000
//-----------------------------------
sbit CY = PSW^7;
sbit AC = PSW^6;
sbit F0 = PSW^5;
sbit RS1 = PSW^4;
sbit RS0 = PSW^3;
sbit OV = PSW^2;
sbit P = PSW^0;
//-----------------------------------
sfr SP = 0x81; //Stack Pointer 0000,0111
sfr DPL = 0x82; //Data Pointer Low Byte 0000,0000
sfr DPH = 0x83; //Data Pointer High Byte 0000,0000
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъПµНі№ЬАнМШК⹦ДЬјДґжЖч
// 7 6 5 4 3 2 1 0 Reset Value
sfr PCON = 0x87; //Power Control SMOD SMOD0 LVDF POF GF1 GF0 PD IDL 0001,0000
// 7 6 5 4 3 2 1 0 Reset Value
sfr AUXR = 0x8E; //Auxiliary Register T0x12 T1x12 UART_M0x6 BRTR S2SMOD BRTx12 EXTRAM S1BRS 0000,0000
//-----------------------------------
sfr AUXR1 = 0xA2; //Auxiliary Register 1 - PCA_P4 SPI_P4 S2_P4 GF2 ADRJ - DPS 0000,0000
/*
PCA_P4:
0, И±КЎPCA ФЪP1 їЪ
1Ј¬PCA/PWM ґУP1 їЪЗР»»µЅP4 їЪ: ECI ґУP1.2 ЗР»»µЅP4.1 їЪЈ¬
PCA0/PWM0 ґУP1.3 ЗР»»µЅP4.2 їЪ
PCA1/PWM1 ґУP1.4 ЗР»»µЅP4.3 їЪ
SPI_P4:
0, И±КЎSPI ФЪP1 їЪ
1Ј¬SPI ґУP1 їЪЗР»»µЅP4 їЪ: SPICLK ґУP1.7 ЗР»»µЅP4.3 їЪ
MISO ґУP1.6 ЗР»»µЅP4.2 їЪ
MOSI ґУP1.5 ЗР»»µЅP4.1 їЪ
SS ґУP1.4 ЗР»»µЅP4.0 їЪ
S2_P4:
0, И±КЎUART2 ФЪP1 їЪ
1Ј¬UART2 ґУP1 їЪЗР»»µЅP4 їЪ: TxD2 ґУP1.3 ЗР»»µЅP4.3 їЪ
RxD2 ґУP1.2 ЗР»»µЅP4.2 їЪ
GF2: НЁУГ±кЦѕО»
ADRJ:
0, 10 О»A/D ЧЄ»»Ѕб№ыµДёЯ8 О»·ЕФЪADC_RES јДґжЖч, µН2 О»·ЕФЪADC_RESL јДґжЖч
1Ј¬10 О»A/D ЧЄ»»Ѕб№ыµДЧоёЯ2 О»·ЕФЪADC_RES јДґжЖчµДµН2 О», µН8 О»·ЕФЪADC_RESL јДґжЖч
DPS: 0, К№УГИ±КЎКэѕЭЦёХлDPTR0
1Ј¬К№УГБнТ»ёцКэѕЭЦёХлDPTR1
*/
//-----------------------------------
sfr WAKE_CLKO = 0x8F; //ёЅјУµД SFR WAK1_CLKO
/*
7 6 5 4 3 2 1 0 Reset Value
PCAWAKEUP RXD_PIN_IE T1_PIN_IE T0_PIN_IE LVD_WAKE _ T1CLKO T0CLKO 0000,0000B
b7 - PCAWAKEUP : PCA ЦР¶ПїЙ»ЅРС powerdownЎЈ
b6 - RXD_PIN_IE : µ± P3.0(RXD) ПВЅµСШЦГО» RI К±їЙ»ЅРС powerdown(±ШРлґтїЄПаУ¦ЦР¶П)ЎЈ
b5 - T1_PIN_IE : µ± T1 ЅЕПВЅµСШЦГО» T1 ЦР¶П±кЦѕК±їЙ»ЅРС powerdown(±ШРлґтїЄПаУ¦ЦР¶П)ЎЈ
b4 - T0_PIN_IE : µ± T0 ЅЕПВЅµСШЦГО» T0 ЦР¶П±кЦѕК±їЙ»ЅРС powerdown(±ШРлґтїЄПаУ¦ЦР¶П)ЎЈ
b3 - LVD_WAKE : µ± CMPIN ЅЕµНµзЖЅЦГО» LVD ЦР¶П±кЦѕК±їЙ»ЅРС powerdown(±ШРлґтїЄПаУ¦ЦР¶П)ЎЈ
b2 -
b1 - T1CLKO : ФКРн T1CKO(P3.5) ЅЕКдіц T1 ТзіцВціеЈ¬Fck1 = 1/2 T1 ТзіцВК
b0 - T0CLKO : ФКРн T0CKO(P3.4) ЅЕКдіц T0 ТзіцВціеЈ¬Fck0 = 1/2 T1 ТзіцВК
*/
//-----------------------------------
sfr CLK_DIV = 0x97; //Clock Divder - - - - - CLKS2 CLKS1 CLKS0 xxxx,x000
//-----------------------------------
sfr BUS_SPEED = 0xA1; //Stretch register - - ALES1 ALES0 - RWS2 RWS1 RWS0 xx10,x011
/*
ALES1 and ALES0:
00 : The P0 address setup time and hold time to ALE negative edge is one clock cycle
01 : The P0 address setup time and hold time to ALE negative edge is two clock cycles.
10 : The P0 address setup time and hold time to ALE negative edge is three clock cycles. (default)
11 : The P0 address setup time and hold time to ALE negative edge is four clock cycles.
RWS2,RWS1,RWS0:
000 : The MOVX read/write pulse is 1 clock cycle.
001 : The MOVX read/write pulse is 2 clock cycles.
010 : The MOVX read/write pulse is 3 clock cycles.
011 : The MOVX read/write pulse is 4 clock cycles. (default)
100 : The MOVX read/write pulse is 5 clock cycles.
101 : The MOVX read/write pulse is 6 clock cycles.
110 : The MOVX read/write pulse is 7 clock cycles.
111 : The MOVX read/write pulse is 8 clock cycles.
*/
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъЦР¶ПМШК⹦ДЬјДґжЖч
//УРµДЦР¶ПїШЦЖЎўЦР¶П±кЦѕО»ЙўІјФЪЖдЛьМШК⹦ДЬјДґжЖчЦРЈ¬ХвР©О»ФЪО»µШЦ·ЦР¶ЁТе
//ЖдЦРУРµДО»ОЮО»С°Ц·ДЬБ¦Ј¬ЗлІОФД РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъЦРОДЦёДП
// 7 6 5 4 3 2 1 0 Reset Value
sfr IE = 0xA8; //ЦР¶ПїШЦЖјДґжЖч EA ELVD EADC ES ET1 EX1 ET0 EX0 0x00,0000
//-----------------------
sbit EA = IE^7;
sbit ELVD = IE^6; //µНС№јаІвЦР¶ПФКРнО»
sbit EADC = IE^5; //ADC ЦР¶ПФКРнО»
sbit ES = IE^4;
sbit ET1 = IE^3;
sbit EX1 = IE^2;
sbit ET0 = IE^1;
sbit EX0 = IE^0;
//-----------------------
sfr IE2 = 0xAF; //Auxiliary Interrupt - - - - - - ESPI ES2 0000,0000B
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr IP = 0xB8; //ЦР¶ПУЕПИј¶µНО» PPCA PLVD PADC PS PT1 PX1 PT0 PX0 0000,0000
//--------
sbit PPCA = IP^7; //PCA ДЈїйЦР¶ПУЕПИј¶
sbit PLVD = IP^6; //µНС№јаІвЦР¶ПУЕПИј¶
sbit PADC = IP^5; //ADC ЦР¶ПУЕПИј¶
sbit PS = IP^4;
sbit PT1 = IP^3;
sbit PX1 = IP^2;
sbit PT0 = IP^1;
sbit PX0 = IP^0;
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr IPH = 0xB7; //ЦР¶ПУЕПИј¶ёЯО» PPCAH PLVDH PADCH PSH PT1H PX1H PT0H PX0H 0000,0000
sfr IP2 = 0xB5; // - - - - - - PSPI PS2 xxxx,xx00
sfr IPH2 = 0xB6; // - - - - - - PSPIH PS2H xxxx,xx00
//-----------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъI/O їЪМШК⹦ДЬјДґжЖч
// 7 6 5 4 3 2 1 0 Reset Value
sfr P0 = 0x80; //8 bitPort0 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0 1111,1111
sbit P00 = P0^0;
sbit P01 = P0^1;
sbit P02 = P0^2;
sbit P03 = P0^3;
sbit P04 = P0^4;
sbit P05 = P0^5;
sbit P06 = P0^6;
sbit P07 = P0^7;
sfr P0M0 = 0x94; // 0000,0000
sfr P0M1 = 0x93; // 0000,0000
sfr P1 = 0x90; //8 bitPort1 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 1111,1111
sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
sbit P15 = P1^5;
sbit P16 = P1^6;
sbit P17 = P1^7;
sfr P1M0 = 0x92; // 0000,0000
sfr P1M1 = 0x91; // 0000,0000
sfr P1ASF = 0x9D; //P1 analog special function
sfr P2 = 0xA0; //8 bitPort2 P2.7 P2.6 P2.5 P2.4 P2.3 P2.2 P2.1 P2.0 1111,1111
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;
sfr P2M0 = 0x96; // 0000,0000
sfr P2M1 = 0x95; // 0000,0000
sfr P3 = 0xB0; //8 bitPort3 P3.7 P3.6 P3.5 P3.4 P3.3 P3.2 P3.1 P3.0 1111,1111
sbit P30 = P3^0;
sbit P31 = P3^1;
sbit P32 = P3^2;
sbit P33 = P3^3;
sbit P34 = P3^4;
sbit P35 = P3^5;
sbit P36 = P3^6;
sbit P37 = P3^7;
sfr P3M0 = 0xB2; // 0000,0000
sfr P3M1 = 0xB1; // 0000,0000
sfr P4 = 0xC0; //8 bitPort4 P4.7 P4.6 P4.5 P4.4 P4.3 P4.2 P4.1 P4.0 1111,1111
sbit P40 = P4^0;
sbit P41 = P4^1;
sbit P42 = P4^2;
sbit P43 = P4^3;
sbit P44 = P4^4;
sbit P45 = P4^5;
sbit P46 = P4^6;
sbit P47 = P4^7;
sfr P4M0 = 0xB4; // 0000,0000
sfr P4M1 = 0xB3; // 0000,0000
// 7 6 5 4 3 2 1 0 Reset Value
sfr P4SW = 0xBB; //Port-4 switch - LVD_P4.6 ALE_P4.5 NA_P4.4 - - - - x000,xxxx
sfr P5 = 0xC8; //8 bitPort5 - - - - P5.3 P5.2 P5.1 P5.0 xxxx,1111
sbit P50 = P5^0;
sbit P51 = P5^1;
sbit P52 = P5^2;
sbit P53 = P5^3;
sfr P5M0 = 0xCA; // 0000,0000
sfr P5M1 = 0xC9; // 0000,0000
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъ¶ЁК±ЖчМШК⹦ДЬјДґжЖч
// 7 6 5 4 3 2 1 0 Reset Value
sfr TCON = 0x88; //T0/T1 Control TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 0000,0000
//-----------------------------------
sbit TF1 = TCON^7;
sbit TR1 = TCON^6;
sbit TF0 = TCON^5;
sbit TR0 = TCON^4;
sbit IE1 = TCON^3;
sbit IT1 = TCON^2;
sbit IE0 = TCON^1;
sbit IT0 = TCON^0;
//-----------------------------------
sfr TMOD = 0x89; //T0/T1 Modes GATE1 C/T1 M1_1 M1_0 GATE0 C/T0 M0_1 M0_0 0000,0000
sfr TL0 = 0x8A; //T0 Low Byte 0000,0000
sfr TH0 = 0x8C; //T0 High Byte 0000,0000
sfr TL1 = 0x8B; //T1 Low Byte 0000,0000
sfr TH1 = 0x8D; //T1 High Byte 0000,0000
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъґ®РРїЪМШК⹦ДЬјДґжЖч
// 7 6 5 4 3 2 1 0 Reset Value
sfr SCON = 0x98; //Serial Control SM0/FE SM1 SM2 REN TB8 RB8 TI RI 0000,0000
//-----------------------------------
sbit SM0 = SCON^7; //SM0/FE
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI = SCON^1;
sbit RI = SCON^0;
//-----------------------------------
sfr SBUF = 0x99; //Serial Data Buffer xxxx,xxxx
sfr SADEN = 0xB9; //Slave Address Mask 0000,0000
sfr SADDR = 0xA9; //Slave Address 0000,0000
//-----------------------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr S2CON = 0x9A; //S2 Control S2SM0 S2SM1 S2SM2 S2REN S2TB8 S2RB8 S2TI S2RI 00000000B
sfr S2BUF = 0x9B; //S2 Serial Buffer xxxx,xxxx
sfr BRT = 0x9C; //S2 Baud-Rate Timer 0000,0000
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъїґГЕ№·¶ЁК±ЖчМШК⹦ДЬјДґжЖч
sfr WDT_CONTR = 0xC1; //Watch-Dog-Timer Control register
// 7 6 5 4 3 2 1 0 Reset Value
// WDT_FLAG - EN_WDT CLR_WDT IDLE_WDT PS2 PS1 PS0 xx00,0000
//-----------------------
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъPCA/PWM МШК⹦ДЬјДґжЖч
// 7 6 5 4 3 2 1 0 Reset Value
sfr CCON = 0xD8; //PCA їШЦЖјДґжЖчЎЈ CF CR - - - - CCF1 CCF0 00xx,xx00
//-----------------------
sbit CF = CCON^7; //PCAјЖКэЖчТзіц±кЦѕ,УЙУІјю»тИнјюЦГО»,±ШРлУЙИнјюЗе0ЎЈ
sbit CR = CCON^6; //1:ФКРн PCA јЖКэЖчјЖКэ, ±ШРлУЙИнјюЗе0ЎЈ
//-
//-
sbit CCF1 = CCON^1; //PCA ДЈїй1 ЦР¶П±кЦѕ, УЙУІјюЦГО», ±ШРлУЙИнјюЗе0ЎЈ
sbit CCF0 = CCON^0; //PCA ДЈїй0 ЦР¶П±кЦѕ, УЙУІјюЦГО», ±ШРлУЙИнјюЗе0ЎЈ
//-----------------------
sfr CMOD = 0xD9; //PCA №¤ЧчДЈКЅјДґжЖчЎЈ CIDL - - - CPS2 CPS1 CPS0 ECF 0xxx,x000
/*
CIDL: idle ЧґМ¬К± PCA јЖКэЖчКЗ·сјМРшјЖКэ, 0: јМРшјЖКэ, 1: НЈЦ№јЖКэЎЈ
CPS2: PCA јЖКэЖчВціеФґСЎФсО» 2ЎЈ
CPS1: PCA јЖКэЖчВціеФґСЎФсО» 1ЎЈ
CPS0: PCA јЖКэЖчВціеФґСЎФсО» 0ЎЈ
CPS2 CPS1 CPS0
0 0 0 ПµНіК±ЦУЖµВК fosc/12ЎЈ
0 0 1 ПµНіК±ЦУЖµВК fosc/2ЎЈ
0 1 0 Timer0 ТзіцЎЈ
0 1 1 УЙ ECI/P3.4 ЅЕКдИлµДНвІїК±ЦУЈ¬Чоґу fosc/2ЎЈ
1 0 0 ПµНіК±ЦУЖµВКЈ¬ Fosc/1
1 0 1 ПµНіК±ЦУЖµВК/4Ј¬Fosc/4
1 1 0 ПµНіК±ЦУЖµВК/6Ј¬Fosc/6
1 1 1 ПµНіК±ЦУЖµВК/8Ј¬Fosc/8
ECF: PCAјЖКэЖчТзіцЦР¶ПФКРнО», 1--ФКРн CF(CCON.7) ІъЙъЦР¶ПЎЈ
*/
//-----------------------
sfr CL = 0xE9; //PCA јЖКэЖчµНО» 0000,0000
sfr CH = 0xF9; //PCA јЖКэЖчёЯО» 0000,0000
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr CCAPM0 = 0xDA; //PCA ДЈїй0 PWM јДґжЖч - ECOM0 CAPP0 CAPN0 MAT0 TOG0 PWM0 ECCF0 x000,0000
sfr CCAPM1 = 0xDB; //PCA ДЈїй1 PWM јДґжЖч - ECOM1 CAPP1 CAPN1 MAT1 TOG1 PWM1 ECCF1 x000,0000
//ECOMn = 1:ФКРн±ИЅП№¦ДЬЎЈ
//CAPPn = 1:ФКРнЙПЙэСШґҐ·ўІ¶ЧЅ№¦ДЬЎЈ
//CAPNn = 1:ФКРнПВЅµСШґҐ·ўІ¶ЧЅ№¦ДЬЎЈ
//MATn = 1:µ±ЖҐЕдЗйїц·ўЙъК±, ФКРн CCON ЦРµД CCFn ЦГО»ЎЈ
//TOGn = 1:µ±ЖҐЕдЗйїц·ўЙъК±, CEXn Ѕ«·ЧЄЎЈ
//PWMn = 1:Ѕ« CEXn ЙиЦГОЄ PWM КдіцЎЈ
//ECCFn = 1:ФКРн CCON ЦРµД CCFn ґҐ·ўЦР¶ПЎЈ
//ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn
// 0 0 0 0 0 0 0 0x00 ОґЖфУГИОєО№¦ДЬЎЈ
// x 1 0 0 0 0 x 0x21 16О»CEXnЙПЙэСШґҐ·ўІ¶ЧЅ№¦ДЬЎЈ
// x 0 1 0 0 0 x 0x11 16О»CEXnПВЅµСШґҐ·ўІ¶ЧЅ№¦ДЬЎЈ
// x 1 1 0 0 0 x 0x31 16О»CEXn±ЯСШ(ЙПЎўПВСШ)ґҐ·ўІ¶ЧЅ№¦ДЬЎЈ
// 1 0 0 1 0 0 x 0x49 16О»Инјю¶ЁК±ЖчЎЈ
// 1 0 0 1 1 0 x 0x4d 16О»ёЯЛЩВціеКдіцЎЈ
// 1 0 0 0 0 1 0 0x42 8О» PWMЎЈ
//ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn
// 0 0 0 0 0 0 0 0x00 ОЮґЛІЩЧч
// 1 0 0 0 0 1 0 0x42 ЖХНЁ8О»PWM, ОЮЦР¶П
// 1 1 0 0 0 1 1 0x63 PWMКдіцУЙµН±дёЯїЙІъЙъЦР¶П
// 1 0 1 0 0 1 1 0x53 PWMКдіцУЙёЯ±дµНїЙІъЙъЦР¶П
// 1 1 1 0 0 1 1 0x73 PWMКдіцУЙµН±дёЯ»тУЙёЯ±дµН¶јїЙІъЙъЦР¶П
//-----------------------
sfr CCAP0L = 0xEA; //PCA ДЈїй 0 µДІ¶ЧЅ/±ИЅПјДґжЖчµН 8 О»ЎЈ 0000,0000
sfr CCAP0H = 0xFA; //PCA ДЈїй 0 µДІ¶ЧЅ/±ИЅПјДґжЖчёЯ 8 О»ЎЈ 0000,0000
sfr CCAP1L = 0xEB; //PCA ДЈїй 1 µДІ¶ЧЅ/±ИЅПјДґжЖчµН 8 О»ЎЈ 0000,0000
sfr CCAP1H = 0xFB; //PCA ДЈїй 1 µДІ¶ЧЅ/±ИЅПјДґжЖчёЯ 8 О»ЎЈ 0000,0000
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr PCA_PWM0 = 0xF2; //PCA ДЈїй0 PWM јДґжЖчЎЈ - - - - - - EPC0H EPC0L xxxx,xx00
sfr PCA_PWM1 = 0xF3; //PCA ДЈїй1 PWM јДґжЖчЎЈ - - - - - - EPC1H EPC1L xxxx,xx00
//PCA_PWMn: 7 6 5 4 3 2 1 0
// - - - - - - EPCnH EPCnL
//B7-B2: ±ЈБф
//B1(EPCnH): ФЪ PWM ДЈКЅПВЈ¬Ул CCAPnH ЧйіЙ 9 О»КэЎЈ
//B0(EPCnL): ФЪ PWM ДЈКЅПВЈ¬Ул CCAPnL ЧйіЙ 9 О»КэЎЈ
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъ ADC МШК⹦ДЬјДґжЖч
// 7 6 5 4 3 2 1 0 Reset Value
sfr ADC_CONTR = 0xBC; //A/D ЧЄ»»їШЦЖјДґжЖч ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0 0000,0000
sfr ADC_RES = 0xBD; //A/D ЧЄ»»Ѕб№ыёЯ8О» ADCV.9 ADCV.8 ADCV.7 ADCV.6 ADCV.5 ADCV.4 ADCV.3 ADCV.2 0000,0000
sfr ADC_RESL = 0xBE; //A/D ЧЄ»»Ѕб№ыµН2О» ADCV.1 ADCV.0 0000,0000
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъ SPI МШК⹦ДЬјДґжЖч
// 7 6 5 4 3 2 1 0 Reset Value
sfr SPCTL = 0xCE; //SPI Control Register SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 0000,0100
sfr SPSTAT = 0xCD; //SPI Status Register SPIF WCOL - - - - - - 00xx,xxxx
sfr SPDAT = 0xCF; //SPI Data Register 0000,0000
//--------------------------------------------------------------------------------
//РВТ»ґъ 1T 8051ПµБР µҐЖ¬»ъ IAP/ISP МШК⹦ДЬјДґжЖч
sfr IAP_DATA = 0xC2;
sfr IAP_ADDRH = 0xC3;
sfr IAP_ADDRL = 0xC4;
// 7 6 5 4 3 2 1 0 Reset Value
sfr IAP_CMD = 0xC5; //IAP Mode Table 0 - - - - - MS1 MS0 0xxx,xx00
sfr IAP_TRIG = 0xC6;
sfr IAP_CONTR = 0xC7; //IAP Control Register IAPEN SWBS SWRST CFAIL - WT2 WT1 WT0 0000,x000
//--------------------------------------------------------------------------------
/////////////////////////////////////////////////
#endif
Сравнить регистры и поправить.
15F204 от 11F04E практически не отличается.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 14:54:35
Shuspano
Zhuk72 писал(а):Если keys не равен 0 проверяете его на равнство keys_old (предыдущее значение). Если не равны, то keys_old = keys и на выход.
меня вот тут ступор случилсся, чтоб сравнить с keys_old, его надо сначала где-то и как-то установить. А все проходы одинаковые, непонятно, где old, а где не old/
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 15:01:42
Zhuk72
Изначально и старый и текущий - нулевые.
Если при считывании текущий не ноль, тогда только сравниваете со старым. Если не равны, то keys_old = keys и на выход.
В следующем проходе, если нажатие все-такие существуют, они будут равны, тогда и обрабатываете значение keys. При выходе опять обнуляете оба регистра (или нет, зависит от хотелок).
keys (если через инверсию читаете) может быть равен 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 или 0x80.
Ну это если одновременно 2 и более кнопок не нажмете.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 15:04:01
Shuspano
[uquote="BOB51",url="/forum/viewtopic.php?p=3964377#p3964377"]Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...[/uquote]
Я вообще не парюсь. Например, нужен регистр какого нет в классике, например, SPI в МК STC12C5A60S2 (успешно разобрался с MAX7219), я посмотрел его адрес в даташите, и сделал SPDAT equ (адрес регистра).
Единственное что - замороченные STC8 и STC15, там надо внимательно читать все, даже некоторые стандартные 8051 регистры там могут быть не на своем месте, а на выводах портов включены альтернативные функции по умолчанию.
Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 15:08:45
BOB51
Там простой буфер-регистр под временное хранение (inp_dat) и буфер для чтения (tmp_lvk) (у STC правда можно непосредственно с выводами сравнивать, но уж лучше таки прочитать значение).
При первом вызове в него (inp_dat) записывается нейтральное состояние, статус tmp_lvk безразличен - он все равно свеженькое значение получит.
Далее
читаем порт в tmp_lvk
сравниваем с inp_dat
по результату
или
inp_dat = tmp_lvk - это случай подтверждения предыдущих считанных данных
или в случае неравенства
mov inp_dat,tmp_lvk ; и после интервала повторяем заново
Только вот надо отслеживать комбинацию "все отпущены" как основу выхода по фальстарту или по завершении исполнения.
А это уже дополнительная обработка считанных из порта данных.
Можно дополнить еще одним регистром - счетчиком для стабилизации количества верно считанных и/или ошибочных комбинаций.
Тогда тайминги автоматом уходят - просто используется контроль в течении N циклов подтверждения совпадения (та же программная задержка).
Насчет *.inc - лучше таки нашкарябать...

Re: 8051. Прерывание на кнопке, жесть.
Добавлено: Чт янв 21, 2021 15:46:17
Zhuk72
Главное неудобство STC - документация, написанная через пень-колоду.
В этом плане МК с ядром 8051 от Силабс, конечно, вне конкуренции.