Перейти к содержанию

Вопросы от начинающих по МК


Рекомендуемые сообщения

ISR (TIMER0_OVF_vect)// Індикація роботи процесора
{
   wdt_reset();
   count_0++;
   if (count_0 == 118)
   {
       PORTD |= (1<<PD6);
       count_0=0;
   }
   if (count_0 ==2)PORTD &=~ (1<<PD6);
   if (kontrol_menu == 1) menu_null++;
   else menu_null = 0;
}

Имеет смысл объявить count_0 локально как static. Не то чтобы это улучшало быстродействие или объем, но лучше чтобы лишние переменные не торчали наружу.

void presets()// Головні налаштування процесора

Имеет смысл поискать копирование массивов из EEPROM в ОЗУ. Чтобы переменные имели разные названия, оставаясь непрерывным массивом, я в свое время делал примерно такой костыль

volatile unsigned int var_ram[10];
#define uart_speed var_ram[0]
#define some_var var_ram[1]
uart_speed=96;

В функции uint8_t clock() жаль не прислушались к советам. Умножение для мег не самая затратная операция, но сравнение все равно быстрее:

uint8_t in_range(char th1,char th2,char tm1,char tm2){
if(hour<th1)return 0; //если часы не попадают в диапазон - дальнейшее сравнение бессмысленно, возвращаем false
if(hour>th2)return 0;
if(minute<tm1)return 0; //если минуты не попадают в диапазон - возвращаем false
if(minute>tm2)return 0;
return 1; //если же в диапазон попадают и часы и минуты - возвращаем true
}

Ну и в оригинале возвращаемое какое-то инвертированное - возвращает true если время не попадает в диапазон, да еще название ни о чем не говорит.

В void lcd()// Головний дисплей можно упростить запись сравнения

if(in_range(t1.h_on,t1.h_off,t1.m_on,t1.m_off) | in_range(t2.h_on,t2.h_off,t2.m_on,t2.m_off) | in_range(t3.h_on,t3.h_off,t3.m_on,t3.m_off) | in_range(t4.h_on,t4.h_off,t4.m_on,t4.m_off)){
OUTPUT_ON;
}else{
OUTPUT_OFF;
}

Компилятор умный, когда хоть одна функция вернет true - прекратит вычисление остальных.

Ну и обработку lcd() имеет смысл синхронизировать с счетчиком минут. Например, как я описывал, на флагах.

.

Это то, что заметно на первый взгляд.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов
  • Создана
  • Последний ответ

Топ авторов темы

По поводу сравнения и попадания в диапазон.

вкл в 02:30 а выкл в 07:00 уже не попали ?? :vava:

А вот если мы переводим все в минуты, а лучше в секунды, то мы сто процентов будем знать в каком времени суток находимся

Ну и обработку lcd() имеет смысл синхронизировать с счетчиком минут. Например, как я описывал, на флагах.

А где описывали, в этой ветке?

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

А вот если мы переводим все в минуты, а лучше в секунды, то мы сто процентов будем знать в каком времени суток находимся
Не будем. Если только Вы не считаете минуты (или секунды) по числам, месяцам и годам.

В любом случае, нужно "ловить" переход через 00:00 и инвертировать значение.

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

В любом случае, нужно "ловить" переход через 00:00 и инвертировать значение.

Переход через 00:00 заведомо не ловим, это же суточный таймер.

Ссылка на комментарий
Поделиться на другие сайты

Я имел в в иду ловить - узнать, переходит ли диапазон включения через 00:00 (например, вкл. от 23:00 до 7:00).

И вычисление полных минут по часам и минутам, и их сравнение, не решает эту проблему.

Ссылка на комментарий
Поделиться на другие сайты

Не будем. Если только Вы не считаете минуты (или секунды) по числам, месяцам и годам.

Будем знать, ведь в моем варианте, все это делает DS1307.

Если принять за точку отсчета 00:00 то, к примеру 02:03 = 123 а 07:55 = 475, тут уже не ошибешься

А для того чтобы перейти через 00:00 Придется настраивать два таймера, потому что сутки заканчиваются в 23:59:59 и начинаются в 00:00

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

По поводу сравнения и попадания в диапазон.

вкл в 02:30 а выкл в 07:00 уже не попали ?? :vava:

Ок, согласен, надо добавить еще условие на строгое равенство

if(minute<tm1 && hour==th1)return 0;

А где описывали, в этой ветке?

Да, в этой ветке. Обратите внимание на переменную flag и ее использование.

.

UPD:

Кстати, можно было воспользоваться и структурами, это еще проще, как предлагал IMXO, да и я.

typedef union{
unsigned int time;
struct{
 unsigned char minute;
 unsigned char hour;
}t;
}time_t;
volatile time_t cur_time,t1,t2,t3,t4;
char time_cmp(time_t t1,time_t t2){
if(t1.time>t2.time)return 1; else return 0;
}
ISR(TIMER0_OVF_vect){
...
if(++cur_time.minute > 60){
 cur_time.minute=0;
 cur_time.hour++;
...
}
}

Изменено пользователем COKPOWEHEU

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

if(minute<tm1 && hour==th1)return 0;

Теперь иная ситуация. настроили вкл в 02:30 а выкл в 10:40 и выключили контроллер(DS1307 работает), включили в 05:10, и не попали в диапазон, а попадем только в 05:30,

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

Да чё вы тут голову ломаете, вот же я вариант предлагал :

Как то, примерно, так :

if ((hour > hour_on_1) && (hour < hour_off_1)) return 1;
if (hour == hour_on_1){
 if (minute >= minute_on_1) return 1;
}
if (hour == hour_off_1){
 if (minute < minute_off_1) return 1;
}
return 0;

Можно ещё вот так сделать:

uint8_t clock(char th1,char th2,char tm1,char tm2)
{
uint16_t   t = (uint16_t)hour<<8 | minute;
uint16_t   t1 = (uint16_t)th1<<8 | tm1;
uint16_t   t2 = (uint16_t)th2<<8 | tm2;

if ((t >= t1) && (t<t2))   return 0;
return 1;
}

И никаких умножений :)

Изменено пользователем Alex
Грёбаный редактор, пробелы рубит, гад :(
Ссылка на комментарий
Поделиться на другие сайты

Теперь иная ситуация. настроили вкл в 02:30 а выкл в 10:40 и выключили контроллер(DS1307 работает), включили в 05:10, и не попали в диапазон, а попадем только в 05:30,

Здесь все нормально, все условия в сравнениях будут ложными, поэтому ни один return 0 не выполнится и перейдет на return 1. Ведь проверять минуты надо только тогда, когда часы строго равны. Собственно, у Alex'a тот же вариант. А второй его вариант - упомянутый мной вариант со структурами, только чуть проще.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Ну со структурами и объединениями, действительно проще. Но не хочет, видимо, он ими заморачиваться :)

По этому это - просто наглядный пример того, о чём ему уже много раз здесь говорили.

Ссылка на комментарий
Поделиться на другие сайты

И никаких умножений :)

Я рассматривал всдовж и в поперек этот код, и понял, я слишком недоросль чтобы так кодить

Если вы видели весь код, то должны были заметить структуру. Первую мою нелепую структуру. Говорю же-- У чайников нет мозгов

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

Я больше объединения (union) имел ввиду, чем структуры. Тут где-то проскакивал вариант с ними.

Второй мой вариант - это и есть объединение, только программное. А можно переменные объединять на этапе компиляции, чтобы у них адреса совпадали.

Ссылка на комментарий
Поделиться на другие сайты

Здесь он вместо умножения на 60 делает умножение на 256 (для контроллера это проще даже, чем умножение на 64 сдвигом на 6 разрядов). Из двух однобайтных чисел получается одно двухбайтное. И неважно, что, например, 0x0102 (1 час 2 минуты) != 0x003E (62 минуты) и вычислять разность времен становится не такой простой операцией. Зато для качественной оценки (больше-меньше) этого достаточно. Способ и объединением (последний мой пост на предыдущей странице) по сути тоже самое, но часы и минуты сразу хранятся в BCD-виде, а не собираются из отдельных переменных,

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Кстати, вариант COKPOWEHEU с полубайтами:

union{
unsigned int time;
struct{
 unsigned char ml:4;
 unsigned char mh:4;
 unsigned char hl:4;
 unsigned char hh:4;
}t;
}time;

действительно не плохой. Особенно, в случае с DS1307.

Не нужно будет делать подобные извращения:

minute = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
hour = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);

А писать сразу считанный байт в структуру.

Тогда и с выводом на дисплей будет проще и со сравнением точек никаких проблем.

Ссылка на комментарий
Поделиться на другие сайты

Пожалуйста опишите мне эту строчку.

uint16_t t = (uint16_t)hour<<8 | minute;

По поводу DS1307, я ее честно стырил, где то в интернете, код работает, по этому и не стал вникать в те "извращения".

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

Дошло, это работа с битовыми полями. :dance2: забавная штука.

Один мой знакомый программист, однажды вывалил такую фразу:- Если ты не получаешь кайфа от программирования, ты никогда не научишься программировать :crazy:

за сем откланяюсь :thank_you2: , пора...

Ссылка на комментарий
Поделиться на другие сайты

Сколачивая различные приблуды на AVR, замечал некие глюки дисплея при комутации индуктивных нагрузок, реле, трансформаторы и прочее. В очередной раз, разработав приблуду, о которой так активно обсуждалось в последних страницах ветки, наткнулся на тот же безпредел. При том что входа, что выхода сделаны через оптопары.

ATmega8a, nokia3310 и реле.

Питаю от стабилизированного импульсного бп на 12в, а в схеме еще два стабилизатора на 5 и 3.3 вольт. Электролиты хорошие, а по всей плате, где идут цепи питания, еще и керамических понатыкал.

Как только срабатывает релюшка, экран белеет и приходится перезагружать все это дело. На реле установлен диод 1n5819, а питается от 12в, после нее и до контроллера, еще два стабилизатора.

Блоки питания подключал разные, заземлял дисплей, не заземлял, пихал провода в экран, все то же самое.

Может кто сталкивался? Ибо инициализировать дисплей каждые пять секунд, не вариант вообще :umnik2:

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...