Перейти к содержанию

Инициализация структуры кнопки в STM32 - C (СИ)


Nicollo

Рекомендуемые сообщения

Добрый день.

Пишу программу под STM32f103, в девайсе есть 2 кнопки, подключены напрямую к ваходам GPIOA (0 и 1);

Хочу сделать по красоте, написал структуру для кнопок: 

typedef struct {
	GPIO_TypeDef* GPIOx;
	uint16_t GPIO_Pin;
	uint8_t isPressed;
	uint8_t ttl;
} Button;

И глобальную структуру:

typedef struct {
	...
	Button* ModeButton; // mode button status
	...
} GlobalRegister;

GlobalRegister Register;

Пример инициализации 1 кнопки:

void main() {
	...
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    Button ModeButton;
    ModeButton.GPIOx = GPIOA;
    ModeButton.GPIO_Pin = GPIO_Pin_0;
    ModeButton.ttl = 0x00;
    ModeButton.isPressed = RESET;

    Register.ModeButton = &ModeButton;
	...
}

После, в обработчике прерываний по таймеру, я пытаюсь проверить нажатие кнопки:

void BUTTON_Check(Button *Button){ ... }


void SysTick_Handler(void){
	BUTTON_Check(Register.ModeButton);
	....
}

Но указатель уже битый, не могу получить объект кнопки.

Изменено пользователем Nicollo
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Извращяюсь - делаю защиту от антидребезга, для каждой кнопки:

т.е. после того как обнаружилось нажатие выжидаю некоторое время и если после него кнопка осталась нажатой - засчитываю нажатие.

#define BUTTON_DELAY 0x0F

void BUTTON_Check(Button *Button) {
	/**
	 * Check if button is pressed
	 */
	if ((Button->GPIOx->IDR & Button->GPIO_Pin) == (uint32_t) Bit_RESET && Button->ttl == 0x00) {
		Button->ttl ++;

		return;
	}

	/**
	 * Wait for a while to skip button rattling
	 */
	if (Button->ttl > 0x00 && Button->ttl < BUTTON_DELAY) {
		Button->ttl ++;

		return ;
	}

	if (Button->ttl == BUTTON_DELAY) {
		if ((Button->GPIOx->IDR & Button->GPIO_Pin) == (uint32_t) Bit_RESET) {
			Button->ttl ++;
		} else {
			Button->ttl = 0x00;
		}

		return ;
	}
	if ((Button->GPIOx->IDR & Button->GPIO_Pin) == (uint32_t) Bit_SET && Button->ttl == (BUTTON_DELAY + 1)) {
		Button->isPressed = SET;

		return ;
	}
}
Ссылка на комментарий
Поделиться на другие сайты

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Опрашивать кнопки в таймере с интервалом 100мс, либо в таймере крутить счетчик и опрашивать в главном цикле, либо сделать функцию delay на SysTick и опять же опрашивать в главном цикле. Никакие структуры там даром не нужны. 

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Добрый день, а еще хотел спросить, есть ли в STM32F103  защита от дребезга энкодера?

Использую входы 3го таймера

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    //Channels TIM3_CH1, TIM3_CH2 as pull up inputs
    GPIO_InitTypeDef GPIO_InitDef;
    GPIO_InitDef.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitDef.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitDef.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOA, &GPIO_InitDef);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    /* TIM3 tunning*/
    TIM_TimeBaseInitTypeDef TIMER_InitStructure;
    TIM_TimeBaseStructInit(&TIMER_InitStructure);
    // set TIM_Period - encoder rotate count reset
    TIMER_InitStructure.TIM_Period = 4;
    // backward and forward count
    TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up | TIM_CounterMode_Down;
    TIM_TimeBaseInit(TIM3, &TIMER_InitStructure);

    /* Tuning Encoder Interface */
    TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM3, ENABLE);

    NVIC_EnableIRQ(TIM3_IRQn);

Направление определяю вот так:

(TIM3->CR1 & TIM_CR1_DIR ? -1 : 1)

Иногда детектится противоположное направление.

Можно ли как-то это решить программно? Или вешать RC фильтр?

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...
On 5/29/2017 at 5:13 PM, Nicollo said:

Button ModeButton;

Register.ModeButton = &ModeButton;

Вы делаете объект (экземпляр) структуры в функцию main, т.е. в стэк-е, а после адрес этой структуры присваиваете глобальному указателю. После выхода из функции (или переключение контекста, если у вас ОСРВ = переключение стэка) этот объект стирается, и у вас в глобальной структуре (Register) висячий указатель.

Если хотите исправить это, либо сделайте в структуре Register не указатель "Button* ModeButton;", а структуру "Button ModeButton;", и инициализацию делайте как "Register.ModeButton.GPIOx = GPIOA;" ...
Второй вариант это оставить ModeButton как указатель, а в функции инициализации выделить Button через malloc/calloc/.. присвоить все необходимые поля этому указателю, а его адрес записать в структуру Register.ModeButton (и по окончанию работы с этим полем освободить память).

Для примера:

void init_buttons(void)
{
	Button *ModeButton = malloc(sizeof(Button));
	ModeButton->GPIOx = GPIOA;
	ModeButton->GPIO_Pin = GPIO_Pin_0;
	ModeButton->ttl = 0x00;
	ModeButton->isPressed = RESET;
	...
	Register->ModeButton = ModeButton;
}

void deinit_buttons(void)
{
	free(Register->ModeButton);
}

 

Ссылка на комментарий
Поделиться на другие сайты

единственное но, юзать динамику во встройке очень затратно по ресурсам

да и нужно ли вообще, если количество источников и исполнителей всегда заранее известно?

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Ссылка на комментарий
Поделиться на другие сайты

Не понятен вообще смысл использования таких структур. Особенно, если учесть то, что большая часть настройки производится один раз при старте МК...

Ссылка на комментарий
Поделиться на другие сайты

ну я о том же. Эмбедед системы практически всегда имеют однозначную и известную конфигурацию

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Ссылка на комментарий
Поделиться на другие сайты

Бывают случаю когда на одном и том-же железе могут быть две и более софтовых конфигураций (для примера по настройкам из еепром-а).
Для примера: у вас есть 2 порта (UART, или SPI, или ...), и 3 возможных датчика которые могут подключатся к этим портам, и для каждого варианта подключения у вас будет разная конфигурация (скажем для настройки под заказчик).

Но соглашусь с вами, что в контроллерах редко используют динамически выделенную память, так как ее в любой момент может не хватить а это может привести к непредсказуемым последствиям.

Ссылка на комментарий
Поделиться на другие сайты

Только что, gindul сказал:

Для примера: у вас есть 2 порта (UART, или SPI, или ...), и 3 возможных датчика которые могут подключатся к этим портам, и для каждого варианта подключения у вас будет разная конфигурация (скажем для настройки под заказчик).

Можно заюзать дефайны и не париться. В том же UART вряд ли понадобится изменить что-то кроме скорости, а это всего один регистр.

Ссылка на комментарий
Поделиться на другие сайты

при возможности выбора, я бы использовал любой доступный способ программирования конфигурации периферии, но динамику в последнюю очередь

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Ссылка на комментарий
Поделиться на другие сайты

21 hours ago, BARS_ said:

Можно заюзать дефайны и не париться.

Вы предлагаете разные прошивки для разных целей. А я говорю об одной прошивке на все устройства, но настраивать вид устройства при установке у заказчика. Установку устройства проводят не программисты, а прошивку не роздают направо и налево :)
В динамической выделении памяти нет ничего плохого, но я соглашусь с тем что это надо использовать ее в последнюю очередь.

Иногда проделывают и такое: выделяют большой статический масив, и по мере необходимости используют из него куски как динамическую память. Это позволяет узнать во время компиляции сколько память у тебя есть свободной, а работать как с динамической :)

Ссылка на комментарий
Поделиться на другие сайты

я для кнопок и медленной фигни делаю так: беру uint8_t где старшие 4 бита это номер порта, ладшие - номер пина, и не надо тратить память на всякие структуры, при этом динамически можно переприсваивать их, в отличии от дефайнов полезно для применения в классах, С++ намного лучше обычного С как по мне (без динамики конечно и прочих радостей).  

Ссылка на комментарий
Поделиться на другие сайты

Так а в чем проблема тоже самое сделать для дефайнов? Что либо поменять занимает несколько секунд. Один фиг надо лезть и менять настройку портов, хоть так, хоть эдак.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • @Romanchek82 в данной ситуации скорее "подложена под ножку стола у дядюшки Ляо")
    • КИТ на Озоне, 2 канала за 500р. РФ. Я сам с конструктора начинал, там и опыт паять получите.  не надо с платы, схемы начинать, блок питания сначала соберёте, КИТ распаяйте, в корпус всё оформите. Одно до ума изделие доведите. Там и поймёте, куда дальше двигаться. А по схеме, ЕЩЁ раз, они есть на любое ОУ в даташит. По "ушникам", пятиножки в бОльшем случае - достаточно (по ссылке) прежде, чем Сухову, Нечаеву,.. в ж. "Радио" писать, готовился, после школы в библиотеку, вечерами за паяльник... пока обратная связь приходила (письма), уже многое исправил, да, не методом тыка, а через понимание физических процессов.  Быстро это только ЕГЭ, описательный, творческий процесс отсутвует (мозгами шевелить, статьи анализировать, углубляться и видеть перспективу).  Паять совет не нужен, ручками, ручками, готовый кит и в корпус.
    • Привет!  Мне не известно, есть ли другие варианты формата прошивки. Почитайте ветку , может кто то и выкладывал.
    • Совершенно точно. И об этом и сам разработчик (ца) подтвердила о силовой плате. Вот файл pdf от разработчика похоже, где то попалось... Сопротивление , импеданс входа операционника надо учитывать как то. По взодам стоят резисторы по 20к (делители), как то многовато для ОУ на биполярниках. В буржуйских схемах и в даташитах начиная с легендарного ОУ 741 стоят не более 10к по входу, пробовал вместо 20к ставить 10к, но это отдельная тема.... И при правильном проектировании замена ОУ на аналогичный не должно влиять на параметры (настройки) схемы. В наем случаее решил заменить ОУ LM324 (бытовку) на LM224 (промышленную) ... Поставил панельку и при смене разных партий 224 и 124 (милитари) настройка тока уходила в ощутимо по индикатору. Ставил LM-ки от томсон и семикондуктор. Семикондуктор резко уходили насторойки, а томсон более близко к заводской настойке. С завода стояла 324 от томсон. Как и что не буду расписывать по этим двум фирмам. Подобрал балее , менее приемлимые 2 корпуса 224, один из частотника, второй из автомобильного реле. Крутить подстроечники на силовой плате не стал особо, т.к. это сложный случай и методики настойки нет и методом тыка не было времени и желания упражнятся. хотя с завода настройка не радует и желательно откорректировать.... термистор поставил  MF52 на 100к и прилепил на термопасту к радиатору VD1. Его тоже заменил на 60А - 100В и падению напряджния по мультиметру в 2 раза меньше, чем заводской. Индуктивность L2 проводом 1,9 мм 19 витков, замер показал 41,5 мкГн (пинцет Smart Tweezers Канада) заменена на на такое же салатовое кольцо (есть в загажнике) намотанно линцедратом 43х0,22 мм. Поместились все 19 витков как задская намотка один в один. Нагрузочный резистор R68 390 Ом заменил на 4 запаралеленных 1,2к 1 Вт. Конденсатор С20 1000х25 заменил на твёрдотельный 1000х50 и вынес от радиаторов. С9 и С10 заменил на твёрдотельные 47х50.  С5 заменил на два в параллель 150х450 и зашунтировал плёночной ёмкостью 2,5х630, чтобы облегчить жизнь электролитам....Поставил синфазный Др на синем колечке по 20 витков МГТФ 0,2 , индуктивность 5 мГн. Добавил варистор 20Т471 (470 В). Добавил сетевой выключательи дополнительную колодку с предохранителем 5А, штатный заменил на твёрдотельный 3,15А. Нагружал на 20А при 12 В - в течении часа всё работает, чуть тёплый воздух из  корпуса. ничего не кипятится не греется критично. ЗУ Вымпел-30.pdf Для справки, вроде как от разработчика(цы), утащено - Вымпел 30 ....
    • 01 — копия.lay6 amp_tda7377.pdf Назовём это "тестовый вариант по турецким мотивам". По идее должно норм ? 1к1 всё равно только рейсфедером нарисуешь.  Решено взять оттуда только УМ, фильтр wm019, питание внешний трансформатор. 
    • Новички собирают схемы из батарейки и лампочки! А не предусилители..
×
×
  • Создать...