From 93b45b844478bdffd07221d7908344d7d9b40634 Mon Sep 17 00:00:00 2001 From: vlad Date: Wed, 24 Aug 2022 11:57:38 +0300 Subject: [PATCH] Send sms for 1 hour, tested version --- .gitignore | 3 +- main.c | 109 ++++++++++++++++++++++++++++++++++++++++++----------- platform.c | 72 ++++++----------------------------- platform.h | 9 +---- 4 files changed, 100 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index da6ed1a..0e7c80a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # Project exclude paths -/cmake-build-debug/ \ No newline at end of file +/cmake-build-debug/ +.idea/ diff --git a/main.c b/main.c index 2e53d31..6164963 100644 --- a/main.c +++ b/main.c @@ -1,17 +1,15 @@ #include "config.h" #include "platform.h" #include +#include #define SMS_END "\032\n" #define SIM800_DELAY_TIME 100 -void sim800_wait_newline() { - while (1) { - char c = uart_read_char(); - if (c == '\n') { - return; - } - } +static volatile uint8_t timer0_time; +ISR(TIMER0_OVF_vect) { + timer0_time++; + LED2_Toggle(); } void sim800_wait_for(PGM_P str) { @@ -151,7 +149,6 @@ static void num2buff(char* buffer, uint16_t num) { } void sim800_send_telemetry() { - platform_read_sensors(); uint16_t bat = sim800_get_battery(); sim800_prepare_sms(); @@ -177,9 +174,48 @@ void sim800_send_telemetry() { sim800_wait_for_sms_send(); } +void read_sensors() { + timer0_time = 0; + EXTPWR_EN_Set(); + register uint32_t s1 = 0, s2 = 0; + + register uint8_t states = FRQ_Gpio & (FRQ1_Pin | FRQ2_Pin); + + TCNT0 = 0; + TCCR0B |= (1 << CS02) | (1 << CS00); // x1024 + + while (timer0_time < 250) { + uint8_t tmp = FRQ_Gpio; + + if ((tmp & FRQ1_Pin) != (states & FRQ1_Pin)) { + states = (states & (~FRQ1_Pin)) | tmp; + s1++; + } + + if ((tmp & FRQ2_Pin) != (states & FRQ2_Pin)) { + states = (states & (~FRQ2_Pin)) | tmp; + s2++; + } + } + + TCCR0B &= ~((1 << CS02) | (1 << CS01) | (1 << CS00)); // x0 + + EXTPWR_EN_Reset(); // отрубаем питание генераторов + + // быстрое деление на 2 (считалось каждое изменение) + // 64 секунды * 2 = 128 (2^7) + sensor_2 = (uint16_t)(s1 >> 7); + sensor_1 = (uint16_t)(s2 >> 7); + + // готово! +} int main() { platform_init(); + LED2_Set(); + _delay_ms(100); + LED2_Reset(); + _delay_ms(10000); // врубаем модем sim800_start(); @@ -191,30 +227,57 @@ int main() { sim800_wait_for_sms_send(); // отправляем сразу же телеметрию + read_sensors(); sim800_send_telemetry(); // рубим модем sim800_stop(); - for (;;) { - uint16_t time = 0; - while (1) { - if (SPEED_Gpio & SPEED_Pin) { - // (скорость отпущена, пин подтянут к питанию) - // если скорости нет, шлем смс раз в час - if (time > 60 * 60) { - break; - } - } else { - // если скорость зажата, то максимальное ожидание 60 секунд - if (time > 60) { - break; + + MCUCR |= (1 << SE); + + systick_execution_enable = 1; + + SP = RAMEND; + asm volatile ( + "main_loop:\n" + "sleep\n" + "rjmp main_loop\n"); +} + +ISR(TIMER1_OVF_vect) { + static uint16_t time = 0; + static char exec = 0; + if (systick_execution_enable) { + time++; + if (SPEED_Gpio & SPEED_Pin) { + // (скорость отпущена, пин подтянут к питанию) + // если скорости нет, шлем смс раз в час + if (time > 60 * 60) { + if (!exec) { + time = 0; + exec = 1; + } + } + } else { + // если скорость зажата, то максимальное ожидание 5 минут + if (time > 300) { + if (!exec) { + time = 0; + exec = 1; } } - time++; - systick_sync(); } + } + if (exec == 1) { + exec = 2; + MCUCR &= ~(1 << SE); + sei(); + read_sensors(); sim800_start(); sim800_send_telemetry(); sim800_stop(); + cli(); + MCUCR |= (1 << SE); + exec = 0; } } diff --git a/platform.c b/platform.c index 1c68f92..760cf4e 100644 --- a/platform.c +++ b/platform.c @@ -5,15 +5,12 @@ #include "config.h" #include #include +#include -static char systick_flag; +char systick_execution_enable; uint16_t sensor_1; uint16_t sensor_2; -ISR(TIMER1_OVF_vect) { - systick_flag = 1; -// LED2_Toggle(); -} void platform_init() { // инициализация GPIO @@ -27,8 +24,9 @@ void platform_init() { // инициализация таймера 1 (16-ти битный) - systick_flag = 0; + systick_execution_enable = 0; + // настройка таймера 1 // mode=14 (FastPWM, top in ICR1), x64, ICR1=1000000/64=15625 TCCR1B = (1 << WGM13) | (1 << WGM12); TCCR1A = (1 << WGM11); @@ -36,8 +34,14 @@ void platform_init() { // выставляем TOP ICR1 = (uint16_t)(F_CPU / 64); + // настройка таймера 0 + // x1024, mode7 (fastpwm, top in OCRA) + TCCR0A = (1 << WGM01) | (1 << WGM00); + TCCR0B = (1 << WGM02); // предделитель пока не ставим, таймер без него не работает + OCR0A = 250; + // разрешаем прерывание по переполнению - TIMSK |= (1 << TOV1); + TIMSK |= (1 << TOV1) | (1 << TOV0); TCCR1B |= (1 << CS11) | (1 << CS10); // выставляем x64, то есть запускаем таймер @@ -58,24 +62,6 @@ void platform_wait_for_interrupt() { ACSR |= acsr; } -void systick_sync() { - systick_flag = 0; // можно не запрещать прерывания: операция атомарна - for(;;) { - cli(); - char flag = systick_flag; - if (flag) { - systick_flag = 0; - } -// else { -// platform_wait_for_interrupt(); -// } - sei(); - if (flag) { - return; - } - } -} - void uart_init() { // U2X=1, baud=9600, error=0.2%, f=1M UBRRH = 0; @@ -126,39 +112,3 @@ void uart_discard_input() { char __attribute__((__unused__)) _tmp = UDR; } } - -void platform_read_sensors() { - EXTPWR_EN_Set(); - systick_sync(); - sensor_1 = 0; - sensor_2 = 0; - uint8_t states = FRQ_Gpio & (FRQ1_Pin | FRQ2_Pin); - - for(;;) { - uint8_t tmp = FRQ_Gpio; - - if ((tmp & FRQ1_Pin) != (states & FRQ1_Pin)) { - states = (states & (~FRQ1_Pin)) | tmp; - sensor_1++; - } - - if ((tmp & FRQ2_Pin) != (states & FRQ2_Pin)) { - states = (states & (~FRQ2_Pin)) | tmp; - sensor_2++; - } - - cli(); - char flag = systick_flag; - if (flag) { - systick_flag = 0; - } - sei(); - if (flag) { - break; - } - } - EXTPWR_EN_Reset(); - // быстрое деление на 2 (считалось каждое изменение) - sensor_2 >>= 1; - sensor_1 >>= 1; -} \ No newline at end of file diff --git a/platform.h b/platform.h index 8fa4826..490f113 100644 --- a/platform.h +++ b/platform.h @@ -10,8 +10,7 @@ extern uint16_t sensor_1; extern uint16_t sensor_2; - -void platform_read_sensors(); +extern char systick_execution_enable; /** * Инициализация модуля @@ -23,12 +22,6 @@ void platform_init(); */ void platform_wait_for_interrupt(); -/** - * Ожидание прерывания по таймеру, то есть выравнивание исполнения программы по секундам. - * Задержит исполнение программы на время от 1 ... 0 секунд, вернет управление когда таймер даст прерывание - */ -void systick_sync(); - void uart_init(); void uart_deinit();