Программирование устройства. Реализация кода
Электроника
“
Хотите расширить функциональность получившихся смарт-часов? Тогда добавим дополнительные события и составим несколько новых методов
Глоссарий
Для успешного освоения материала рекомендуем вам изучить следующие понятия:
Таймер
в информатике — средство обеспечения задержек и измерения времени средствами компьютера. Существуют два вида таймеров:
- аппаратные таймеры функционируют независимо от центрального процессора и в момент срабатывания генерируют прерывание
- программные таймеры реализуются за счет выполнения в цикле заданного количества одинаковых «пустых» операций. При фиксированной частоте работы процессора это позволяет точно определять прошедшее время
Прерывание
сигнал от программного или аппаратного обеспечения, сообщающий процессору о наступлении какого-либо события, требующего немедленного внимания
Видеолекция
Конспект
Как расширить функциональность смарт-часов? Давайте добавим дополнительные события и составим новые методы
Этапы
- Добавление событий с будильником
- Добавление счетчика неактивности пользователя
- Просыпание и засыпание устройства
- Заполнение методов действия
Работа на компьютере
1. Открываем проект смарт-часов
2. Находим метод прерывания таймера (т.к. наши события будут формироваться в таймере)
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. Настраиваем циферблат аналоговых часов
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. Устанавливаем время на часах по аналогичному шаблону
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). Эти методы настраиваются отдельно, так как вызывают перерисовку значения всего экрана часов, если время попадает в допустимый интервал
8. Отдельно выделяем методы, которые обеспечивают изменение состояний при установке времени, но со значком inc и dec (т. е. изменение на 1). Эти методы настраиваются отдельно, так как вызывают перерисовку значения всего экрана часов, если время попадает в допустимый интервал
Завершение проекта и тестирование
1. Компилируем и прошиваем
2. После прошивки наше устройство может работать автономно на аккумуляторе
3. Возврат в активный режим происходит нажатием энкодера
2. После прошивки наше устройство может работать автономно на аккумуляторе
3. Возврат в активный режим происходит нажатием энкодера
4. Нажатием энкодера устанавливаем время. Изменение цифр происходит по вращению энкодера
5. Нажатием повторно мы переходим в настройку будильника. Будильник срабатывает сигналом и светом и действует минуту
6. На экране оповещения отображаются зарядка, значение гироскопа и т. д.
5. Нажатием повторно мы переходим в настройку будильника. Будильник срабатывает сигналом и светом и действует минуту
6. На экране оповещения отображаются зарядка, значение гироскопа и т. д.
“
Мы рассмотрели функциональное программирование часов и получили полностью рабочее устройство. Перейдем к заданиям.
Интерактивное задание
Тест
Для закрепления полученных знаний пройдите тест
Стартуем! |
Где формируются события?
Дальше |
Проверить |
Узнать результат |
Когда вызывается событие перерисовки циферблата
Дальше |
Проверить |
Узнать результат |
Как происходит отрисовка?
Дальше |
Проверить |
Узнать результат |
Выберите верную функцию для установки разделителя времени
Дальше |
Проверить |
Узнать результат |
К сожалению, вы ответили неправильно
Прочитайте лекцию и посмотрите видео еще раз
Пройти еще раз |
Неплохо!
Но можно лучше. Прочитайте лекцию и посмотрите видео еще раз
Пройти еще раз |
Отлично!
Вы отлично справились. Теперь можете ознакомиться с другими компетенциями
Пройти еще раз |