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

Подсчет имупульсов/оборотов двигателя ВАЗ инжектор с помощью ATMEGA8 и C


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

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

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

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

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

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

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

@BARS_ Кнопки = герконы, которые замыкаются при включении передачи, ещё один вход для ручника, на матрице рисуются символы 1-5, R, P, N

 

Отслеживать одновременное нажатие кнопок нужно для калибровки, моргание для напоминании о том что была включена скорость при поднятом ручнике.

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

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

Только что, BARS_ сказал:

А смысл какой данной схемы?

Хобби, развитие, изучение СИ и МК

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Ааа. Я тоже примерно с такого начинал, только делал типа бортового компа на Москвич 2141 и встроил 8 семисегментников прямо в панель приборов

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

Только что, BARS_ сказал:

Ааа. Я тоже примерно с такого начинал :rolleyes:

Дак вот, если всё же о программе, кнопки посоветуете в таймере опрашивать? И как вообще, как обычно отслеживают одновременное нажатие кнопок, подскажите пожалуйста?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Я бы опрашивал все в главном цикле, с задержкой после опроса в 100мс для подавления дребезга. Опрашивал бы все кнопки по очереди и записывал состояние каждой в переменную.

unsigned char button = 0;


while(1){
  button = 0;
  
  if (!(PIND&(1<<GEAR1)){
      button = (1 << 0);
  }

  if (!(PIND&(1<<GEAR2)){
      button = (1 << 1);
  }

  if (!(PIND&(1<<GEAR3)){
      button = (1 << 2);
  }

  if (!(PIND&(1<<GEAR4)){
      button = (1 << 3);
  }

  if (!(PIND&(1<<GEAR5)){
      button = (1 << 4);
  }
      
      _delay_ms(100)
}

Далее уже по наличию или отсутствию 1 в определенном бите делать действия хоть в таймере, хоть где угодно. А можно даже еще проще, использовать напрямую PORTB:

button = PORTB;
_delay_ms(100);

Или же опрашивать порт в таймере, только завести переменную для счетчика, чтобы опрос был раз в 100мс, к примеру.

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

1 минуту назад, BARS_ сказал:

Далее уже по наличию или отсутствию 1 в определенном бите делать действия хоть в таймере, хоть где угодно. 

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

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

5 часов назад, -=FISHER=- сказал:

У меня светодиодная матрица 5х7 и 6 кнопок

Это мелочи. 

Кнопки опрашивайте в прерывании по переполнению таймера 0, там же по событию нажатия той или иной кнопки запоминаете это событие в переменную, одной переменной типа чар хватит на 6кнопок. И потом в программе когда нужно обработать событие это, оно само обработается и там же скидываете флаг кнопки. И того имеем защиту от пропуска события по кнопке. Ну а все остальное время занимаетесь индикацией. И ещё там останется ресурсов вагон и тележка, на развитие 

Не знаеш как? Спроси у Google'а !!!

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

Достаточно в прерывании поднять флаг, а в основном цикле этот флаг проверять. Как только он будет поднят - выполнить ряд задач (опрос кнопок, вывод очередного символа на динамическую индикацию и т.д.), не забывая в конце опустить этот флаг (до следующего прерывания). Времени хватит и на кнопки, и на дисплей, и... "объявить войну и проиграть ее":).
 

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

В 11/28/2016 в 11:53, BARS_ сказал:

Опрашивал бы все кнопки по очереди и записывал состояние каждой в переменную.

При опросе кнопок, записываю бит в переменную вот так:

if (!(PIND&(1<<GEAR1)))
	{
      button=(1<<0);
    }

if (!(PIND&(1<<GEAR2)))
	{
      button=(1<<1);
    }

if (!(PIND&(1<<GEAR3)))
	{
      button=(1<<2);
    }

if (!(PIND&(1<<GEAR4)))
	{
      button=(1<<3);
    }

if (!(PIND&(1<<GEAR5)))
	{
      button=(1<<4);
    }

После чего проверяю сколько единичек записалось в байт переменной button, вот так:

for (t=0; t<5, t++)
	{
      if (button&(1<<t)) {err++;}
    }

if (err>2) [/* ВЫВОДИМ СИМВОЛ E НА ДИСПЛЕЙ*/; err=0;]

Однако, на дисплей сразу же даже при нажатии одной кнопки выводится "E", у меня предположение что я не правильно проверяют коичество единиц в байте. Поправьте пожалуйста.

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

 

button = 0;	// обнуляем состояние нажатых кнопок
key = PIND;	// фиксируем состояние входов порта D

if (!(key & (1<<GEAR1)))
	{
      button |= (1<<0);	// если кнопка нажата, то устанавливаем бит
    }

if (!(key & (1<<GEAR2)))
	{
      button |= (1<<1);
    }

if (!(key & (1<<GEAR3)))
	{
      button |= (1<<2);
    }

if (!(key & (1<<GEAR4)))
	{
      button |= (1<<3);
    }

if (!(key & (1<<GEAR5)))
	{
      button |= (1<<4);
    }

а почему не хотите так

button = PIND;

а потом анализируйте биты в переменной button

24 минуты назад, -=FISHER=- сказал:

После чего проверяю сколько единичек записалось в байт переменной button

 

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

3 минуты назад, dm37 сказал:

а потом анализируйте биты в переменной button

А наведите пожалуйста на мысль как именно? Так как я описал почему то не корректно работает.

5 минут назад, dm37 сказал:

а почему не хотите так


button = PIND;

 

Потому что у меня на PD5 висит вход от на таймер для счета импульсов от тахометра.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

button = PIND & ((1<<GEAR1) | (1<<GEAR2) | (1<<GEAR3) | (1<<GEAR4) | (1<<GEAR5)); // накладываем маску только на входа кнопок
err = 0;
for (t=0; t<8, t++)
{
   if (button & (1<<t))
      err++;
}

// в err количество единичек (нажатых кнопок)

 

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

В 12/2/2016 в 16:00, dm37 сказал:

char button = PIND & ((1<<GEAR1) | (1<<GEAR2) | (1<<GEAR3) | (1<<GEAR4) | (1<<GEAR5)); // накладываем маску только на входа кнопок

Компилятор ругается, пишет initializer element is not constant

 

 

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Напишите просто:

button = PIND;

А далее просто смотрите, где оказались 1, а где нули. Например так:

if(button&0x01)//условие верно, если в нулевом бите будет 1
{ 
}

Можно вообще сразу так писать:

if(PIND&0x01)//условие верно, если в нулевом бите будет 1
{ 
}

 

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

5 минут назад, BARS_ сказал:

 

А далее просто смотрите, где оказались 1, а где нули. Например так:


if(button&0x01){ //условие верно, если в нулевом бите будет 1
	}
	

Это понятно...я вот так проверял : if (!(PIND&(1<<GEAR1))), но при таком решении дальше не получится в цикле перебрать значения, для определения, а не замагнитились ли сразу два соседних геркона, а это будет удобно при настройке на авто.

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

6 минут назад, -=FISHER=- сказал:

сразу два соседних геркона

Так можно проверять сразу несколько битов. 

if (!(PIND&(1<<GEAR1)) && !(PIND&(1<<GEAR2)))

 

Или короче записать через маску

if (!(PIND&0x06))
Изменено пользователем BARS_
Ссылка на комментарий
Поделиться на другие сайты

1 минуту назад, BARS_ сказал:

Так можно проверять сразу несколько битов. 

Честно признаться, я думал об этом, но мне кажется что так не делается, ну типа слишком "топорно" и на самом деле есть изящнее рещшение, которое я вот пытаюсь найти. Но возможно более изящного решения нет.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Нету, придется именно проверять все комбинации. Более изящное оно будет, если слать состояние порта в виде строки светодиодов на матрицу. Тогда это всего одна строка кода будет и по состоянию пикселей в строке можно отследить, какие герконы сработали.

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

 

40 минут назад, -=FISHER=- сказал:

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

Сдвигать переменную никто не запрещал:

button = PIND;
//если кнопка замыкается на землю проинвертировать: button=~button;
t=5;
while (t--)
{
  if (button&0x01)
  {err++;}
  button=button>>1; //сдвиг переменной реализовать проще чем создание маски на лету: if (button & (1<<t))
}
if (err>2) [/* ВЫВОДИМ СИМВОЛ E НА ДИСПЛЕЙ*/; err=0;]
Изменено пользователем Dan'nah
Ссылка на комментарий
Поделиться на другие сайты

1 час назад, -=FISHER=- сказал:

Компилятор ругается, пишет initializer element is not constant

странно у меня не ругается, у вас похожий код?

#include <avr/io.h>
#include <avr/interrupt.h>
  
#define GEAR1 1
#define GEAR2 2
#define GEAR3 3
#define GEAR4 4
#define GEAR5 5

	
int main(void)
{
    unsigned char button = PIND & ((1<<GEAR1) | (1<<GEAR2) | (1<<GEAR3) | (1<<GEAR4) | (1<<GEAR5)); // накладываем маску только на входа кнопок
	  
    unsigned char err = 0;
    for(unsigned char t=0; t<8; t++)
    {
        if (button & (1<<t))
            err++;
    }

    while (1) 
    {
    }
}

Можно не проверять все нажатия по case или if, если памяти (flash) достаточно то сделайте таблицу на 256 символов, а код считанный с порта в button преобразуйте в "код клавиши" через таблицу TableKeyDecode[], с учетом любой комбинации нажатых клавиш. Да и время выполнения данной операции будет всегда одинаково. Таблица TableKeyDecode[] содержит коды нажатых клавиш, если комбинация не используется, то код клавиши равен, например 0xFF.

//строка для IAR
//  const uint8_t __flash TableKeyDecode[] =
const unsigned char TableKeyDecode[] PROGMEM =
{
  0x00,0x01,0x02,0x03,0x04,0x05,0x06,0xFF,0x08,0x09,0xFF,0xFF,0x0C,0xFF,0xFF,0xFF,
    ...
};

key = TableKeyDecode[button];

а хитрая комбинация из нажатых кнопок обязательно? Я без надобности стараюсь не делать одновременное нажатие, только последовательное нажатие.

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

1 час назад, BARS_ сказал:

Нету, придется именно проверять все комбинации.

Вообще конечно теоретически, замкнуться одновременно могут скорости (R и 1), (1 и 3), (3 и 5), (2 и 4), тогда примерно так должно выглядеть?...массивно конечно, но ничего не поделаешь...

If (((!(PIND&(1<<GEAR_R)) & (!(PIND&(1<<GEAR1))) || ((!(PIND&(1<<GEAR1)) & (!(PIND&(1<<GEAR3))) || ((!(PIND&(1<<GEAR3)) & (!(PIND&(1<<GEAR5))))
                                                     
//этим я проверю не замкнуло ли, при включении задней, первой, третьей или пятой скорости одну из соседних

 

5 минут назад, dm37 сказал:

а хитрая комбинация из нажатых кнопок обязательно? Я без надобности стараюсь не делать одновременное нажатие, только последовательное нажатие.

Получается возможно одновременное нажатие максимум двух герконов.

Индикатор включенной скорости.jpg

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

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

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

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

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

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

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

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

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

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