Created
November 11, 2018 15:45
-
-
Save XanderEVG/bc1cfcbb97258c68d6af6fe3c78ad9f5 to your computer and use it in GitHub Desktop.
DIHALT_RTOS_EXAMPLE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================================ | |
// Прерывания | |
//============================================================================ | |
ISR(RTOS_TIMER_ISR) | |
{ | |
TimerService(); //Магия таймерной службы | |
} | |
//Прерывание опроса кнопки | |
ISR (PCINT2_vect) | |
{ | |
byte buttonState = HARD_BTN_PORT & 1<<HARD_BTN_PIN; | |
if(!buttonState) | |
{ | |
if(_btn_state==BTN_NO_PRESS) | |
{ | |
_btn_state=BTN_PRESS; | |
SetTask(Btn_pressed); | |
// Дребезг контактов не влияет, | |
// т к SetTask не добавляет задачу, | |
// если она уже в очереди. | |
// Но можно взводить запрет прервывания на этот пин, а | |
// в Btn_pressed или Btn_release обратно разрешать прерывание | |
// Фишка: в обработке кнопок можно писать тяжелые функции, | |
// выполняться будет вне прерывания | |
} | |
} | |
} | |
//============================================================================ | |
// Область задач | |
//============================================================================ | |
void BlinkON (void) | |
{ | |
digitalWrite(LED_BUILTIN, HIGH); | |
SetTimerTask(BlinkOFF,500); | |
} | |
void BlinkOFF (void) | |
{ | |
digitalWrite(LED_BUILTIN, LOW); | |
SetTimerTask(BlinkON,500); | |
} | |
void Btn_pressed() | |
{ | |
Play(); | |
SetTimerTask(Btn_release,300); | |
} | |
void Btn_release() | |
{ | |
// нужно что бы не обрабатывать нажатия кнопок чаще чем 1 раз в 300мс | |
_btn_state=BTN_NO_PRESS; | |
} | |
void read_max_volume() | |
{ | |
//в прерывание выносить лень, ресурсов хватает что бы юзать тупую analogRead | |
int val; | |
val = analogRead(MAX_VOLUME_PIN); | |
val = map(val, 0, 1023, 0, 30); | |
val = constrain(val, 0, 30); | |
max_sound_lvl=val; | |
SetTimerTask(read_max_volume, READ_MAX_VOLUME_DELAY); | |
} | |
void check_time() | |
{ | |
cli(); | |
//_time_h - это переменные из прерывания, поэтому оборачиваем в cli/sei | |
byte time_h=_time_h; | |
byte time_m=_time_m; | |
byte time_s=_time_s; | |
sei(); | |
#if defined( CHECK_TIME_SHOW_TIME ) && defined( BLUETOOTH_BY_SOFT ) | |
Serial.print(time_h, DEC); | |
Serial.print(":"); | |
Serial.print(time_m, DEC); | |
Serial.print(":"); | |
Serial.println(time_s, DEC); | |
#endif | |
if(время_позднее) Включаем тихий режим; | |
SetTimerTask(check_time, 1000); | |
} | |
void sync_send_data() | |
{ | |
// Пакет состоит из 4 частей: | |
// "SYNC_" - начало пакета, 4 байта | |
// Method - тип сообщения, 1 байт. | |
// DATA - данные в виде строки, около 31 байт | |
// "END\n" - конец пакета | |
SerialBT.print("SYNC_D"); // старт | |
SerialBT.print("D"); //метод | |
SerialBT.print("полезная инфа"); //данные | |
SerialBT.print("END\n"); // конец. println почему то не подходит, видать отправляет \r\n или подобное | |
} | |
void sync_get_data(byte *data) | |
{ | |
читаем_данные_из_пакета(); | |
if(ошибка) | |
{ | |
SetTask(sync_send_error); | |
} | |
else | |
{ | |
SetTask(after_sync); //сохраняем и настраиваем mp3 модуль | |
} | |
} | |
void after_sync() | |
{ | |
SetTask(write_rtc); | |
SetTask(sync_eeprom_update); | |
SetTask(write_rtc); | |
SetTask(setting_mp3); | |
SetTask(sync_send_ok); | |
} | |
void check_sync() | |
{ | |
// Проверка пришло ли сообщение от блютуза | |
// Ждем пока пакет придет целиком | |
if (SerialBT.available() > 40) { | |
for(byte i=0; i<41; i++) | |
{ | |
data_array[i]=SerialBT.read(); | |
} | |
//Проверяем начало пакета, ищем "SYNC_", если не нашли это в начале пакета - пакет битый | |
for(byte i=0; i<5; i++) | |
{ | |
if(data_array[i]!=start_str[i]) | |
{ | |
error("Не нашли начало пакета"); | |
} | |
} | |
// Если нашли начало пакета - ищем конец пакета. если не нашли - ну ты понел | |
if(correct_string!=false) | |
{ | |
byte end_str_index=3; | |
for(byte i=40; i>36; i--) | |
{ | |
if(data_array[i]!=end_str[end_str_index]) | |
{ | |
error("Не нашли конец пакета"); | |
} | |
end_str_index--; | |
} | |
} | |
//Если начало и конец пакета найдены - смотрим какой метод пришел | |
if(correct_string!=false) | |
{ | |
byte method = data_array[SYNC_INDEX_METHOD]; | |
if(method=='R') // - запрос анных, отправляем | |
{ | |
SetTask(sync_send_data); | |
} | |
else if(method=='W') //Пришли новые данные - читаем и сохраняем | |
{ | |
sync_get_data(data_array); | |
} | |
else if(method=='T') //Пришло время | |
{ | |
sync_get_time(data_array); | |
} | |
else if(method=='P') //Пришла команда воспроизвести мелодию | |
{ | |
sync_play(); | |
} | |
else | |
{ | |
error("че за метод?!") | |
} | |
} | |
} | |
SetTimerTask(check_sync, SYNC_PERIOD); | |
} | |
//******************************************************************************************************************************************************** | |
// ************************* Главный цикл //************************************************************************************************************** | |
//******************************************************************************************************************************************************** | |
void setup() { | |
поднимаем_serial(); | |
настраиваем_пины(); | |
инициализируем_переменные(); | |
настраиваем_mp3(); | |
настраиваем_прерывание_с_кнопки(PCIN2); | |
настраиваем_таймер_для_отсчета_времени(); | |
InitRTOS(); // Инициализируем ядро таймерной службы | |
RunRTOS(); //Запускаем таймерную службу и диспетчер задач | |
// Запуск фоновых задач | |
SetTimerTask(read_max_volume, READ_MAX_VOLUME_DELAY); | |
SetTimerTask(check_time, 1000); | |
SetTimerTask(read_rtc, RTC_READ_PERIOD); | |
SetTimerTask(check_sync, SYNC_PERIOD); | |
SetTimerTask(BlinkON,500); | |
sei(); | |
} | |
void loop() { | |
TaskManager(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment