Send sms for 1 hour, tested version

This commit is contained in:
vlad 2022-08-24 11:57:38 +03:00
parent 3292123b06
commit 93b45b8444
4 changed files with 100 additions and 93 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
# Project exclude paths # Project exclude paths
/cmake-build-debug/ /cmake-build-debug/
.idea/

109
main.c
View File

@ -1,17 +1,15 @@
#include "config.h" #include "config.h"
#include "platform.h" #include "platform.h"
#include <util/delay.h> #include <util/delay.h>
#include <avr/interrupt.h>
#define SMS_END "\032\n" #define SMS_END "\032\n"
#define SIM800_DELAY_TIME 100 #define SIM800_DELAY_TIME 100
void sim800_wait_newline() { static volatile uint8_t timer0_time;
while (1) { ISR(TIMER0_OVF_vect) {
char c = uart_read_char(); timer0_time++;
if (c == '\n') { LED2_Toggle();
return;
}
}
} }
void sim800_wait_for(PGM_P str) { void sim800_wait_for(PGM_P str) {
@ -151,7 +149,6 @@ static void num2buff(char* buffer, uint16_t num) {
} }
void sim800_send_telemetry() { void sim800_send_telemetry() {
platform_read_sensors();
uint16_t bat = sim800_get_battery(); uint16_t bat = sim800_get_battery();
sim800_prepare_sms(); sim800_prepare_sms();
@ -177,9 +174,48 @@ void sim800_send_telemetry() {
sim800_wait_for_sms_send(); 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() { int main() {
platform_init(); platform_init();
LED2_Set();
_delay_ms(100);
LED2_Reset();
_delay_ms(10000);
// врубаем модем // врубаем модем
sim800_start(); sim800_start();
@ -191,30 +227,57 @@ int main() {
sim800_wait_for_sms_send(); sim800_wait_for_sms_send();
// отправляем сразу же телеметрию // отправляем сразу же телеметрию
read_sensors();
sim800_send_telemetry(); sim800_send_telemetry();
// рубим модем // рубим модем
sim800_stop(); sim800_stop();
for (;;) {
uint16_t time = 0; MCUCR |= (1 << SE);
while (1) {
if (SPEED_Gpio & SPEED_Pin) { systick_execution_enable = 1;
// (скорость отпущена, пин подтянут к питанию)
// если скорости нет, шлем смс раз в час SP = RAMEND;
if (time > 60 * 60) { asm volatile (
break; "main_loop:\n"
} "sleep\n"
} else { "rjmp main_loop\n");
// если скорость зажата, то максимальное ожидание 60 секунд }
if (time > 60) {
break; 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_start();
sim800_send_telemetry(); sim800_send_telemetry();
sim800_stop(); sim800_stop();
cli();
MCUCR |= (1 << SE);
exec = 0;
} }
} }

View File

@ -5,15 +5,12 @@
#include "config.h" #include "config.h"
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <util/delay.h>
static char systick_flag; char systick_execution_enable;
uint16_t sensor_1; uint16_t sensor_1;
uint16_t sensor_2; uint16_t sensor_2;
ISR(TIMER1_OVF_vect) {
systick_flag = 1;
// LED2_Toggle();
}
void platform_init() { void platform_init() {
// инициализация GPIO // инициализация GPIO
@ -27,8 +24,9 @@ void platform_init() {
// инициализация таймера 1 (16-ти битный) // инициализация таймера 1 (16-ти битный)
systick_flag = 0; systick_execution_enable = 0;
// настройка таймера 1
// mode=14 (FastPWM, top in ICR1), x64, ICR1=1000000/64=15625 // mode=14 (FastPWM, top in ICR1), x64, ICR1=1000000/64=15625
TCCR1B = (1 << WGM13) | (1 << WGM12); TCCR1B = (1 << WGM13) | (1 << WGM12);
TCCR1A = (1 << WGM11); TCCR1A = (1 << WGM11);
@ -36,8 +34,14 @@ void platform_init() {
// выставляем TOP // выставляем TOP
ICR1 = (uint16_t)(F_CPU / 64); 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, то есть запускаем таймер TCCR1B |= (1 << CS11) | (1 << CS10); // выставляем x64, то есть запускаем таймер
@ -58,24 +62,6 @@ void platform_wait_for_interrupt() {
ACSR |= acsr; 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() { void uart_init() {
// U2X=1, baud=9600, error=0.2%, f=1M // U2X=1, baud=9600, error=0.2%, f=1M
UBRRH = 0; UBRRH = 0;
@ -126,39 +112,3 @@ void uart_discard_input() {
char __attribute__((__unused__)) _tmp = UDR; 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;
}

View File

@ -10,8 +10,7 @@
extern uint16_t sensor_1; extern uint16_t sensor_1;
extern uint16_t sensor_2; extern uint16_t sensor_2;
extern char systick_execution_enable;
void platform_read_sensors();
/** /**
* Инициализация модуля * Инициализация модуля
@ -23,12 +22,6 @@ void platform_init();
*/ */
void platform_wait_for_interrupt(); void platform_wait_for_interrupt();
/**
* Ожидание прерывания по таймеру, то есть выравнивание исполнения программы по секундам.
* Задержит исполнение программы на время от 1 ... 0 секунд, вернет управление когда таймер даст прерывание
*/
void systick_sync();
void uart_init(); void uart_init();
void uart_deinit(); void uart_deinit();