HHIMERA писал(а):Юзать прерывания - моветон.
Т.е. лучше заводить таймер и опрашивать через определенный период, тем самым и дребезг устранить и в главном цикле не тормозить ?
HHIMERA писал(а):Юзать прерывания - моветон.
menzoda писал(а):Нет уж, я всегда буду настаивать на аппаратном антидребезге и только на нем.
menzoda писал(а):Если нужно - повешу на внешнее прерывание, если нужно - просто на ножку, если нужно - буду читать через сдвиговый регистр по SPI, но во всех случаях антидребезг буду использовать аппаратный.
Foks писал(а):Про "дорого" зависит от объемов. Если вы инженер компании, которая производит модули миллионными партиями, то экономическая часть вопроса будет стоять у вас по сути на первом месте. Если же нет - что же, можно и добавить пару элементов, но будет ли от них реальная польза?
Вообще, соглашусь, что решение может зависеть от конкретных условий. Не стоит ограничивать себя ни аппаратным, ни программным способом, лучше держать в голове все возможные способы, и выбирать оптимальный для каждой задачи.
amv2000 писал(а):HHIMERA писал(а):Юзать прерывания - моветон.
Т.е. лучше заводить таймер и опрашивать через определенный период, тем самым и дребезг устранить и в главном цикле не тормозить ?
HHIMERA писал(а):[Не только дребезг...
amv2000 писал(а):...кнопка опрашивается 100 раз в секунду...организовать по таймеру.
Однозначно!kolobok0 писал(а):собственно можно по разному мутить.
Ну вот. Так сразу. Только два? Почему?Тут два способа - прерывание либо опрос. опрос проезжаем - это понятно. остаётся прерывание. собственно если мы отжимаемся и время прошло мало - то его в пень. если много - то флаг нажатия.
ut1wpr писал(а):Если кому-то будет интересно - спрашивайте. Тратить время "в воздух" нет желания.
Код: Выделить всё
void SysTick_Handler()
{
static unsigned button_cnt = 0;
if (GPIOA->IDR & 1) {
if (++button == некая_константа) Action();
} else button_cnt = 0;
}Код: Выделить всё
static uint16_t KeyAcc = 0; /* Key Accumulator */
static uint16_t Key = 0; /* Key State */
/*
* Read Key
*/
void ReadKey() {
KeyAcc = KeyAcc << 1;
KeyAcc |= !(KEYPORT & KEYPIN);
if(KeyAcc == 0xFFFF) Key = 1;
if(KeyAcc == 0) Key = 0;
}
Функция ReadKey() вызывается либо из главного цикла программы, либо по прерыванию таймера.
В главном цикле обрабатывается переменная Key.
if(Key) /* кнопка нажата */
{
}Практически то, что я применяю.amv2000 писал(а):Да ладно Вам, очень даже интересно. Я перекопал интернет и везде только разговоры на эту тему или примеры с применением библиотеки SPL, а она хоть и говорят для удобного восприятия у меня в голове вызывает только кашу. Впрочем про таймер SysTick читал именно с применение SPL, так же попадалось очень похожее на пример выше, где учитывается время нажатия. Только здесь я думаю опечатка надо if (++button_cnt == некая_константа) Action();, тогда условие выполняется если нажата кнопка, запускаем счет и ждем когда значение будет равно константе. Если равно выполняем какое то действие, если нет обнуляем счетчик. Надеюсь правильно понимаю код, тем более он простКод: Выделить всё
void SysTick_Handler()
{
static unsigned button_cnt = 0;
if (GPIOA->IDR & 1) {
if (++button == некая_константа) Action();
} else button_cnt = 0;
}
Код: Выделить всё
volatile int button_cnt_1, button_cnt_2;
void AnyTimer_Handler( void){
if( GPIOA->IDR and 0x01 ) button_cnt_1 = 0x00; else if( button_cnt_1 < TRESHOLD ) button_cnt_1++;
if( GPIOA->IDR and 0x02 ) button_cnt_2 = 0x00; else if( button_cnt_2 < TRESHOLD ) button_cnt_2++;
return;Код: Выделить всё
int GetPressedButton( void ){
if( button_cnt_1 == TRESHOLD ) button_cnt_1 = TRESHOLD+1; else return 1;
if( button_cnt_2 == TRESHOLD ) button_cnt_2 = TRESHOLD+1; else return 2;
// ... по количеству кнопок
return ( 0 );
}ut1wpr писал(а):Практически то, что я применяю.
Код: Выделить всё
*((uint32_t *)(0x08080000)) = 0xFEDCBA; Код: Выделить всё
uint32_t * pMyVal = (uint32_t *)0x08080000;
*pMyVal = 0xABCDEF; Читать можно свободно. А вот с записью не получится. Области EEPROM и FLASH имеют защиту. При обращении к памяти в этой области ее необходимо предварительно снять. Учитывая это, механизм программной инициализации не может быть выражен путем VAR = VALUE. Запись во флеш и еепром имеет механизм, отличный от ОЗУ. Причем далеко не все STM32 имеют этот самый eeprom.ibiza11 писал(а):Satyr, добрый день!
Вы уважаемый мной кот, ни в коем разе не хочу Вас обидеть.
Но мне кажется в данном случае Вы заблуждаетесь. в STM32L EEPROM отображается в общее адресное пространство на адреса начиная с 0x08080000.
Следовательно переменную можно разместить там явно, указав ее адрес. Или неявно, используя указатель, записать просто в ячейку.
И то и другое делается без всяких функций, таких как например в AVR.илиКод: Выделить всё
*((uint32_t *)(0x08080000)) = 0xFEDCBA;Код: Выделить всё
uint32_t * pMyVal = (uint32_t *)0x08080000;
*pMyVal = 0xABCDEF;