Программирование устройства. Реализация кода

Электроника

Хотите расширить функциональность получившихся смарт-часов? Тогда добавим дополнительные события и составим несколько новых методов
Глоссарий
Для успешного освоения материала рекомендуем вам изучить следующие понятия:
Таймер
в информатике — средство обеспечения задержек и измерения времени средствами компьютера. Существуют два вида таймеров:
  • аппаратные таймеры функционируют независимо от центрального процессора и в момент срабатывания генерируют прерывание
  • программные таймеры реализуются за счет выполнения в цикле заданного количества одинаковых «пустых» операций. При фиксированной частоте работы процессора это позволяет точно определять прошедшее время
Прерывание
сигнал от программного или аппаратного обеспечения, сообщающий процессору о наступлении какого-либо события, требующего немедленного внимания
Видеолекция
Конспект
Как расширить функциональность смарт-часов? Давайте добавим дополнительные события и составим новые методы

Этапы
  1. Добавление событий с будильником
  2. Добавление счетчика неактивности пользователя
  3. Просыпание и засыпание устройства
  4. Заполнение методов действия
Работа на компьютере
1. Открываем проект смарт-часов

2. Находим метод прерывания таймера (т.к. наши события будут формироваться в таймере)
Важно
Наш таймер вызывается с частотой 1 кГц
3. Добавляем метод отрисовки картинки на циферблате и событие для засыпания всей системы
if(htim->Instance == TIM1)
	{//прерывание из таймера TIM1 - настроен на обновление раз в 1 мс


		if(periodupdate!=0)
			periodupdate--;
		else
		{
			periodupdate=UPDATE_DRAW_PERIOD_TIM1;
			to_redraw=1;
		}


		//timeout sleep
		if(count_tim1_timeout_sleep!=0)
			count_tim1_timeout_sleep--;
		else
		{
			count_tim1_timeout_sleep=TIMEOUT_SLEEP_TIM1;
			signal_timeout_sleep=1;
		}
4. Добавляем событие счета сенсора положения
update imu
		if(count_tim1_update_imu!=0)
			count_tim1_update_imu--;
		else
		{
			count_tim1_update_imu=UPDATE_IMU_TIM1;
			to_update_imu=1;
		}
5. Организуем работу с кнопкой
btn_bounce_tim1--;
		if(btn_bounce_tim1==0)
		{//update 100 ms

			//keys

			if(HAL_GPIO_ReadPin(BUTENC_GPIO_Port,BUTENC_Pin)==GPIO_PIN_RESET)
				state_btn=0;
			else
				state_btn=1;


			if(state_btn_old==0 && state_btn==1)
				{
					btn_try_poll=1;
					count_tim1_timeout_sleep=TIMEOUT_SLEEP_TIM1;
				}

			if(state_btn_old==1 && state_btn==0)
				{
					btn_try_push=1;
					count_tim1_timeout_sleep=TIMEOUT_SLEEP_TIM1;
				}

			state_btn_old=state_btn;
6. Работаем с энкодером
//encoder roller
			int32_t lev_enc = 0;
			state_enc = HAL_LPTIM_ReadCounter(&hlptim1);
			if(state_enc > state_enc_old + lev_enc)
			{
				enc_try_inc=1;
				count_tim1_timeout_sleep=TIMEOUT_SLEEP_TIM1;
			}

			if(state_enc < state_enc_old - lev_enc)
			{
				enc_try_dec=1;
				count_tim1_timeout_sleep=TIMEOUT_SLEEP_TIM1;
			}

			state_enc_old = state_enc;

			btn_bounce_tim1=BTN_BOUNCE_PERIOD_TIM1;
		}
Условия для будильника
Если будильник включен (по умолчанию это всегда так), то мы сравниваем текущее время и установленное (заданное с помощью энкодера):
  • если время совпадает, то вызывается событие сигнала
  • по окончании работы сигнала будет возникать событие остановки
Заполнение методов
1. Переходим в функцию main

2. Настраиваем циферблат аналоговых часов
void draw_analog_watch(enum STATE state, enum STATE state_old)
{

	if(state != state_old)
	{
		to_redraw =1;
	}
	if(to_redraw!=1)
		return;

	to_redraw=0;
	ssd1331_clear_screen(BLACK);

	draw_watch(state, state_old);

    SSD1331_UpdateScreen();//обновление экрана из внутреннего буфера

}
Важно
Важно вызывать событие только если произошел переход из другого состояния. Если состояние перешло само в себя, то перерисовку вызывать не нужно, иначе эти действия загрузят микроконтроллер
3. Для отрисовки вызываем методы из библиотеки (линия, окружность и т. д.)

4. Устанавливаем время на часах по аналогичному шаблону
void draw_settime_hours(enum STATE state, enum STATE state_old)
{
	if(state != state_old)
	{
			to_redraw =1;
	}

	if(to_redraw!=1)
		return;

	to_redraw=0;

	ssd1331_clear_screen(BLACK);
	ssd1331_display_string(0, 0, (uint8_t *)"Set Time", FONT_1206, PINK);

	if(field==1)
	{
		ssd1331_draw_3216char(8,16, (current_time.hours/10)+0x30, WHITE);
		ssd1331_draw_3216char(24,16, (current_time.hours%10)+0x30, WHITE);
	}
Важно
Разделитель (точки на часах) отображается функцией ssd1331_draw_3216char (40,16,":", RED)
5. Настраиваем дополнительный циферблат, который отображает информацию по системе или по сенсорам положения
6. Отдельно выделяем метод для отрисовки будильника. От отрисовки обычных часов он отличается вызовом сигнала и изображения при срабатывании будильника
7. Настраиваем режим пониженного потребления — to_sleep отключает все интерфейсы

8. Отдельно выделяем методы, которые обеспечивают изменение состояний при установке времени, но со значком inc и dec (т. е. изменение на 1). Эти методы настраиваются отдельно, так как вызывают перерисовку значения всего экрана часов, если время попадает в допустимый интервал
Завершение проекта и тестирование
1. Компилируем и прошиваем

2. После прошивки наше устройство может работать автономно на аккумуляторе

3. Возврат в активный режим происходит нажатием энкодера
4. Нажатием энкодера устанавливаем время. Изменение цифр происходит по вращению энкодера

5. Нажатием повторно мы переходим в настройку будильника. Будильник срабатывает сигналом и светом и действует минуту

6. На экране оповещения отображаются зарядка, значение гироскопа и т. д.
Мы рассмотрели функциональное программирование часов и получили полностью рабочее устройство. Перейдем к заданиям.
Интерактивное задание
Тест
Для закрепления полученных знаний пройдите тест
Стартуем!
Где формируются события?
Дальше
Проверить
Узнать результат
Когда вызывается событие перерисовки циферблата
Дальше
Проверить
Узнать результат
Как происходит отрисовка?
Дальше
Проверить
Узнать результат
Выберите верную функцию для установки разделителя времени
Дальше
Проверить
Узнать результат
К сожалению, вы ответили неправильно
Прочитайте лекцию и посмотрите видео еще раз
Пройти еще раз
Неплохо!
Но можно лучше. Прочитайте лекцию и посмотрите видео еще раз
Пройти еще раз
Отлично!
Вы отлично справились. Теперь можете ознакомиться с другими компетенциями
Пройти еще раз