Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: 4 нажатия - 4 действия. STM32F1. CMSIS.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
EpoLLIa
Здравствуйте. Помогите решить проблему, есть задание, по каждому нажатию кнопки выполнять разную комбинацию миганий светодиодами.
1 нажатие - горит первый светодиод
2 нажатие - гаснет первый, загорается второй
3 нажатие - горят оба
4 нажатие - гаснут оба

В голове вроде понимаю как, но реализовать не могу. В этом деле совсем новичок.
Вот что у меня получилось.
CODE
#include "stm32F10x.h"

uint8_t n=0;
uint8_t bc=0;
uint8_t bs=0;

void InitAll(void){

RCC ->APB2ENR |= RCC_APB2ENR_IOPCEN;
RCC ->APB2ENR |= RCC_APB2ENR_IOPAEN;

GPIOC ->CRH &= ~GPIO_CRH_MODE8;
GPIOC ->CRH |= GPIO_CRH_MODE8_1;
GPIOC ->CRH &= ~GPIO_CRH_CNF8;

GPIOC ->CRH &= ~GPIO_CRH_MODE9;
GPIOC ->CRH |= GPIO_CRH_MODE9_1;
GPIOC ->CRH &= ~GPIO_CRH_CNF9;

GPIOA ->CRL &= ~GPIO_CRL_CNF0;
GPIOA ->CRL |= GPIO_CRL_CNF0_0;
GPIOA ->CRL &= ~GPIO_CRL_MODE0;

return;
}
void sys(void) // Вроде от дребезга
{
if ((GPIOA->IDR&0x01)==1)
{
if (bc <5)
{
bc++;
}
else
{
bs=1;
}
}
else {
if (bc > 0)
{
bc--;
}
else
{
bs=0;
}
}
}

int main(void){
sys();
InitAll();
while(1)
{
if (bs==1)
{
n++;
}
switch (n) {
case 1:
GPIOC->BSRR = GPIO_BSRR_BR9;
GPIOC->BSRR = GPIO_BSRR_BS8;
break;
case 2:
GPIOC->BSRR = GPIO_BSRR_BR8;
GPIOC->BSRR = GPIO_BSRR_BS9;
break;
case 3:
GPIOC->BSRR = GPIO_BSRR_BS8;
GPIOC->BSRR = GPIO_BSRR_BS9;
break;
case 4:
GPIOC->BSRR = GPIO_BSRR_BR8;
GPIOC->BSRR = GPIO_BSRR_BR9;
break;
default:
n=0;
break;
}
}
}

Выручите пожалуйста.
Повторюсь, до этого ни разу не сталкивался с программированием, тем более с программированием микроконтроллеров, сильно не ругайте, лучше помогите. Заранее спасибо.
mcheb
Общий смысл такой -азбука Морзе. Выбираете конкректный временной интервал, короткое нажатие- 0 длинное - 1 (или наоборот) Если ничего не нажималось очень долго - это окончание нажатий и анализ 0 и 1.
EpoLLIa
Общий смысл я примерно понимаю. Реализовать не получается никак, один раз получилось, но уже не помню как там делал, но работало только раза с десятого, постоянно дребезг, никак не получается от него избавится.
KnightIgor
Цитата(EpoLLIa @ Apr 22 2015, 14:19) *
Здравствуйте. Помогите решить проблему, есть задание, по каждому нажатию кнопки выполнять разную комбинацию миганий светодиодами.
1 нажатие - горит первый светодиод
2 нажатие - гаснет первый, загорается второй
3 нажатие - горят оба
4 нажатие - гаснут оба

Имеется ввиду ПЕРВОЕ нажатие, потом последующее (ВТОРОЕ) нажатиЕ или ОДНОКРАТНОЕ нажатие, ДВУХКРАТНОЕ (тип-тип) нажатие, ТРОЙНОЕ и т.д.?
EpoLLIa
Цитата(KnightIgor @ Apr 23 2015, 00:35) *
Имеется ввиду ПЕРВОЕ нажатие, потом последующее (ВТОРОЕ) нажатиЕ или ОДНОКРАТНОЕ нажатие, ДВУХКРАТНОЕ (тип-тип) нажатие, ТРОЙНОЕ и т.д.?

Первое, последующее (второе), и т.д. С этой задачей я уже справился, всё работает. Теперь хочу мигание светодиода сделать через SysTick.
Obam
Цитата(EpoLLIa @ Apr 23 2015, 12:17) *
Первое, последующее (второе), и т.д. С этой задачей я уже справился, всё работает. Теперь хочу мигание светодиода сделать через SysTick.


Так расскажите сообществу как побороли дребезг
EpoLLIa
Цитата(Obam @ Apr 23 2015, 02:20) *
Так расскажите сообществу как побороли дребезг

Только вот, чтобы всё заработало как надо, методом тыка (т.к. не знаю особенностей case+swtich) сделал case 5, который точно повторяет case 4 (тут гаснут оба светодиода), и в default n приравниваю к нулю. Иначе если делать без case 5, после 4ого нажатия он почему-то гасил оба и тут же зажигал первый светодиод и так по кругу.
CODE

#include "stm32F10x.h"

uint8_t MAXCNT=50, n=0, cntr=0;
char pressed=0;

void delay (volatile uint32_t nCount){

for (; nCount !=0; nCount--);
}
void InitAll(void){

RCC ->APB2ENR |= RCC_APB2ENR_IOPCEN;
RCC ->APB2ENR |= RCC_APB2ENR_IOPAEN;

GPIOC ->CRH &= ~GPIO_CRH_MODE8;
GPIOC ->CRH |= GPIO_CRH_MODE8_1;
GPIOC ->CRH &= ~GPIO_CRH_CNF8;

GPIOC ->CRH &= ~GPIO_CRH_MODE9;
GPIOC ->CRH |= GPIO_CRH_MODE9_1;
GPIOC ->CRH &= ~GPIO_CRH_CNF9;

GPIOA ->CRL &= ~GPIO_CRL_CNF0;
GPIOA ->CRL |= GPIO_CRL_CNF0_0;
GPIOA ->CRL &= ~GPIO_CRL_MODE0;

return;

}

int main(void){
InitAll();
while(1) {
if((GPIOA->IDR&0x01)==0) { // Здесь от дребезга
pressed=0;
cntr=0;
}
else if(!pressed) {
cntr++;
if(cntr>MAXCNT)
{n++;

switch (n) {
case 1:
GPIOC->BSRR = GPIO_BSRR_BR9;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BS8;
break;
case 2:
GPIOC->BSRR = GPIO_BSRR_BR8;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BS9;
break;
case 3:
GPIOC->BSRR = GPIO_BSRR_BR9;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BS8;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BR8;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BS8;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BR8;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BS9;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BR9;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BS9;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BR9;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BS8;
GPIOC->BSRR = GPIO_BSRR_BS9;
break;
case 4:
GPIOC->BSRR = GPIO_BSRR_BR8;
GPIOC->BSRR = GPIO_BSRR_BR9;
break;
case 5:
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BR9;
delay(0xFFFFF);
GPIOC->BSRR = GPIO_BSRR_BR8;
break;
default:
n=0;
break;
}
}
}
}
}

toweroff
как-то так
Код
uint8_t n;
// подразумевается, что светодиоды соответствуют младшим разрядам n


n = 0;

while(1)
{
    set_LED(n & 0x03); // включаем светодиоды, значимые только последние 2 бита
    wait_key(); // ждем нажатия кномки, устранение дребезга там же
    n++;
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.