Ср апр 20, 2022 09:00:46
void read_button(void) {
static uint8_t count_read_button_ok=0;
count_read_button_ok++;
//---------- OK ----------
static char button, button_old=1;
button_old=button;
button=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
if (((button_old!=button)&&(button==0))) {
delay_ms(5);
button=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
if (((button_old!=button)&&(button==0))) {
delay_ms(5);
button=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
if (((button_old!=button)&&(button==0))) {
delay_ms(5);
button=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
if (((button_old!=button)&&(button==0))) {
delay_ms(5);
button=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
if (((button_old!=button)&&(button==0))) {
second_systick_ms=0;
button_second=0;
while (((GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13)==0)&&(button_second<2))); // зачем это???
if (button_second<2) {
button_ok_press(); // управляющая функция.
}
else {
RTC_Counter = RTC_GetCounter();
RTC_GetDateTime(RTC_Counter, &RTC_DateTime);
RTC_DateTime.RTC_Seconds=0;
RTC_SetCounter(RTC_GetRTC_Counter(&RTC_DateTime));
}
}
}
}
}
}
//PinB 13 - Ok, PinB 14 - Down, PinB 15 - Up
static void button_init(void){
GPIO_InitTypeDef button_ok =
{.GPIO_Pin = GPIO_Pin_13, .GPIO_Speed = GPIO_Speed_2MHz, .GPIO_Mode = GPIO_Mode_IPU};
GPIO_InitTypeDef button_down =
{.GPIO_Pin = GPIO_Pin_14, .GPIO_Speed = GPIO_Speed_2MHz, .GPIO_Mode = GPIO_Mode_IPU};
GPIO_InitTypeDef button_up =
{.GPIO_Pin = GPIO_Pin_15, .GPIO_Speed = GPIO_Speed_2MHz, .GPIO_Mode = GPIO_Mode_IPU};
GPIO_Init(GPIOB, &button_up);
GPIO_Init(GPIOB, &button_down);
GPIO_Init(GPIOB, &button_ok);
}
Ср апр 20, 2022 09:18:38
delay_ms(5);
Ср апр 20, 2022 09:23:35
delay_ms(5);
и написать по-человечески!
Ср апр 20, 2022 10:02:31
void ReadButtons(void)
{
static uint16_t old = (1 << BTN0_Pin) | (1 << BTN1_Pin) | (1 << BTN2_Pin);
uint16_t port = GPIOB->IDR; // однократное чтение порта
if((port & (1 << BTN0_Pin) == 0)
{ /* если состояние кнопки = нажата */
if((old & (1 << BTN0_Pin) != 0)
{ /* если предыдущ.сост.кнопки = не нажата*/
btn0_flag = 1; // выставить флаг события нажатой кнопки
old &= ~(1 << BTN0_Pin); // и обновить предыдущ.состояние кнопки
}
} else
{ /* если кнопка не нажата, то просто обновить предыдущ.сост.кноп. */
old |= 1 << BTN0_Pin;
}
/* повторить то же самое для BTN1 и BTN2 */
}
Типо антидребезг ?
Ср апр 20, 2022 11:21:48
Ср апр 20, 2022 11:56:34
Ср апр 20, 2022 12:10:36
Ср апр 20, 2022 14:20:17
Ср апр 20, 2022 19:53:20
Ср апр 20, 2022 21:05:03
void delay_ms(uint32_t ms)
{
volatile uint32_t nCount;
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq (&RCC_Clocks);
nCount=(RCC_Clocks.HCLK_Frequency/10000)*ms;
for (; nCount!=0; nCount--);
}
static void init_sys_counter(void) {
system_counter_init(1000);
counter = system_counter_ticks();
SysTick_Config(SystemCoreClock / 1000);
}
volatile uint16_t button_delay;
volatile uint8_t flag = 0;
void SysTick_Handler(void) {
button_delay ++;
if (button_delay >=20) {
button_delay=0;
flag = 1;
}
}
volatile uint16_t button_delay;
void SysTick_Handler(void) {
button_delay ++;
if (button_delay >=20) {
ReadButtons(void);
button_delay=0;
}
}
void ReadButtons(void)
{
static uint16_t old = (1 << BTN0_Pin) | (1 << BTN1_Pin) | (1 << BTN2_Pin);
uint16_t port = GPIOB->IDR; // однократное чтение порта
if((port & (1 << BTN0_Pin) == 0)
{ /* если состояние кнопки = нажата */
if((old & (1 << BTN0_Pin) != 0)
{ /* если предыдущ.сост.кнопки = не нажата*/
btn0_flag = 1; // выставить флаг события нажатой кнопки
old &= ~(1 << BTN0_Pin); // и обновить предыдущ.состояние кнопки
}
} else
{ /* если кнопка не нажата, то просто обновить предыдущ.сост.кноп. */
old |= 1 << BTN0_Pin;
}
/* повторить то же самое для BTN1 и BTN2 */
}
Ср апр 20, 2022 22:13:44
Чт апр 21, 2022 05:51:52
typedef struct{
uint32_t delay; ///< Интервал счета (в тиках)
uint32_t cnt; ///< Счетная переменная
uint8_t mode: 1; ///< Режим однократный/циклический
uint8_t run: 1; ///< Бит работы таймера
uint8_t flag: 1; ///< Флаг истечения интервала
}utim_t;
#define MAX_UTIMERS 5 ///< Максимальное число софтовых таймеров
volatile utim_t utimer[MAX_UTIMERS];
/** ----------
* \brief Счет таймеров.
* \details Функция может вызываться из прерывания аппаратного таймера.
* Производит декременты счетных переменных и выставляет флаги
* окончания счета.
*/
void UserTimer_Count(void)
{
for(volatile uint8_t n = 0; n < MAX_UTIMERS; n++)
{
if(utimer[n].run)
{
if(utimer[n].cnt) utimer[n].cnt--;
else
{
utimer[n].flag = 1;
if(utimer[n].mode == UTIMER_CIRCMODE) utimer[n].cnt = utimer[n].delay;
else utimer[n].run = 0;
}
}
}
}
/** ----------
* \brief Запуск таймера.
* \details Задание значений, запуск
* @param timer номер таймера
* @param delay интервал счета в тиках
* @param mode режим (однократный/циклический)
*/
void UserTimer_Start(uint8_t timer, uint32_t delay, uint8_t mode)
{
utimer[timer].cnt = delay - 1;
utimer[timer].delay = delay - 1;
utimer[timer].mode = mode;
utimer[timer].run = 1;
}
/** ----------
* \brief Остановка таймера без сброса счетной переменной.
* @param timer номер таймера
*/
void UserTimer_Stop(uint8_t timer)
{
utimer[timer].run = 0;
}
/** ----------
* \brief Проверка истечения времени таймера.
* \param timer - номер таймера
* \return Да/Нет
*/
uint8_t UserTimer_Check(uint8_t timer)
{
if(utimer[timer].flag)
{
utimer[timer].flag = 0;
return 1;
}else
return 0;
}/
/**----------
* \brief Блокирующая задержка.
* \details Функция блокирующей задержки на заданный интервал времени
* в тиках.
* \param delay - начальное значение счета
*/
void BlockedDelay(volatile uint32_t delay)
{
bltimer_cnt = delay;
while(bltimer_cnt) { }
}
/** ----------
* \brief Счет блокирующей задержки.
* \details Функция может вызываться из прерывания аппаратного таймера
* Производит декременты счетной переменной.
*/
void BlockedDelay_Count(void)
{
if(bltimer_cnt) bltimer_cnt--;
}
Чт апр 21, 2022 08:23:53
volatile uint16_t button_delay;
volatile uint8_t flag = 0;
void SysTick_Handler(void) {
button_delay ++;
if (button_delay >=20) {
button_delay=0;
flag = 1;
}
}
volatile bool flag = false;
void SysTick_Handler(void)
{
static uint32_t button_delay=0;
if (++button_delay >=20)
{
button_delay=0;
flag = true;
}
}
Чт апр 21, 2022 10:21:21
void timer_init() {
/*---------- TIM4------------------*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
/* По умолчанию частота шины 24 МГц при использовании кварца 8 МГц */
TIM4->PSC = 24000 - 1; /* Настройка делителя на 1000 "тиков" в секунду */
TIM4->ARR = 20; /* Отработка прерывания раз в 20мс */
TIM4->DIER |= TIM_DIER_UIE; /* Разрешения прерывание от таймера */
TIM4->CR1 |= TIM_CR1_CEN; /* Запуск таймера */
NVIC_EnableIRQ(TIM4_IRQn); /* Разрешение TIM4_IRQn прерывания */
}
void TIM4_IRQHandler(){
ReadButtons();
}
__enable_irq();
NVIC_SetPriorityGrouping(0x3);
Чт апр 21, 2022 10:39:05
Чт апр 21, 2022 10:59:26
Чт апр 21, 2022 11:05:08
Чт апр 21, 2022 12:01:15
то почему бы и нет?
Таймеров TIMx может быть с избытком
систик может использоваться для других задач и считать более быстро
прежде чем сесть за кодописательство, продумывают стратегию, распределяют ресурсы
Чт апр 21, 2022 13:10:33
А смысл,
Чт апр 21, 2022 15:00:28
При задержке между нажатием кнопки и получением отклика более 50-70 мс получается эффект тормознутости.