Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

8051. Прерывание на кнопке, жесть.

Ср янв 20, 2021 21:47:17

Что нибудь можно сделать, чтоб избавится от дребезга? Пытаюсь сбрасывать бит 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

В сети куча информации по борьбе с дребезгом. См, например, здесь: https://radioprog.ru/post/251

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:05:00

В сети куча информации по борьбе с дребезгом. См, например, здесь: https://radioprog.ru/post/251

Не спорю, но про то как это сделать в прерывании у 8051-го - чё-то небогато.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:31:30

Потому что никто так не делает. Разве что, из всяких слипов выходить.
К чему такая молниеносная реакция на нажатие кнопки ?

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:33:44

Вот мой старый проект часов на асме для С8051. Анти-дребезг реализован в соответствии с алгоритмом в листинге 1 на стр. 20 в приложенной PDF.
Clock.zip
(526.75 KiB) Скачиваний: 173

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:53:33

Потому что никто так не делает. Разве что, из всяких слипов выходить.
К чему такая молниеносная реакция на нажатие кнопки ?

молниеносная реакция мне не нужна. На самом деле пока не смог придумать как сделать кнопки на МК по-другому.
Хочется читать штук 8, сразу. Захожу в прерывание, читаю порт с кнопками, кладу в регистр, выхожу из прерывания (МК при этом снимается с IDLE), Прерывание по нажатию любой кнопки, через диодное лог. "ИЛИ" на вход инта. Вроде все классно.
Но пока решил попробовать с одной, и получается не очень.
Вложения
buttonz.png
(10.11 KiB) Скачиваний: 114

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 07:47:33

Сканировать по таймеру каждые 20-50мс не пробовал?

Так-то классика жанра, которую ТС не знает. Ха-ха... С IDLE можешь выходить по прерыванию таймера, что, обычно, позволяли все МК на ядре MCS-51, с которыми я когда-то работал. И не нужно ни каких "монтажных И". Для считывания 8 кнопок хватит 6 ног МК. Если ног не хватает, то добавляется сдвиговый регистр, который уменьшит число потребных ног до трёх.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 09:12:03

https://m.radiokot.ru/forum/viewtopic.php?f=61&t=79801

Там буквально на первых страницах описан принцип, Alex даже приводил пример на Си. По тому же принципу и действуйте на асме.

Для начала заведите таймер на 1 мс. На него и заведите все процессы: чтение кнопок, отображение информации, считайте датчики и пр.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 10:15:14

В схеме диоды нужно переставить в цепь R1,R3.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 10:37:00

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

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 12:52:53

Вот только как все это сделать, блин. Примеры на "С" (а других в общем, нет) мне непонятны, я его почти не знаю, в больших программах на асме тоже сложно разобраться.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:05:47

Вечерком чегось поднашкрябаю для примера...
Именно под вариант прерывания - но только для базовой классики (AT89C51 за основу).
Для STC там надо "привести в соответствие" - влазить в доки чуток влом.
:write:

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:20:09

Таймер с прерыванием в 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:
... для базовой классики (AT89C51 за основу)

STC11F04E, кстати, имеет совместимую с AT89C2051 цоколевку.
Отличаться может только вторым режимом таймера.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:47:17

Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...
Мне его готовить влом... имеется в наличии для STCшек только под stc15f204ea...
:(
Да так пока и лежит без дела (несмотря что есть подопытный МК).
:sleep:

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:49:48

Таймер с прерыванием в 1 мс настроить сможете?

Вспомнил, что в программе для прошивки встроены различные полезные утилиты для генерации готового кода, например, настройка таймера, а также множество демо-кодов (правда, описание на китайском, да еще и шрифт левый). Причем все это и на Си, и на асме. В даташите на семейство тоже хватает примеров использования.

Добавлено after 2 minutes 11 seconds:
Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...

В прошивальщике все это есть:
Спойлер
Код:
#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 практически не отличается.
Последний раз редактировалось Zhuk72 Чт янв 21, 2021 14:55:16, всего редактировалось 1 раз.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:54:35

Zhuk72 писал(а):Если keys не равен 0 проверяете его на равнство keys_old (предыдущее значение). Если не равны, то keys_old = keys и на выход.

меня вот тут ступор случилсся, чтоб сравнить с keys_old, его надо сначала где-то и как-то установить. А все проходы одинаковые, непонятно, где old, а где не old/

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:01:42

Изначально и старый и текущий - нулевые.
Если при считывании текущий не ноль, тогда только сравниваете со старым. Если не равны, то keys_old = keys и на выход.
В следующем проходе, если нажатие все-такие существуют, они будут равны, тогда и обрабатываете значение keys. При выходе опять обнуляете оба регистра (или нет, зависит от хотелок).
keys (если через инверсию читаете) может быть равен 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 или 0x80.
Ну это если одновременно 2 и более кнопок не нажмете.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:04:01

Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...

Я вообще не парюсь. Например, нужен регистр какого нет в классике, например, SPI в МК STC12C5A60S2 (успешно разобрался с MAX7219), я посмотрел его адрес в даташите, и сделал SPDAT equ (адрес регистра).
Единственное что - замороченные STC8 и STC15, там надо внимательно читать все, даже некоторые стандартные 8051 регистры там могут быть не на своем месте, а на выводах портов включены альтернативные функции по умолчанию.
Последний раз редактировалось Shuspano Чт янв 21, 2021 15:12:40, всего редактировалось 1 раз.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:08:45

Там простой буфер-регистр под временное хранение (inp_dat) и буфер для чтения (tmp_lvk) (у STC правда можно непосредственно с выводами сравнивать, но уж лучше таки прочитать значение).
При первом вызове в него (inp_dat) записывается нейтральное состояние, статус tmp_lvk безразличен - он все равно свеженькое значение получит.
Далее
читаем порт в tmp_lvk
сравниваем с inp_dat
по результату
или
inp_dat = tmp_lvk - это случай подтверждения предыдущих считанных данных
или в случае неравенства
mov inp_dat,tmp_lvk ; и после интервала повторяем заново
Только вот надо отслеживать комбинацию "все отпущены" как основу выхода по фальстарту или по завершении исполнения.
А это уже дополнительная обработка считанных из порта данных.
Можно дополнить еще одним регистром - счетчиком для стабилизации количества верно считанных и/или ошибочных комбинаций.
Тогда тайминги автоматом уходят - просто используется контроль в течении N циклов подтверждения совпадения (та же программная задержка).
:roll:

Насчет *.inc - лучше таки нашкарябать...
:roll:

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:46:17

Главное неудобство STC - документация, написанная через пень-колоду.
В этом плане МК с ядром 8051 от Силабс, конечно, вне конкуренции.
Ответить